I'm building an iOS app using Xcode 3.2.5 with the Base SDK set to iOS 4.2
I know I've used some api's from 4.0 and 4.1 but not sure about whether I actually require 4.2.
According to the iOS Development Guide, "Xcode displays build warnings when it detects that your application is using a feature that’s not available in the target OS release".
So I was hoping to use the compiler warnings to derive my minimum OS requirement.
However, even when I set my iOS Deployment Target to iOS 3.0, I still don't get any compiler warnings.
I must be doing something wrong, but not sure what? Can anyone confirm that they get compiler warnings when the iOS deployment target is less than the base SDK and the code uses base SDK functions? Or do the compiler warnings only show if you link a framework that didn't exist in the iOS deployment target version?
It's behaving as expected: changing the deployment target only affects the minimum OS version you app will run on, not the maximum.
If you use the 4.3 SDK and set the deployment target to 4.0, it just means your app will hard-link any pre-4.0 APIs and weak-link any APIs introduced between 4.0 and 4.3. You have to check at runtime either for the existence of the API (e.g. null pointer for C functions) or the OS version.
The deployment target does generate Xcode warnings but for deprecated APIs: for example if you use an API deprecated in 4.1 and later and the deployment target is 4.1 or later, you get a warning, but if it's 4.0 or earlier, you don't.
It looks like what you really need in your case is the equivalent of MAC_OS_X_VERSION_MAX_ALLOWED (it's not part of the default build settings, but you can custom define it and it should override the value set by the SDK) but for iOS SDK. I'm not sure it officially exists actually: I was able to find a __IPHONE_OS_VERSION_MAX_ALLOWED but considering it starts with __, I'm not sure it's really supported.
The right solution appears to simply build against previous versions of the SDK (you can always do that in the Simulator) and you will get Xcode errors if using missing APIs.
For more info, read this technote: http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/cross_development/Configuring/configuring.html
temporarily change your base sdk to see them
Edited: for detecting new APIs that are only available in new versions of iOS, I don't think Xcode can do it automatically for us. We need to put them in our mind by ourselves. My suggested reading source:
Login into your dev account and search API diffs. These official API diffs documents should be thorough and helpful.
Check this great post on how to wrap up your code to make it compatible on lower versions of iOS:
===
Try clean your project's build folder. After that you should see warnings on deprecated APIs that your code used.
Related
I was wondering if it's possible to downgrade an app from the app store (ARM binary) to a lower version. For example if the app requires iOS 5.0 or 4.3 or later getting it to run on iOS 4.2 or 4.0.
I understand that the requirements are important as the newer version contains API linked calls only exposed on the newer iOS platform. However, I've many apps that are cabable of running on lower versions are needlessly compiled on newer versions of xcode (just a minor update supports a huge jump on iOS supported version, like iOs 4.0 -> iOs 5.0)
What I would like to do is maybe downgrade an iOS 5.0 app to iOS 4.3 app by verifying that there are no new linked functions apis and thereby adjusting the plist files to the lower vesion? Can otool or class-dump help with this?
Yes, it's possible. Submit a binary with a different "iOS Deployment Target" (in Project > Info and Targets > Deployment Target), even if it is lower than the one you currently have.
You'll need to do extensive testing to make sure your code runs on the various compatible iOS, since a lot has changed with the release of iOS 5 (and subsequently, 6), meaning a lot of functions and methods will not be recognized in those iOS versions.
Regarding finding which API's may not work, here's a small discussion of [Finding unsupported API's with OS version][1]
[1]: finding unsupported apis with os version "Finding unsupported API's with OS version".
Can anyone please explain the concept of iOS deployment target build setting in iOS project. I have an application which I needed to support from iOS 4.3 up till iOS 6.0. What should be my iOS deployment target?
When I set this to 4.3 it compiles well but if I change it to 6.0 I see lot of compilation warnings for deprecated methods. What is the ideal way of handling this. Shall I remove all the warnings I see on iOS 6.0 keeping in mind that it still supports 4.3 targets?
Deployment target is the earliest version of iOS that can run your application. So if you want to support from iOS 4.3 to 6.0 you should have Deployment target set to 4.3 and Base SDK to iOS 6.0.
Deprecated methods are methods that will no longer be supported in future versions of the SDK. These methods give a warning and could lead to unsafe code, because there is a better approach. Its encouraged not to use them. Sometimes, you need to run one method or other depending on the version of the OS, but this becomes out of the scope of the question ;-)
As a conclusion, the ideal depends on your product, but keep in mind that iOS users adopt new versions of the OS quite early. So I would go from iOS 5.0 to 6.0, but this is my personal opinion ;-)
The deployment target is how you specify the minimum required iOS version for your app. If you need to support iOS 4.3 and above, your deployment target should be iOS 4.3.
A "deprecated method" is one that has been marked for removal from the SDK at some point in the future. Depending on the API in question, you may have no choice but to continue using them as long as you have to target iOS 4.3.
Consider raising your required iOS version as soon as is reasonably possible so that you can take advantage of the newest APIs. This will give the best overall compatibility and performance on the largest number of recent iOS devices.
Please tell me which version of the iOS SDK i should use so that my app works on iPhone 3.0 or later.
There are two different concepts you should be aware of:
The Base SDK
This is what you use to build your application. The most recent release is 4.2 so you should use that to build your applications against.
The iOS Deployment Target
This is the target version of iOS you are building for. In your case, you set that (in Project or Target settings of Xcode) to "iOS 3.0".
The rest is up to you. You are, of course, building for many versions of the SDK, so if you use something that was introduced in any SDK after 3.0, you need to test for that functionality explicitly.
This is not a question of "which to use" but a question of "which one you have to use to get your apps accepted by apple", and the answer for that is: Use the newest one marked stable that is available to you. Apple accepts only Apps submitted for the AppStore build with one of the latest 2 (or so) Versions.
For setup see the answer of Typeoneerror and be aware, that you can build with a newer Base SDK (in fact you have to) but the compiler will not warn you if you use functions that are not available in your "Deployment Target", so you will have to test your app with a device that has the old iOS version installed to be sure it doesn't crash!
I'm wondering if I will have compatibility issues with OS4.0 if my app is built with the 4.1 SDK, or is this a non-issue?
The short answer to your question is: Use a Base SDK Version of at least 4.0 for your application and a Deployment Target Version of exactly 4.0.
I've downvoted both answers because they are wrong or at least incomplete.
When building applications there are two settings that you should be aware of:
There is the Base SDK Version which defines against which version of the SDK your application will be compiled.
There is also the Deployment Target Version which defines the lowest version of the iOS that your application requires. You can set this to as low as 2.2.1 in Xcode but the App Store will not accept versions lower then 3.1.3 at the moment.
The Base SDK Version can be higher then the Deployment Target Version. This simply means that your application is backward compatible with older version of the iOS. This also means that your app needs to make decisions at runtime to be sure not to use newer functionality when running on an older version.
For example, the MFMessageComposeViewController was introduced in 4.0 so if your app has been configured to also run on 3.1.3 then you should use NSClassFromString() to find if that specific class is actually available before you use it.
There are many questions here on Stack Overflow on how to discover available functionality so I will not repeat those techniques here.
And a somewhat important note:
Behaviour does change across OS releases. There were a pile of changes in 3.0 (we had issues with UITableView/UITableViewCell):
Some changes happened on old apps (e.g. compiled for 2.2.1). I forget what these were.
Some of them were in the toolchain (I think they changed how nibs were compiled with ibtool; it was something like setting both an image and a custom view for a UITableViewCell). This happened when we upgraded the SDK on the build server, even if we didn't touch "Base SDK"
Some of them happen only when you compiled with a Base SDK of 3.0 (UIKit automagically detects which version you've linked against and has backwards-compatability modes for some things)
Additionally, there were some runtime/C++ changes in GCC 4.2, which meant a GCC 4.2 app running on OS 2.2.1 crashed when casting unsigned int/long to float/double or using std::ostringstream. I've since added a check for GCC version.
So no, compiling with a newer SDK can result in issues — you might not want to risk it if there are time constraints (you don't have time to implement multitasking support, or you don't have time to do a complete re-test and fix all the bugs, or so). Or maybe you still want to support 2.2.1 for some strange reason (4.0 dropped 2.x "device support", which effectively made it impossible to debug apps on 2.x devices).
Usually nothing breaks across minor OS releases (discounting 3.1/3.2). I'd recommend upgrading SDKs as soon as you have the time; don't shy away from new features just because old OSes don't have them.
Depending on the APIs you will be using. Let's say you want to implemented in-app texting (MFMessageComposeViewController) and want ALL of your end-users (will be defined as EUs) to access that feature then you'll have to compile against iOS 4.0. But let's say you want the in-app texting to be optional and a "plus" for your EUs, you'll just compile your app against iOS 3.0 (let's say).
Hope I answered your question :-)
I know that parts of this question was asked in several variation but I want to make sure I got it right.
Here are my assumptions and understandings which I want to know if they are correct before submitting.
My application assumes features supported by all OS, and so I should:
Set the Active SDK to be the latest (currently SDK 3.0).
Set the Deployment Target to be the lower I want to be supported - iPhone 2.0 and higher?
What exactly is the Base SDK for? should I ignore it if I chose Active SDK to be different and where do I see the Active SDK in the Projects settings?
One final question - is apple allowing to choose iPhone OS 2.0 as the Deployment Target?
Thanks in advance,
BTW - one of my main reason for this question is because when compiling with earlier SDKs apple seems to have a problem releasing the memory for UIImageView animation array when this animation was saved for multiple time usage. This is a known problem that was fixed with SDK 3.0 (by simply setting the UIImageView animation array to nil)
The difference between the Base and Active SDK is that the former is the default SDK set for the project and the latter is the SDK you are currently building against. So it is possible for your Active SDK to be the Base SDK, at which point XCode will use the SDK you specified for the project.
In order to build your app for the widest set of devices possible, you are correct:
Set the Base SDK to the lastest SDK possible (3.0, 3.0.1)
Set the Deployment Target to the earliest SDK possible (2.0)
Apple does allow you to specify iPhone 2.0 as the Deployment Target, but keep in mind any API or framework released after iPhone 2.0 you will not have available to you for use by default. There are techniques to use features from later SDKs, however they are nontrivial.
You should set the Base SDK build setting to the latest SDK that contains all of the features that you intend to use (usually, the latest available SDK), and set the "iPhone Deployment Target" build setting to the earliest version of the OS on which you want to run.
You then need to make sure that you check, at runtime, for any features that may not exist on the earlier OSes.
"Base SDK" is the Maximum SDK you application can support. There's a hard limit here - you can't select a future, unreleased SDK.
"Deployment Target" is the Minimum SDK you are willing to support. It how far back in time you are willing to go.
Xcode appear to create a spurious dependency on "Deployment Target." For example, I can't develop on my iOS 5.1.1 iPod with Xcode 4.5.2 (Xcode 4.5.2 is paired with iOS 6.0), even though the 4.3, 5.0, and 5.1 APIs and Simulators are installed on this installation. I need to use the simulator or jack in my iOS 6.0 iPhone.
The games Apple is playing appears to be causing problems with apps, too. My purchased copy of Elements will not sync via iTunes to the iPod because Elements needs a newer version of iOS to run (it syncs and runs fine on my iOS 6.0 iPhone).
I've got two iPads and one is 4.3. I shudder to think what a mess it will cause.
In general;
Set the BASE SDK to the very latest SDK you are willing to support and test.
Set the Deployment Target to the lowest version of iOS you are willing to support and test.
If you happen to use Base SDK features not available on the deployment target SDK, the app will crash at runtime on older devices, so testing is vital.
An alternative / complementary process would be to use Deploymate http://www.deploymateapp.com/ which does static code analysis to identify problems.
If you are from the android world the analogies are such;
TargetSDK -> Base SDK
MinSDK -> Deployment Target
Lint -> Deploymate