Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing iOS7 code that compiles against iOS 6 Base SDK

Tags:

xcode

sdk

ios6

We have an iOS app on-sale now, and we're developing the iOS 7 version on XCode 5 DP using the same code base.

We really need to release an update right now for existing iOS 5/6 customers but, of course, when we re-load the project into XCode 4, it complains about non-existing properties since the Base SDK then 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;

(obfuscated to avoid breaking NDA)

XCode Errors:

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

Use of undeclared identifier 'UIFooEdgeLeft'

Use of undeclared identifier 'UIFooEdgeRight'

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

It would be a pain to comment out this new code. What is the correct way to re-write it to be compatible with both the old and new Base SDKs, and does submitting it now (via XCode 4 and built against iOS 6 SDK) risk any sort of App Store rejection?

like image 792
Carlos P Avatar asked Aug 18 '13 21:08

Carlos P


1 Answers

I would advise to wait until iOS 7 is ready to submit your update.
However, they are ways to fix the issue.

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

As properties are just a syntactic sugar, the easy way to fix this kind of error is to use a selector to call the method (setter):

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

@selector() can't be used since you're asking for an iOS 7 selector with an iOS 6 SDK.
Hence the use of NSSelectorFromString.
The withObject argument is made for objects, as it names implies. But as objects are pointers, and as your method takes an enum value, you can actually pass it without problem, using a cast.

Use of undeclared identifier 'UIFooEdgeLeft'
Use of undeclared identifier 'UIFooEdgeRight'

Now about your enum values, there's no such trick.
The only way is to declare them, with the same values as in the iOS 7 SDK, and pray that it won't change until the official release.

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

like image 52
Macmade Avatar answered Sep 18 '22 15:09

Macmade