There are elements like UITableView
s, UINavigationBar
s that have a different style on iOS 7.
This style is determined at run time, since those classes are implemented on UIKit
, and UIKit
is linked with your application dynamically at runtime, not statically at compile time.
So one would think that any app run on iOS 7 would have those elements look the way they look on iOS 7. However, they keep the same style they used to have on iOS 6, until you compile with the iOS 7 SDK. Except for some of them (like UIAlertView
or UIMenuController
)
My only explanation for this is that they do something kind of like this:
#define SDKApplicationWasLinkedAgainst ...
if (SDKApplicationWasLinkedAgainst < 7.0)
...
else
...
This is obviously really cumbersome, cause they need to keep maintaining a lot of old code. So I'm curious, is this really what is going on under the hood? What am I missing?
The framework provides the window and view architecture for implementing your UI, the event-handling infrastructure for delivering Multi-Touch and other types of input to your app, and the main run loop for managing interactions between the user, the system, and your app.
The UIKit framework provides the core objects that you need to build apps for iOS and tvOS. You use these objects to display your content onscreen, to interact with that content, and to manage interactions with the system.
UIKit is a high-level Objective-C framework that manages the graphical front-end of the iPhoneOS. It is a public framework, and therefore its documentation can be found on Apple's iPhone Dev Center.
Without going too much into NDA'd territory, I'd just like to state that yes, they are conditionalizing appearance and behavior based off of the result from the following call:
_UIApplicationUsesLegacyUI()
This function, in turn, makes a call to GSApplicationUsesLegacyUI()
, which I presume returns a result based off of the version of the linked UIKit.
This means that yes, they are conditionalizing parts of UIKit for legacy. Not sure that's a good thing, but that's what they decided to do.
My bet is that they use framework compatibility versions.
Each time you compile your app, your app is linked against an specific framework, with compatibility version and current version. You can see those numbers if you run otool -L YourApp.app/YourApp
. For example, for an application compiled some time ago I obtained this:
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 751.58.0)
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 1500.0.0)
As you can see the full path of the UIKit framework is stored in the Mach-O binary, along a couple of versions (and specially the version I compiled against at that moment).
I suppose that iOS 7 will have both UIKit version included: the one from iOS6 marked with the corresponding version and saying compatibility from 1.0.0, and the one from iOS7 marked as compatible with something higher than 1500.0.0 (I don’t know if that’s the number for iOS 6.1.3, but you get the idea).
When your iOS6 binary is loaded, its library dependencies are read by dyld
and resolved, because you were compiled saying current version 1500.0.0
, and the library for iOS 7 says compatibility version 1501.0.0
, you will be linked against the library for iOS 6.
Since a framework is also a bundle, all the resources are perfectly contained, and will be used only by the right version, and that’s how the different visual elements will look different if you compile against iOS 6 SDK or iOS 7 SDK.
I might be wrong, but I simply hope they are not using the code technique you propose, because that will be a crappy code base to maintain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With