Discover calls to methods not available in earlier iOS versions - objective-c

I am building my app using iOS 5.0 as base SDK and iOS 3.0 as deployment target.
I know I need to check for existence of methods and classes when I work with features that are not available in the earlier iOS versions, but lately I've lost a few hours on a problem just to discover I was calling a method not available in some iOS versions. I simply did not notice it was a new method and did no check before to call it. The app of course compiled with 0 errors and 0 warnings.
This is a big problem because if I forgot some other check somewhere in the app, I will not know it until I or, worst, some user will activate that specific part of code.
Maybe I am missing something, is there some compiler option I can set to detect the calls I make to methods not available in the iOS deployment target? How do you deal with such a problem?

This link might point you in the right direction. Supporting mutiple ios Versions in your apps. It explains how to deal with taking advantage of the newer ios features while maintaining backwards compatibility. Hope that helps.

The only way to check for compatibility with a prior version of iOS, currently, it to test the app on an old non-updated device running that version of the OS.
If you can't find a device that old, even just to borrow for short time, then there may not be a good buiness reason to set the Deployment target that low.

Related

Is there a way to tell (at build-time) if my 10.9 app will run on 10.8?

I have an app I've been developing under 10.9 using the 10.9 SDK, and I want to distribute it to my friends who are running 10.8. I know I can't guarantee it'll work there without finding an OS X 10.8 system (maybe in a virtual machine) and running it there, but is there any way I can check that I'm not using any 10.9-only APIs? Or even get a list of 10.9-only APIs that my application uses?
My understanding is that:
"Deployment Target" doesn't do this -- this just sets the LC_VERSION_MIN_MACOSX, so that if you tried to run it on an earlier version of OS X, it would refuse to even start.
"Base SDK" doesn't do this -- this is the version of the API it's compiled with. Some features added in newer versions of the SDK are available even on older versions of OS X at runtime (e.g., NSArray -firstObject).
Xcode's static analysis is pretty good at identifying the source of symbols (classes / methods) that I use, so it seems like this should be fairly easy to do, but I don't know how to do it.
"Base SDK" does what you want in a legalistic sense. Yes you may get some false negatives - for methods like firstObject - but better those than false positives. You can check any reported non-existant APIs and put in code to check dynamically (respondsToSelector:) and code defensively for those cases, or ignore them if you must and are really sure they are available.

Switch to xCode5 with the new SDK will eliminate bugs?

I've just installed ios7 on my iPhone, however I have not yet downloaded xCode5, so I've been producing my archives using iOS6 SDK and using TestFlight to test them on my phone. When running my app on iOS7, I'm noticing a lot of bugs that I didn't see in iOS6 (some that are unpredictable and very difficult to fix). I've been avoiding downloading xCode7 because I'm not yet ready to make the commitment to the new UI elements, but I'm wondering if I did produce my app using the iOS7 SDK, is it possible some of these bugs could be eliminated?
This is a very broad question. iOS 7, despite its advanced beta count, is still very much a work in progress. There are bugs that should be reported to Apple that should not happen. But beyond that, there are changes in the internal API that influence how the app behaves. Apple has done its best to try and preserve SDK 6 apps as much as possible, but there is breaking API which can cause crashes. One example off the top of my head is the class cluster they are now using with ABPersonViewController. Subclassing that in iOS 6 works fine, but in iOS 7, even when compiled with SDK 6, causes a crash in most cases. These issues can be resolved even with Xcode 4.6 and SDK 6.
Compiling with SDK 7 may help you fix some issues, but it will come with a plethora of issues of its own. Depending on how complex your view hierarchy is, you may have to invest a considerable amount of effort to support the new API and functionality. You don't really have a choice, as this is the future, but you should be prepared for this, and arrange your schedule accordingly.

making app compatible with previous iOS versions

I just released my app but I am only able to make it compatible from 4.3 and up.
When I try to go any lower than 4.3 (xcode), it says I need to add code to make this work.
Does anyone know how to do this or has any suggestions? I would like my app to be compatible with 3.0 and onwards.
Thank you very much
You have to reach the least common code, what I mean by this is that you must find all the methods that are all incompatible within all of these versions of the OS. After that you will have to find each and every of it's functional equivalents. Then you can use conditional statements to check for every version and see what fits better or you can use the respondsToSelector method inherited from the NSObject class. In the end you have to test it on each device you are targeting :P
You can run this checkup list that I have always liked.
Edit:
I think I misunderstood your question though it has already been mentioned, be sure to check your deployment target in your build settings.
Checklist:
In your project's build settingsā€¦
Did you set the "iOS Deployment Target" to iOS 3?
Did you include the armv6 architecture in both, the built and the valid architectures?
In general:
Do you link to any framework that is not supported on iOS 3?
Do you use any methods, classes or other features that have been added later?

How check the availably of all objective-c function in source code for Cocoa

When you read the Class Reference of every object of iOS, you will find:
Available in iOS 2.0 and later.
There are a program or a way to list all function and the minimum iOS system?
How can I know if the iPhone with iOS 3.0 will run all iOS function? I can check it in runtime with respondToSelector, but can be more easy with source code?
Set your project's base SDK to iOS 3, and see if it builds.
AFAIK there is no way to list all the APIs you use in your app into one list and check that you are building past the minimum for all those APIs. You will just have to check each one, one by one. Highlight the API in Xcode, and then click escape and it will tell you very easily.
But also I have to mention that this won't be extremely necessary since you should test on the minimum OS you are building for and if it crashes at any point then you have your issue for that certain API.

Check for availability of blocks at runtime on iOS

I need to test for the availability of blocks at runtime, so I can handle backwards compatibility with iOS 3. Any tips?
edit:
So far I'm doing if (!NSClassFromString(#"NSBlockOperation")) {...}
Seems to be working...
You will also need to make sure to weak link the libSystem.B.dylib, set your base SDK to 4.0 and deployment target to 3.1.3, as described here.
A good overview on how to deal with iOS versioning issues can also be found in this this Cocoa with Love article: Tips & Tricks for conditional iOS3, iOS3.2 and iOS4 code