How to get multiple targets into one binary for app store submission? - iphone

I have split my iPhone app into two targets one for the ipad and one for the iphone. When I upload to the appstore I can only have one binary. But I have two targets?
I think I am missing a step. Thanks in advance for any help.

A "target" encompasses all of the instructions that Xcode uses to build your app.
You can have two targets inside of one binary, although this is not always done. This is how Universal Binaries are made. The two apps are bundled together inside of one binary. If you open up a Mac app "bundle" you will notice a few meta files, like icons and such, and there will be the actual compiled binary code. An iOS Universal Binary has both apps inside of it.
(If you watch your compilation carefully, you'll notice that Xcode actually builds your app twice. It does one build for iPhone/iPod and one for iPad.)
Provided that your Xcode project is set up properly, you will get the intended results.

The binary will be fine, the "targets" refer to what runs when it is run on an iPhone vs iPad. If the project is setup correctly for universal it should work fine.

Related

Can two iPhone apps built from the same code use different iTunesArtwork (full version & lite/free version)?

I am currently building a full and a lite/free version of an iPhone app from the same source (along the lines of Creating Lite Versions of iPhone Games / Apps). This works great.
The only thing I cannot figure out is how to have two different iTunesArtwork files included in the respective build (e.g. one with a "lite" stamp on it, one without).
I read App Icons on iPad and iPhone on Apple's page but they don't say what to do with iTunesArtwork. I did include different "Icon.png" etc. files in the two different *.plists I have and this works as expected. But what about iTunesArtwork?
Am I missing something?
It is not required to embed the 512x512 artwork into your bundle. In iTunes Connect you will be able to upload the 512x512 file and you will be able to upload screen captures for the two different apps.
In XCode 4 you can create a group where you put your target specific files and assign them the correct target membership in the identity inspector.
Thus you have always the correct iTunesArtwork in your .ipa file.
This worked for me like a charm.
Hope it helps.

Is there a global way to merge an iPhone and an iPad app into a universal app?

I wrote an iPhone app. Then, I changed the interface a fair bit, added higher res images, and made an iPad version of it. In a perfect world, I would like for anyone who buys the iPad version to get the iPhone version for free (though not conversely). Since Apple doesn't seem to have a way to do that (right??), my next favorite solution is to make the iPad version include the iPhone version somehow.
I know that I could just convert the iPad version to "universal", but since the face of the app is so different, that seems like a real pain. I have many view controllers and they are almost completely different between the two versions. Some of the methods are the same, but only about 30%. Is there an easy solution along the lines of this:
Check if device is iPhone or iPad
If iPhone, then use one group of files
If iPad, then use a different group of files
Thanks in advance!
Try creating a new project in Xcode and choose to make it a universal app. In the default way Xcode lays it out, there is a distinct divide between the iPad and iPhone versions. You can make the two versions of the app as similar or different as you want.
In addition, you can check which device you are running on at runtime by using UI_USER_INTERFACE_IDIOM(). Currently the two values for this are UIUserInterfaceIdiomPad and UIUserInterfaceIdiomPhone.
The "easy solution" you describe is basically how iOS loads Universal apps.
There's no other real way around it. You'll have to merge your two projects into one again to do what you want.
The first problem will be that some (many?) names of classes will be common between both projects. You can save yourself some pain by using the "Refactor..." functionality in Xcode to change the names of the classes in one project (say, your iPhone app, since it's older) before you merge them together. The second problem will be your Info.plist; you'll need to ensure that the correct "Main nib file base name", the correct supported interface orientations, icon files, and so on are set to correct values for both iPad and iPhone respectively.

Can I keep one project in XCode but build it for Mac OS X, Apple Mac Store and iOS device(s)?

I noticed that there are different requirements for each platform here. I was wondering if it's possible to build a single project but with multiple targets where each target is Mac OS X (something like a CD / install build), Apple Mac Store, and iOS device.
IfIi'm going about this the wrong way then I'd love to know! I mostly develop on the PC but with the state of the App Store I'd love to spread out as much as I can!
Keeping separate targets for the Mac app store and an independently-distributed Mac application is simple. You just need to ensure that your receipt validation code is conditionally included on the app store target and not in the other target; and your custom licensing scheme is included the other way round. Things get a bit more complicated if you target different operating systems in the two targets, but they're not insurmountable: you can test for the existence of classes or selectors at runtime to ensure you never call newer API on older systems.
By the way, it's also worth having separate Info.plist files for these targets. Partly because you don't need or want to include things like Sparkle properties in your app store target, but also because each target should have a unique bundle identifier. The app store does odd things when you have an app installed that it thinks came from the store but really didn't, and you don't want to risk your updater or Apple's trying to update the app deployed via the other mechanism. But that's not really about organising your Xcode project, it's a deployment issue.
For the most part, yes. All Mac/iOS apps can be written in Objective-C and the code is very similar. However, you must bear in mind that iOS devices have different screen sizes from the Mac and even from each other. That means that the input metaphor is different, and that the UI is different. While it is possible to do what you want, it's not advisable to just code once and compile thrice.
That said, I don't use Xcode 4 so I can't tell you about that. Of you are looking to do different builds for different devices, you will want to write your app logic and your input logic as separately as possible. Then, you create multiple targets, one for each build. You define compiler flags for each target. In your code you will use those flags to use the appropriate code for your build.
At least as of 3.2.5, this is absolutely not a problem. You won't necessarily be able to apply all of your build settings project-wide, but you can specify them on a per-target basis.
Just add the appropriate-type target (Cocoa Touch, Cocoa, etc.).

What's the best way using XCode to install multiple builds of the same iOS app to your iPhone?

I frequently find that I need to have a build on my iPhone which is my 'demo-ready' version which might point to my demo server. I also want a build that is the latest and greatest debug build that I'm developing with that points to my development server. Has anyone found a really simple way for me to install two apps that perhaps are the exact same code but point to different servers? Alternately perhaps I would have an app that was a few versions behind the latest version? Preferably I would use the same XCode project to build and install onto the iPhone.
You can add special build configurations for them that each use a different info.plist file. So, maybe for your demo, you have an info.plist named MyApp-Info-DEMO.plist and MyApp-Info.plist for the release.
Then you could add your server variable as an info.plist variable and look it up when the app starts. Or even just create a DEFINE statement in your new configuration that's something like SERVER=demo.myserver.com for the demo and SERVER=production.myserver.com for the live.
The most important part is to change the CFBundleIdentifier in the new info.plist. So in your demo, you could name it something like com.mycompany.myapp.DEMO and the real one might just be com.mycompany.myapp.
This will allow both versions to appear on the phone at the same time (the different CFBundleIdentifiers). Just remember, if you are using in-app purchases or server push notifications, you won't be able to do this without a separate, specific profile for both your real app identifier and your demo one.
You could create 2 different targets with 2 different info.plists and 2 different preprocessor defines (in the Build Settings for each of the 2 targets). Then ifdef on the preprocessor defines to select the server constant the compiler uses for each target.
Then make the product name and the bundle ID different in the two different target settings (so that neither the device or the Simulator will confuse the two app bundles).
With the current version of Xcode, you'd achieve this by changing the app's Info.plist file to use a different bundle identifier (and possibly also change the Product Name of the app in the build settings).
The upcoming version of Xcode, from what I've read in the prerelease documentation, has a feature that may simplify what you want to do quite a bit. However, since prerelease software is covered under NDA, I can't give you any details.

Whats the best way to create an iPhone and an iPad application simultaneously?

I have an iPhone app that I would like to port over to the iPad, but I would like to have as little duplication as possible.
How do people usually go about doing this?
In xcode can you have different targets for iPhone and iPad and perhaps do some pre-processor checks? Or is it best to simply have two separate projects altogether?
Note, Im NOT talking about running the iPhone app on the iPad, I mean creating a native 3.2 app...
EDIT
So it looks like creating a universal application is the way to go:
http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/StartingYourProject/StartingYourProject.html#//apple_ref/doc/uid/TP40009370-CH9-SW8
But what I still dont understand is how to select different NIB files based on your current deployment???
Thanks a lot
For minimal duplication, you can use one project, with 2 sets of .nib files, but one set of source code files which include run-time checks for the UIUserInterfaceIdiom differences.
If you want two (or more) apps instead of a Universal app, just create two targets containing only the appropriate .nib files, and #ifdef the run-time check results using a Preprocessor Macro define in each target's Build Settings to force iPhone or iPad idiom only.
The latest (3.2.3) Xcode auto-generates a Universal project which is a great starting point to see how to target iPad and iPhone in one Xcode project.
File > New Project > Window-based Application > Product : Universal