Have developed an iPhone app which has two different functionality and it using same images and string in some areas in both the project. Here I am using preprocessor macros which are differentiating it during compile time say for example project one and project two.
Here my question is is there any way to pass the images and string in generic way. I mean if I execute the application for project one means it should only take relevant app's images and string it should not bundled with another project i.e. project two's source.
Any idea and suggestion will be greatly appreciated.
Have a look at the screenshot of a project that has two targets:
And at folder structure:
You can put shared assets in the Shared folder and add them to both targets like SharedImage.png in the example. For assets that has two different versions, you can put each version on the appropriate folder (Target A or Target B) and use the same name for both versions. For example, when adding the image MyImage.png to Target A, you simply have to check the box Target A like in the following screenshot:
Now, it is easy to use the correct asset for each target and without using preprocessor macros. For example, the following code will use the correct version of MyImage.png whether it is running in Target A or Target B
UIImage *image = [UIImage imageNamed:#"MyImage.png"];
Related
I'm curious if there is a way to programmatically get the location of the .xcodeproj package within an Objective-C (or Swift) class contained within that package. I'd like to make a simple utility that puts files directly into the containing folder based on various app events, but I would rather avoid hard coding the path.
Essentially I want to create a target (and a reusable class) that builds swift files for NSManagedObject subclasses based on the Core Data model present in the app.
I found out the trick here is to add an item to your plist file that contains value ${PROJECT_DIR}, then you can get the location in your code with
var projectPath = NSBundle.mainBundle().infoDictionary.objectForKey("com.myapp.project_dir") as String
This assumes the plist key is "com.myapp.project_dir", of course.
I'm looking for executing a .xib (with its own controllers and libraries) precompiled on a server, downloading it on runtime.
Is it possible?
Thanks!
EDIT:
So could somebody give me an example of a program that uses NSBundle that executes other app?
And how do I create the bundled application?
I don't think you can import a xib into the application's bundle at run-time (which you would have to in order for this to happen). Others may know more and correct me!
I can think of a couple of ways you could try to do this, but are you aiming to get it in to the store?
This is expressly prohibited by Apple Developer Guidelines.
A .xib file is just a data file, so there shouldn't be any problem loading one that's outside your app's bundle. I can't say I've ever tried it, but as long as it's in a bundle, you should be able to:
Create an instance of NSBundle using the path to the bundle containing the .xib you want to load. See +[NSBundle bundleWithPath:] for that.
Load the .xib using the bundle you created in the previous step with any of the normal .xib-loading methods, such as -[UIViewController initWithNibNamed:bundle:] or +[UINib nibWithNibName:bundle:].
with it's own controllers and libraries
That part won't work. iOS doesn't allow dynamic linking to frameworks other than the ones provided by the system, so there's no way to load your code. If you can build all the code you need into your app, though, you should still be able to use downloaded .xib's as described above. That would let you do things like update the way your views are laid out or what targets and actions your controls are connected to.
I have a little problem.. which I know there is a fix for, I just don't know what it is.
The problem is the following. A few weeks ago (2 or so) I had to remove 4 apps from the appstore due to a data problem on my server side. I decided to upgrade all the apps to the latest version at the same time giving them some new features. (I have 6 of the same apps out there, targeting different airports). The difference between these versions are the following:
A set of 50-80 or so images that combine the map of each airport. The filenames are the same in each app. (How do I solve that?)
The name of the app
The Default.png (and those for iPad and retina of course)
The App Icon
The content of a details page (which exists in a .plist file)
The content of the "About" page where the page refers back to the app
Some localize content, refering back to the airport the app targets.
The provisioning profiles, of course.
Keeping track of these things are just a pain in the ass, so I want to have 1 project with 1 code base and just add the images and details (mentioned above) and new versions appear. When I "Archive", I want all of the apps to be build and ready to be send of to apple (which I will have to do manually).
How can I achieve this?
I have done this before using multiple targets and conditional compilation. You need one target per deliverable. You can configure the name, icons etc for each target in the usual way.
A set of 50-80 or so images that combine the map of each airport. The filenames are the same in each app. (How do I solve that?)
Keep the images in different directories and for each target only add the images for that app. This technique will also work for the contents of the about page if you can load that from a file.
I also use conditional compilation so that I can define different values for my constants for each app.
To do this add a setting to Other C Flags and Other C++ flags to identify your app. Something like:
-DAPP_VARIANT=1
In your code you can then use the following to implement any app specific behaviour:
- (id)init
{
#if APP_VARIANT == 1
self->server_url = [[NSURL URLWithString:#"http://app1.example.com"] retain];
#elif APP_VARIANT == 2
self->server_url = [[NSURL URLWithString:#"http://app2.example.com"] retain];
#endif
}
Can't you use one version control branch for all the main code, then fork it six times (once for each airport) where you fill in the data? Once you make new code changes, just push the changes from the main branch to the forks and you're done.
I'm trying to convert a project, which has images, into a static library.
The code that gets the image is as follows:
[UIImage imageNamed:#"foo.png"]
When I include this library into another project, the image doesn't load. However, if I copy the images into the new project, then it does load.
Is there any way I can get this to work where the images are only contained in the library and I don't have to copy them over to my project?
By the way, my Header Search Paths contains the path to where these images are located in the library, if that makes any difference.
Just prepend the name of the bundle that contains your image to the image name:
[UIImage imageNamed:#"Myframework.bundle/MyImage"
This also works in Interface Builder, the preview may be broken but the image will be properly loaded.
If using CocoaPods (which I would recommend) make sure to use the resource_bundles option for your images and Nibs.
You can see a related answer here.
A static library cannot contain bundle resource. So simply linking the .a file will not be enough. But you should be able to cross-reference the static library xcodeproj. Example
Had a similar situation to this and wrote a script to copy the files in to the .app at compile time. A similar fix to the one we use is described in the "Non-code assets for static libraries" section on this web page. This works but can cause some code signing errors. Another option is to create a second .bundle target for the resources described on this web page although for some reason I could not get the bundle to actually build. I am currently looking at writing a script to copy the resources in to a bundle at compile time and compile any .xib files to .nibs, this is also a possible solution you could look at.
I'm trying to create an NSService in a Bundle project. I need to add a main and other bits of code to the actual cocoa bundle created for me by xcode.
Is this as simple as just adding an object-c class via the xcode wizard, then adding my main function to that? or is there some other magic way or other steps involved?.
Many thanks.
You can add code by simply adding source files.
A bundle normally does not have a main function since it is loaded from another executable.
thanks Nikolia - after adding the code, i also had to change the bundle type to Executable, which also allowed me to change the extension from .bundle to .service.
Now all I need to do is work out how to stop the service!