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

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.).

Related

Core Data DB Location Debug v Release Build

I have been developing my first SWIFT MacOS App and it uses Core Data. I've just done my first release build and found that it still points at the same SQL Lite DB as my debug build. As I didn't not specify it's location I assumed (incorrectly) it would be in a different location for release.
How do I specify the location of the Database for Core Data ? Is there a way to automatically set a different location for Debug and Release ? I want to be able to run release and debug on the same machine.
What I usually do is have separate debug and release versions of the app. Then I can have both installed on the same device at the same time. The persistent store (and other files) use the same file names, but since they're separate apps the data is separate.
You can do this by duplicating the app target in Xcode, and making a few changes. In the list of targets, right-click your app and select "duplicate". Give the new one a similar but slightly different name. For example, maybe add "-dev" to your app's name to indicate it's the development target.
You'll also need to change the bundle ID and display name of the app. The bundle ID tells iOS it's a different app, and the display name makes it obvious which one you're tapping. You can also add a different app icon if you like.
Now you can build two versions of the app and install both on the same device. The dev version can have whatever code you're working on that's maybe still kind of broken, and the release version can be whatever's ready for release or a version downloaded from the App Store.
In iOS, your CoreData database file is usually located in Library/Application Support within the sandboxed App. Pre iOS 10 it used to be in the Documents folder.
On MacOS with sandboxing enabled it's usually located at ~/Library/Containers/<app_bundle_id>/Data/Library/Application Support/<app_target_name>
Depending on your needs, you can choose different locations for each of your persistent stores when you setup the CoreData stack.
However, I don't see any reason to choose different store locations for different Build Configurations. Thats not the purpose for Build Configurations anyway. Your database will end up being exactly the same - it cannot be affected by build settings.
I would also not recommend to use different store locations for any purpose - except perhaps when you perform Unit Tests.
What you can do however, is to set certain environment flags that affect CoreData's behaviour, for example that enables Thread Violation Assertions. You do this in Xcode Schemes - not in the build settings. Note, that a scheme uses a certain Build Configuration, say Release or Debug and that the name for the scheme can be the same which is often confusing.
You should ensure that these helpful assertions that you can set in a Scheme are not enabled when you build a release. ;)

Is it possible to generate two different IPAs on Xcode 4 using the same project? One for iPhone and one for iPad?

I currently have an Universal iOS app, but with the new iPad3 device we needed to add resources/sprites for that specific device, the problem is that the size of the IPA has become incredible larger thanks to the huge new screen. I was wondering if its possible to have only one Xcode 4 Project that could generate two different IPAs, one with target:iphone and other with target:ipad, that could also include or exclude files depending on the file extension, for example blah-ipad.png wont be on the iphone version.
Thanks!
#Conrad Shultz is correct about why you shouldn't split an existing paid app into two.
For people who haven't released their app, or whose app is free, it's worth knowing that you can duplicate a Target by right-clicking (or control-clicking) on it and selecting Duplicate. I'm pretty sure Duplication is only offered through this context menu. The more obvious 'Add Target' options involve creating a whole new Target and manually duplicating the contents and settings of your existing Target.
Once you have multiple targets, you can specify which resources are distributed with each.
Edit: you will also need to change the 'Devices' setting if you have an iPhone Target and an iPad Target.
If you have a lot of resources, consider including them in folders with Folder References. Then you can specify target membership for the entire folder, without having to change individual files. This will change the path to those resources within your bundle, so plan accordingly.
Yes and no.
You can certainly set up different build targets (and schemes) for different products, targeting different device families, different architectures, even entirely different platforms (OS X vs. iOS). You can of course include different assets in each. I personally do this all the time, so if that's what you're looking to do, let me know and I'll try to provide further details.
But what you can't do is submit multiple IPAs for a single product to the App Store. If you are already distributing a Universal app through the App Store, your only recourse would be to pull it and create two new apps with new bundle identifiers, product names, etc. (I don't think, but I could be wrong on this point, that you can even downgrade a Universal app to a single-family app, but that's something you'd have to check in the developer/App Store documentation and agreements.)
If you went this route, you would force existing users to purchase the new app again at full price. This would likely be poorly received by customers. If I were you, I'd look at whether the size difference is really large enough to worry about and, if so, look at strategies for reusing assets across devices (for example, downscaling higher resolution images on #1x devices), though this introduces possible performance penalties.

What do I need to do to configure a new iPhone project so it can be seen as the same as my current iPhone app in the Appstore?

I currently have an app in the Appstore. I need to make changes to the app, but they are significant enough that we've decided it would be easier to create a new Xcode project from scratch rather than modify our existing project. I don't fully understand everything that goes into an iPhone application, just enough to support the code and make basic changes. But I assume that the binary I upload to the Appstore, to replace my existing code there, needs to be similar enough so Apples sees it as the "same" code. What things in the new project do I need to make sure are the same as the old project so Apple knows it's the "same" app?
I've compared the Info.plist file in both projects to make sure they're the same. I only needed to change the bundle identifier in the new project to match the old. Also, the Product Name has been modified to be the same. I don't know if these changes are necessary, but they are the sort of things that I think need to be the same. Are there others? If so, what are they?
The only thing that matters, as far as the app store is concerned, is the app id (Bundle identifier). You can rename the app, change the icon, upload an entirely different program, whatever. As long as the app id matches, the store considers it the same.
Other things I would check are the Build Settings if the defaults are not suitable or the Code is having issues compiling and the Build Phases and Build Rules for all your Targets.
Essentially if your Code compiles fine and you have no issues within the Application then the Bundle Identifier and the name (Basically the Info.plist) needs to be the same to replicate.
Edit: If you have migrated from an older Xcode version then you may have different Build Settings and Build Phases. I would just see if compilation is okay and the App works properly in functionality under all your Targets

Is a Dynamically Linked Framework possible on iOS?

The keyword here is possible. I know of a few resources that talk about this and how to create static frameworks - here: https://github.com/kstenerud/iOS-Universal-Framework and here: http://db-in.com/blog/2011/07/universal-framework-iphone-ios-2-0/
I'm interested to see if it's possible to create a dynamically linked framework in an app that will not be submitted to the app store. I know it's impossible to write to the application bundle on a device without jailbreaking it. Is it possible to say, download a compiled framework file, put it in the documents directory and then access it via the application (think plug-in architecture). I know that if it is, you would be turned away from the app store for submitting it, but let's say this was an enterprise app, or an ad-hoc distributed app where Apple would not have to approve.
In my initial research I haven't found anything supporting that it is possible, but I feel like this may be such a fringe case that no one has published anything about it. Looking for a guru to give me a definite "no" before I give up.
not sure if this is what you are after but according to Apple there dynamically linked libraries even usable in iOS - for example the system libraries... XCode contains copies of them and references them via symbolic links...
see near the end of this http://developer.apple.com/library/ios/#documentation/Miscellaneous/Conceptual/iPhoneOSTechOverview/iPhoneOSFrameworks/iPhoneOSFrameworks.html#//apple_ref/doc/uid/TP40007898-CH6-SW3
just an idea:
put the .dylib + include files you want to use into the respective folders where XCode expects the system libraries... use themn and then put symlinks into your bundle on deployment... let the symlinks point where ou copy the .dylib
I believe the answer is no. Apps on the iPhone are sandboxed. That is, aside from Apple supplied frameworks, an app cannot access anything outside of its own build.
This is possible now with IOS 8 Xcode 6.

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.