Migrating to iOS8 - the challenges we encountered, and how we dealt with them
When you google “iOS8” the first sentence you'll see is “iOS 8 is the biggest iOS release ever.” And it sure is. When we first tried to compile our code for iOS8 in Xcode 6 we thought it would instantly work and we’d see our beautiful app running on an iOS8 device with no trouble at all. And then we hit “run”.
Oh, how naive we were. The app crashed often, and when it did run everything looked bad. The scaling was wrong and things just weren’t working.
Most of our efforts went into these tasks:
New NSObject properties
Update all SDK in the project to iOS 8 (and 64bit) support
Urban Airship SDK iOS 8 support
Configuring the project and code to 64bit
How to migrate Xcode project to support “real scale” for the new iPhone 6\6+
Auto Layout transform issues
New NSObject properties
Guess what? In iOS8 the NSObject class now contains 4 other properties. Properties, not methods, and here they are:
hash superclass description debugDescription
We had a “description” property in one of our classes that caused the crashes.
Update all SDK in the project to iOS 8 (and 64bit) support
Most SDKs and 3rd party libraries have an iOS8 compatible version. If one of the SDKs you are using have not been updated in a while, it might be a good opportunity to replace your outdated SDKs with one that is compatible.
Urban Airship SDK iOS 8 support
Updating the SDKs will probably require some work, one SDK in particular we had to adjust the integration with is the Urban Airship SDK.
Urban Airship is a service we use to manage our push notification process. Since some of the API regarding push notifications has changed, it was of course inevitable to make some adjustments to the integration with them.
Some functions were removed like this method:
registerDeviceToken:(NSString *)token;
that as has been replaced with this one:
appRegisteredForRemoteNotificationsWithDeviceToken:(NSString *)token;
Also, the call to this method
[[UAPush share] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge| UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert)];
has been replaced with
[UAPush shared].userNotificationTypes = (UIRemoteNotificationTypeAlert| UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound); [UAPush shared].userPushNotificationsEnabled = YES; [[UAPush shared] updateRegistration];
Another change was to the
[UAPush shared].userNotificationTypes = (UIRemoteNotificationTypeAlert) UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound);
function to register the device’s token. But in iOS8 devices, this function was not called. So we added this function:
(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings;
which had to be called first in iOS8 devices.
Configuring the project and code to 64bit
Another struggle we had to deal with was including 64bit support in our app. As stated in the Apple developer page: https://developer.apple.com/news/?id=10202014a, starting from Feb 1, 2015 new submissions to the App Store must include 64bit support.
The first thing you have to do is change the architecture to “standard architectures (armv7, arm64)”. Note that Apple no longer requires support for armv7s since they claim it differs from armv7 in so little that it’s not really necessary.
Next, in our app we sometimes used int and sometimes NSInteger, and often casted between them. Since in 32-bit NSInteger is 32-bit and in 64-bit, NSInteger is 64-bit, we just went ahead and replaced “int” with “NSInteger”, keeping in mind that it can’t be casted to int.
How to migrate Xcode project to support “real scale” for the new iPhone 6\6+
At this point we noticed that the app was still auto scaled in iPhone6/6+. To make sure, we checked what was the screen width in iPhone 6 and saw it really was 320 instead of the expected 375. This made the views and fonts look too big and bulky.
Apparently the solution for this problem is to add launch images for iPhone 6 and iPhone 6+. When the new launch images were added to our Xcode project, Xcode automatically stopped doing “automatic scaling” and allowed us to adjust the elements on the screen as we like.
Before this addition, Xcode auto scales your app for the new devices, which caused the problem and made all objects bigger than you might want them to be. After this fix, our app was able to fully use the extra screen real estate the new iPhones have to offer.
Here is an example of how it looked with auto scale, and how it looked after the launch images addition: iPhone 6+ with auto scale iPhone 6+ with real scale
side note:
For us, the auto scale also caused the iPhone 6+ feed to have this weird, unsmooth scroll. Be sure to go over all of your app at this point, if you had constraints that assumed all devices have a fixed width of 320, this will need to be changed because it’s no longer the case.
Auto Layout transform issues
One more big change we had to do has to do with the Auto Layout transform issue. In iOS7 and iOS8, changing the transform of a view behaves differently. pop up view before the fix: iphone 5s iOS7 iPhone 5s iOS8
We found that in iOS7 a transform change causes an immediate call to layoutSubviews, and in iOS8 it does not. So a simple solution could be adding [view layoutIfNeeded] right after the transform change, but we decided to go with a safer solution.
Before the fix, the code that adds the popup was something like this (this is of course partial and simplified):
[view addSubview:popUpView]; popUpView.center = view.center; view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.1, 0.1); [UIView animateWithDuration:0.4/1.5 animations:^{ view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1); }];
So what we eventually did was instead of adding the view and setting its center, we added the view and added centerX, centerY, width and height constraints between the 2 views:
popUpView.translatesAutoresizingMaskIntoConstraints = NO; NSLayoutConstraint *centerXconstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:0 toItem:view.superview attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];NSLayoutConstraint *centerYconstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:view.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]; NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:0 toItem:nil attribute:0 multiplier:1 constant:view.width]; NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:0 toItem:nil attribute:0 multiplier:1 constant:view.height]; NSArray *constraints = [NSArray arrayWithObjects:centerXconstraint, centerYconstraint, widthConstraint, heightConstraint, nil]; [view.superview addConstraints:constraints];
And now it looks good in both iOS7 and iOS8!
pop up view after the fix: iphone 5s iOS7 iPhone 5s iOS8
* Written by Meshi Haiman













