Writing iOS7 code that compiles under the iOS 6 Base SDK

We now have an iOS application, and we are developing a version of iOS 7 on Xcode 5 DP using the same code base.

We really need to release an update right now for existing iOS 5/6 clients, but, of course, when we reload the project in Xcode 4, it complains about non-existent properties since the base SDK becomes iOS6, not 7:

// Only run this bit on iOS 7 if ([self respondsToSelector:@selector(setFooForExtendedLayout:)]) { self.fooForExtendedLayout = UIFooEdgeLeft | UIFooEdgeRight; } float bottomOffset = 0; // Only run this bit on iOS 7, else leave bottomOffset as 0 if ([self.hostController respondsToSelector:@selector(bottomLayoutFoo)]) bottomOffset = self.hostController.bottomLayoutFoo.length; 

(obfuscation to avoid NDA violation)

Xcode Errors:

Property 'fooForExtendedLayout' not found on object of type 'UIViewController *'

Using undeclared identifier 'UIFooEdgeLeft'

Using undeclared identifier 'UIFooEdgeRight'

Property 'bottomLayoutFoo' not found on object of type 'UIViewController *'

It would be painful to comment on this new code. What is the right way to overwrite it for compatibility with both old and new base SDKs, and is it sending it now (via Xcode 4 and the built-in iOS 6 SDK) the risk of any rejection of the App Store?

+7
xcode sdk ios6
source share
5 answers

I would suggest waiting until iOS 7 can send your update.
However, these are solutions to the problem.

Property 'fooForExtendedLayout' not found on object of type 'UIViewController *'

Since properties are just syntactic sugar, an easy way to fix such an error is to use a selector to call the method (setter):

 [ self performSelector: NSSelectorFromString( "setFooForExtendedLayout:" ) withObject: ( id )xxx ]; 

@selector() cannot be used because you are requesting an iOS 7 selector with the iOS 6 SDK.
Hence the use of NSSelectorFromString .
The withObject argument is created for objects, as the name suggests. But since objects are pointers, and since your method takes an enumeration value, you can pass it without problems using a listing.

Using undeclared identifier 'UIFooEdgeLeft'
Using undeclared identifier 'UIFooEdgeRight'

Now about your enumeration values ​​there is no such trick.
The only way is to declare them with the same values ​​as in the iOS 7 SDK, and pray that it does not change before the official release .

So now it is up to you ... Personally, I would wait.

+6
source share

Here is the recommended way to have code that compiles on both iOS 6 and 7 SDKs:

 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) self.edgesForExtendedLayout = UIRectEdgeLeft | UIRectEdgeRight; #endif 
+7
source share

You can use:

 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { self.edgesForExtendedLayout = UIRectEdgeNone; } #endif 
+5
source share
 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) { self.edgesForExtendedLayout = UIRectEdgeNone; } #endif 
+1
source share

Edit: this answer (as well as questions) is no longer relevant since Xcode 5 is now released! Please think about it when voting down;)

The rationale for using the SCM tool to get two different branches of code is due to minor issues that may arise when switching Xcode Developer preview versions and Xcode Release versions with an identical Xcode project and the same code and resource base. The project file, storyboard or xib may be modified under the hood and may be damaged. This is not because there was no way to find a solution in the code! However, I would not recommend working with different versions of Xcode in an identical Xcode project. It can cause a headache!


The right way is to use a source control tool like git. You must have an β€œiOS 6” branch where you support release versions, and you must have one or more development branches in which you use the preview versions of Xcode and iOS.

-2
source share

All Articles