Sanity-check for iOS API versions used within an application - ios

I have an application where I am supporting a deployment target of 4.3 with a base SDK of 6.x.
I find myself having to weak link API methods and provide alternative workarounds for older runtime based on strategies found in the document "Using SDK-Based Development".
The problem I am facing is, occasionally and unintentionally, I would use a method that is available only in a newer SDK without realizing it and did not weak-link the method. This causes a crash for users running the app on an older version of the OS.
While I know the number of users having that old a runtime (iOS 4.3) is diminishing, I would like to know if there is a tool or a way for us to generate a report that would list APIs available in SDKs other than that of the deployment target, so that I may review the code to ensure proper weak-linking is performed, prior to shipping the product.
Off the top of my head, compiling the source to an older version of the SDK should throw errors, but then again, Apple's strategy has always been to ship new XCode without older SDKs.
I am not looking for a perfect solution. Any other workarounds would be helpful too.

If you don't mind paying, Deploymate can scan your project and identify API calls which may fail on older operating system versions. Works with Mac and iOS apps/projects.
Deploymate helps you identify unavailable, deprecated and obsolete API usage in your Xcode projects

Related

Xcode How to check if there is any API used in the whole project which is not available for the current development target

Recently my app was getting crashed on IOS8 because i have used an API which is only available for IOS 9 and above. I am wondering is there anyway to check the whole project and find out if I am using any API which is not available for the current development target. Something like the warnings for the deprecated APIs. Thanks.
In order to tell the compiler you want to support an earlier OS, you need to set the SDK to that earlier OS's SDK. If you set the SDK to iOS 8, then any time you use functionality from a later OS, you should get a compiler error.

How to build a MonoTouch app with SDK version 4.x (not target earlier version with current sdk)

