MonoTouch: Approaching Obsolete iOS methods - ios

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.

Related

App migration between different iOS versions

Currently, I'm in the middle of adapting my app for iOS 7.1 to support iOS 8.
During this process, it dawned more and more on me that I may have seen the relationship between SDKs and OS versions wrong all the time.
I'll tell you with a concrete example:
The UIViewControllerContextTransitioning protocol gained some more methods for iOS8. So in order to support the new OS, I started implementing the new methods in my ContainerViewController.
When I came across the - (UIView *)viewForKey:(NSString *)key method, I naturally checked the key against the UITransitionContextFromViewKey constant.
This constant has the NS_AVAILABLE_IOS(8_0) suffix. So I assumed the constant is only available when running on iOS8 and above.
When I set the deployment target in Xcode from 8.0 to 7.1 and hit 'Build & Run', to my surprise there was no error at all and the app ran on my iOS7.1 device without any problem. - Even while the code contained the constant that should only be available at >= iOS8.
So here are the questions that came to my mind at this point:
The NS_AVAILABLE_IOS(8_0) suffix in the header files does not determine the iOS version, but rather the SDK version from which on the marked API is available. - is that correct?
Does this mean we are able to use APIs added in the iOS8 SDK in apps that are compiled for iOS7.1, as long as we use the new SDK to build the app?
I'm particularly curious about the second question, because that would mean we can use cool new stuff like the UIVisualEffectView for apps that run on iOS < 8. Also, this would mean much less headache for example when maintaining CoreLocation functionality while following all the changes made to it (kCLAuthorizationStatusAuthorized -> kCLAuthorizationStatusAuthorizedWhenInUse, etc.), because we can simply maintain a single code base and do not have to #ifdef a lot.
Please tell me if my assumptions are correct and if not, please correct them in your answer.
Thank you!
It's important to realize that linking against the iOS 8 SDK with a deployment target of iOS 7 allows you to create an application that will run on both, but there will be differences in API availability.
When the application is run on iOS 7, iOS 8 APIs will be unavailable. At runtime, acccessing an iOS 8 API can cause a crash or other undesirable behavior. The recommended way to handle this is when using classes, methods, or constants that are marked as available only on iOS 8 or later, you must query for their availability at runtime.
In the case of new UIViewControllerContextTransitioning methods, you would query for the presence of those iOS 8 methods at runtime:
if ([transitioner respondsToSelector:#selector(viewForKey:)]){
// It's available, you're set to call it
} else {
// The method is not available, you will have to work around it.
}
Obviously, this can complicate things significantly for some applications. The application DeployMate can be very useful for finding API disparities in your code base. It will scan your project and tell you where you are using a method that is iOS 8 only.
Guidance for supporting different SDK and OS versions and capabilities is explained in more detail in the iOS 7 Tech Talk Architecting Modern Apps, Part 2. While the examples are for supporting iOS 6 and 7, the guidance here applies to supporting more than one OS or SDK, no matter what the version.

How does an app with lower base sdk work?

In XCode I can specify Base SDK. I am wondering how does that work behind the scenes? If I am running an app, for example, on a device that has iOS 7 and my base SDK is iOS 6, then how come the app has the old 'look and feel'? Does XCode compile the older SDK and include it within my app or does new version of iOS comes with older libraries/SDKs?
In other words, does the run time know this app is compiled with lower base SDK and somewhere in UIKit's code it does:
if (lower SDK) {
//show old look/feel
} else {
//show new look/feel
}
or does the app itself include the old library and load it ?
Thanks
iOS applications are forward compatible with new versions of iOS. The reason is :
Almost all changes to the iOS versions are additive and hence an
application build using lower version still runs on the higher iOS
version.
Though, we need to take care of this point:
As frameworks evolve through various releases, APIs are introduced or
deprecated and behaviors of existing APIs may occasionally change.
Apple makes every effort to minimize changes that may cause
incompatibilities, in some cases providing alternate behaviors based
on the framework version. In rare cases, your code needs to determine
the framework version and adjust accordingly
To understand more, read this
Apple never changes / deletes / renames classes or methods. They only add new ones.
If they don't want you to use it anymore, they mark it as deprecated.
This is a very important point.
At compile-time, the compiler checks if all classes and method signatures are available in the SDK your building your app with.
If that's the case, you can build and deploy your app. Because those classes and methods will never be deleted from newer versions of the framework, your app will run just fine.
On the other hand, you can build apps and deploy them to systems, which do not actually support the current SDK. For example, you can use Autolayout (NSLayoutConstraint class is available since 10.7) and deploy it for Mac OS X 10.6. The compiler will not say a word.
The app will crash though on systems prior to 10.7.
You should set your target to ios 5.0 (via your project target settings) for making sure that none of the ios6 methods are used (or else a compilation error will prevent you from building it).
In order to support new features and check if ios6 is available on the device you have two ways :
During compilation (so you can still build your app with lower targets and newer together) use the following macro
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0
// Your ios6 code goes here
#endif
2: During runtime : [[[UIDevice currentDevice] systemVersion] floatValue] > 6.0
Your project is built against the Current SDK. If you have an older Deployment Target, then your code base is compiled against that. So if you are building against 7.0, but have a 6.0 deployment target, iOS 7 specific deprecations will not be triggered. Everything will be compiled against the oldest specified deployment target.
This will however put the pressure on you as a developer to make sure you are not using iOS 7 specific code. The compiler will still assume you mean to allow newer users to run your application as well and that all the newest methods are available to you and your latest version users. You can either test your code base against the older SDK with older devices or Simulators to make sure it runs well, or use an application like Deploymate that will test for methods you are using that could potentially cause problems.
If you plan to use any of the latest methods, you will need to wrap them up in the compiler if statement (like Peter Fidemraizer answered) or in normal if statements checking the version in the Foundation framework.
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
// Load resources for iOS 6.1 or earlier
} else {
// Load resources for iOS 7 or later
}
Base SDK means, the SDK that your app is going to be built on. SDK's have some frameworks etc. that are differantiated as the version of the SDK changes. For example;
Let's say your current Base SDK in your XCode is iOS 6:
You can have the frameworks and feautres that iOS 6 SDK provided you to.
Your app will be usable in any iOS SDK that you specify as "Minimum iOS SDK". Minimum iOS device gives you some restrictions on components to use. be aware of that.
Your app will be usable in iOS 7 too, just like it works in iOS 5 or iOS 6. Because iOS versions have backward compatibility. That means, iOS 7 will run the apps that are running in iOS 6 too.
Let's say your current Base SDK is iOS 6 and you want to make it iOS 7
Your app will be built with a brand new SDK, so, if the new SDK has
some big changes in it, you will see the differences immediately when
you run the app. For example, in iOS 7 SDK, you can use status bar
(20 px) as a view component too. That may ruin your view hierarchy.
You need to test your app again to check that your code is compatible with iOS 7
If you want to use new iOS 7 frameworks or features, you are in the correct way, you can use them now :)
In short, Base iOS SDK is on what iOS version your app is compiled & built on. running it on a iOS X? device is a different concept.
Hope this helps
Base SDK is the SDK that you want to use to build the app. Use "Deployment target" to specify the minimum OS you want your app to run on.
If you want to know the iOS version, check out this question.
While updating the Apple frameworks itself,Apple takes care of support for multiple iOS versions;However you need to follow some basics checks, which are explained here

Sanity-check for iOS API versions used within an application

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

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.

Using storyboards in xcode and the app store

I am in a process of learning ios development. I am beginning to learn storyboards and i found out that its only IOS 5 compatible. I searched here and found some answers but i wanted to find out if it make sense at this point to use storyboards. How does application behave that requires 5.0 in the app store? Does it show up for people that have 4.3 and lower? When i look through new application i don't see any that says 5.0 required in the description. Does that mean most people do not use storyboards to develop apps yet?
Thanks in advance!
story board is available in SDK 4.2 with which you can build for iOS 5, you can certainly set your deployment target to 4.x and it will work like a charm..!!
Updated : as #FirozeLafeer told, I confirmed my knowledge that he is right - XCode displays a message that "storyboards are unavailable on iOS 4.3 or prior"
From Apple: Storyboards are supported in iOS 5 and later and are enabled by default for new projects. If your app must run on earlier versions of iOS, though, you cannot use storyboards and should continue to use nib files.
Source: https://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/AppDesignBasics/AppDesignBasics.html

Resources