EDIT:
The answer below from H2CO3 makes me almost happy. But it does not
explain one thing: why do I get a runtime exception when building the
app against SDK6 (UIPageViewController requires one child controller
before adding it to a parent controller) but not when building against
SDK5?
The answer from Rolf explains what is going on: the device knows the SDK an app was built
with and behaves differently to ensure maximum compatibility.
While fighting with iOS SDK versions, MonoTouch versions and different iOS Versions, I started wondering: What IS an iOS SDK after all?
I mean, I install Xcode 4.4 and I get iOS SDK 5. If I install Xcode 4.5, I get iOS SDK 6. So far no problem.
- Now assume I build an app that
targets iOS 5
and does not use any iOS 6 specific
things. I but build this app using iOS SDK 6
.
- Then I build the
same app
but use iOS SDK 5
.
Then I run both versions of the app on an iOS 6 device.
Why do they behave differently? There are small differences, for instance UIPageViewController throws an exception if no child controller is set before adding the page view controller as a child to a parent controller.
To my understanding, the callbacks, the features and everything is coming from the iOS Operating System and not from the SDK. But the OS is the same in both cases.
I totally understand that if I want to user an iOS 6 specific feature, I need to use iOS SDK 6 because a UICollectionView just doesn't exist in SDK 5. But the UI code for this view is obviously not getting included in my app, otherwise it would work on iOS5 too. So the collection view is coming from a shared library provided by the OS.
On top of that there is then MonoTouch. If we assume that each MonoTouch version is nothing but an extension of the bindings without fixing any bugs, it should not matter what MT version I use.
A short recap of my question would be: how do iOS version, iOS SDK version, MonoTouch version and application's target version play together?
In theory, you should be able to switch from the iOS 5 to iOS 6 SDK and not see any differences. In practice it's a little bit different.
- The device knows the SDK you used. This means that the device itself can decide to behave differently (for whatever reason Apple determines that's a good idea).
- You're using a different toolchain (gcc and related binaries), and they may compile things differently (this is rare though and I haven't seen it actually happen).
- MonoTouch itself may behave differently (nothing comes to mind right now, but for instance we may use different default values for things such as the Deployment Target (if you haven't set that yourself of course)).
I believe you're running into the first case - Apple has added a few restrictions to their UI hierarchy in iOS6 which they only enforce if you built against the iOS 6 SDK (to not break existing apps I presume).
The iOS SDK consists of two components: the toolchain (Clang and/or GCC as a compiler, ld(64) as the linker and other parts of the cctools
package (GNU people call it binutils
) and the libraries and header files.
The toolchain (compiler) version is not strictly related to the version number of iOS. In theory, any sufficient cross-compiler can build code for any iOS (although in practice, there are exceptions and restrictions, arising out of the mistakes Apple had made when designing their compiler, including hardcoded library function names, classes and method selectors, etc.).
The header files and libraries (including the Apple-specific "framework" types of libraries) are essentially a copy of the /usr/include
, /usr/lib
and /System/Library/Frameworks
directories on iOS. (Even this is not entirely true - on iOS, the header files are not present from iOS 3 and the libraries from iOS 3.1, because the dyld shared cache was introduced). They basically tell the compiler and the linker what functions, classes and methods are available for a specific version of iOS. Header files are for compilation-time verification and libraries are for linkage-time verification. Basically, on a normal, non-embedded system (i. e. on the desktop), where one doesn't have to cross-compile code, the "SDK" would basically mean the same files in the operating system itself, and it wouldn't be called an "SDK"; it would rather be referred to as "the sysroot".