I have a legacy application distributed Ad-Hoc that runs on older iPod Touches (running iOS 3.1.3) with a custom connection to rather expensive 3rd party hardware. Unfortunately my annual renewal of the provisioning profile (which also involved rebuilding with the most recent version of XCode that will compile armv6 (4.5) and the corresponding SDK) seems to have broken the app.
I know that you can set the target platform earlier (and I've done that). But my problem seems to be specifically related to the SDK. The hardware these devices interface with is several hundred miles from me so testing is very difficult.
My first set of problems were related to deprecation of the TouchID APIs, but I've worked around that problem. Unforatunately, I still have crashes and they are proving very elusive to debug.
The simplest solution for me would be to just rebuild against the older SDK (4.x). Is this possible? To make matters worse my Mac is running 10.8.4--so there's a limit to how far back I can get XCode working on it.
I was able to get this to work by renaming my current version of XCode to something else, downloading and installing XCode 4.4 something from the developer site. Then I downloaded an earlier version yet and used the techniques described in this post:
Adding Older iOS SDKs to Xcode 4.1 in Lion
To extract the older SDKs. I was then able to copy these SDKs into XCode 4.4 (as described in the post). Now I was able to build using older versions of the SDK.

MonoTouch: Approaching Obsolete iOS methods

As iOS is upgraded the signatures and methods of older versions get marked as obsolete by MonoTouch.
My question is, if we take the suggestion for a new method that MonoTouch offers , will we be negatively affecting older iOS versions?
I understand that new features, such as Facebook in iOS 6 are not available in 4.3, but this question is more about migration for MonoTouch apps to higher versions of IOS while keeping compatibility.
For example:
An iOS 4.3 device running a MonoTouch 6 app : Will removing obsolete methods and replacing them with the new ones work still ?
There's no single, general, answer as it depend why the method/type was obsoleted.
Most [Obsolete] attributes have a message stating why you should avoid them. They mostly fall in two groups:
There was a binding error in the API, e.g. a typo. A new API was added to correct this (and its name should be part of the description). In this case there is no problem, for a 4.3 device, to use the new API added in MonoTouch 6.x;
Apple introduced a new API and deprecated the use of an older one. In this case the description should state the new API and the iOS version where it applies. You should not use the new API (e.g. anything added in iOS 6.0) if you wish to target older devices (e.g. 5.x).
If you find [Obsolete] method/types without any text message or when the text is not clear enough to allow you to make a clear decision please file a bug report so it can be corrected.
This may help in testing. Add old iPhone Simulators:
open xcode and in the top menu go to xcode >> preferences >> Downloads and you will be given the option to download old sdks to use with xcode. You can also download command line tools and Device Debugging Support.
This will let you go to the simulators Hardware/Version menu and choose 4.3 or 5.0 or 5.1 etc.

Do new Apple SDKs patch previous releases?

A new iPhone will be soon out there along a new iOS release. Sooner or later there will also be a Xcode upgrade with the SDK for iOS 6
Does Apple do any type of bugfix on previous SDKs or are bugfixes just solved on new releases?
As an example: Core Data with iCloud still have some issues but it is getting better over time. Let's say I have an app that really depends on that combo. I would require iOS6, however not all users upgrade the handsets. Ideally an app compiled with a newer XCode release could patch some error on previous SDKs if the target is set to an older iOS release.
Should I expect that a project compiled with future SDK releases to work better on devices running on older iOS versions? will be some SDKs bugfixes backported?
I understand that there are some bugs that cannot be fixed without an iOS update on the client. Also that it is a lot of work (and unlikely) to backport bugfixes. I am just wondering what is the normal release policy of Apple.
The new SDK may enable some new features on old iOS versions due to new constants or functions becoming documented, but it won't fix anything.
You can be reasonably sure at this point there will never be an iOS 5.2. Bugs are here to stay, unless they're security issues and Apple decides to do a security release. I doubt they'll bother, as only the original iPad is being abandoned over this ugprade.

Updating apps to iOS6

Haven't been able to find an accurate response to this question on Apple Developer forums.
As with other Apple Developers, I will upgrading our apps to support iOS6 devices.
I've downloaded XCode 4.5 which supports iOS6 SDK.
I understand I cannot submit versions of my app to the app store using this XCode build, however:
if I re-compile and build an app using the deployment target of 6.0 and fix all the known issues e.g. deprecated methods etc. when Apple releases GM for iOS6, will any build compile and work with iOS5 devices as well?
Should I just be submitting apps with a deployment target of 5.0 or will those fail to run in iOS6?
Should my deployment target only be iOS6 if I am using new iOS6 features?
(confused).
Since this is a pretty generic question about supporting multiple versions of iOS and does not cover any iOS6 specific things (covered by NDA), here goes my answer:
if I re-compile and build an app using the deployment target of 6.0 and fix all the known issues e.g. deprecated methods etc. when Apple releases GM for iOS6, will any build compile and work with iOS5 devices as well?
In principle, yes, it will, provided you have not used any iOS6-only feature or you did it properly (see the answer to your third question). However, testing against an actual device running iOS5/4 (or the simulator) is almost mandatory if you want to be sure that things work correctly.
There is also a chance that something that is currently working under an older iOS version will just break on iOS6 (this can happen in case some bugs were added, but also in case some bugs were fixed and it happens that your code had a bug of its own that countered the effect of the former). So, testing is the king. (Thanks to rsswtmr's comment about this).
Should I just be submitting apps with a deployment target of 5.0 or will those fail to run in iOS6?
You can specify a deployment target of 5.0 if your app does no use any iOS6-only feature (or you do it properly, read later); in other words, this setting will not break compatibility with iOS6;
Should my deployment target only be iOS6 if I am using new iOS6 features?
It can, but it is not the only way.
If you specify your deployment target as iOS6, then you can freely use any iOS6-only feature in your app without concern. The app store mechanics will prevent your app from being installed on any older device and you will be safe.
On the other hand, if you specify your deployment target as iOS5 or older, then you can still use any iOS6-only feature in your app, but you should properly support older versions of iOS by "guarding" any usage of iOS6-only features and providing a fallback for iOS5.
This means the following: say that you are going to use featureA only available on iOS6; what you can do is:
check to see if the feature is available at runtime (e.g. class respondsToSelector, etc);
guard your code within an #ifdef so that it will be compiled only on when possible;
if the check at 1. will fail, define a way out for older iOS versions.
Have a look at this post on supporting multiple iOS versions.
Set "Base SDK" to Latest iOS and "iOS Deployment Target" to the older version you plan to support (iOS 5.0 for instance).
Add conditional code to use feature available in latest iOS without crashing in the old one supported.
The section "Conditional Coding" in this Apple guide can be helpful. Also check other questions on the subject in SO.

Resources