Upgrading an iOS project from Xcode 6 to 7

At work I’m in the midst of upgrading Find&Save to Xcode 7 and in this post I thought I would capture the issues I ran into while migrating our app to the latest build tools. I decided to keep my Xcode 6 install by renaming it “Xcode 6” and installing Xcode 7 along side it and all that worked pretty seamlessly (though keep reading because the AppStore updates will bite you). Once installed I opened our project workspace and hit Project | Build and thus began the journey of our migration.

Updating Build Settings on .xcodeproj

Upon building our project I got the following warning:
Update to recommended settings
Which lead to this dialog for updating various build settings:
Screen Shot 2015-10-01 at 12.45.49 PM
At least this step seems pretty straight-forward onward…

Xcode 7 Enable BitCode Setting

Right of the bat I ran into this linker Error caused by our use of the Localytics SDK:

clang: error: linker command failed with exit code 1 (use -v to see invocation)

Error Details:
ld: '/Users/strefethen/iPhoneGeo/Pods/Localytics/Localytics-iOS-3.5.0/libLocalytics.a(LLInAppViewControllerFactory.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

After a fair amount of research on Bitcode (pretty interesting tech btw) I toggled Enable Bitcode on the project Target to “No”. I need to do some more research based on a note on Apple’s App Thinning page with regard to our use of watchOS and determine where this leaves us.

Xcode Build Setting for Enable Bitcode
Xcode Target Build Settings

HTTPS and NSAppTransportSecurity

At this point our project compiled successfully which at first struck me as far too easy. When I launched the app no content loaded and nothing that touched the net was working. I noticed these error messages in the console:
2015-09-29 22:49:40.281 iPhoneGeo[6153:1394717] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
Essentially, Xcode wasn’t allowing our app to talk to anything on HTTP and instead preferring HTTPS. I found a good post discussing how to disable this requirement using NSAppTransportSecurity in the info.plist and allow all traffic because a) our staging setup does not use HTTPS and b) I wanted to understand what else didn’t work throughout our app so I opted to use the NSAllowsArbitraryLoads key set to YES. At first my desire was to do this just for debug builds and make it configurable though unfortunately I couldn’t find a way to use an environment variable for a BOOL prop in the info.plist.
Info.plist NSAppTransportSecurity
I tried adding a User-Defined setting for ALLOWS_ARBITRARY_LOADS and assigning it a string value of “Yes” for Debug and “No” for Release builds since I’ve seen other places where this had worked. Something like this:
User-Define build setting
My plan was to use it like so:

NSAllowsArbitraryLoads -> ${ALLOWS_ARBITRARY_LOADS}

However, this setting doesn’t seem to like anything but a BOOL which seemingly rules out using a User-Define to address this Debug/Release difference. Anyway, I continue on…

WatchKit

The Find&Save app supports Apple Watch and has a Cash Dash Inbox view for offers listed on the watch. At this point, more out of habit than anything I did a full clean and rebuild at which point I got the following error:
(null): error: WatchKit Extension doesn't contain any WatchKit apps. Verify that the value of WKWatchKitApp in your WatchKit App's Info.plist is set to YES.
After a little Googling I did a Project | Build and the problem magically took care of itself (though this is not an unusual occurrence for Xcode for me these days).

Images.xcassets Issues

There were two warnings related to Images.xcassets:
/Users/strefethen/github/iPhoneGeo/iPhoneGeo/Images.xcassets: The image set "list" references a file "list.PNG", but that file does not have a valid extension.
And…
(null):  A launch storyboard or xib must be provided unless the app requires full screen
And of course now Xcode 7.1 will be breathing down our necks.
UPDATE 9/30: I just clicked the Update button on the Xcode v7.0.1 release in the AppStore app and following the install found it DELETED my Xcode 6.4 installation. Thank you Apple. 
UPDATE #2 9/30: I just found that pod update now gives this error:
Update all pods
Analyzing dependencies
xcrun: error: active developer path ("/Applications/Xcode 6.app/Contents/Developer") does not exist, use `xcode-select --switch path/to/Xcode.app` to specify the Xcode that you wish to use for command line developer tools (or see `man xcode-select`)

So I ran an xcode-select as follows:
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer/
…and now I’m getting this error:
Generating Pods project
2015-09-30 13:55:38.204 ruby[18384:2457584] [MT] DVTAssertions: ASSERTION FAILURE in /Library/Caches/com.apple.xbs/Sources/IDEFrameworks/IDEFrameworks-8228/IDEFoundation/Initialization/IDEInitialization.m:590
Details: Assertion failed: _initializationCompletedSuccessfully
Function: BOOL IDEIsInitializedForUserInteraction()
Thread: {number = 1, name = main}
Hints: None
Backtrace:
0 0x0000000104f33a4c -[DVTAssertionHandler handleFailureInFunction:fileName:lineNumber:assertionSignature:messageFormat:arguments:] (in DVTFoundation)
1 0x0000000104f331d9 _DVTAssertionHandler (in DVTFoundation)
2 0x0000000104f33445 _DVTAssertionFailureHandler (in DVTFoundation)
3 0x0000000104f333a7 _DVTAssertionFailureHandler (in DVTFoundation)
4 0x0000000106c42f5c IDEIsInitializedForUserInteraction (in IDEFoundation)
5 0x0000000109848e49 +[PBXProject projectWithFile:errorHandler:readOnly:] (in DevToolsCore)
6 0x000000010984a9ce +[PBXProject projectWithFile:errorHandler:] (in DevToolsCore)
7 0x00007fff90ed2f44 ffi_call_unix64 (in libffi.dylib)
Abort trap: 6

Which I fixed following the advice on the above link which involved:
stevet-2:iPhoneGeo strefethen$ sudo gem uninstall cocoapods
Password:
Select gem to uninstall:
1. cocoapods-0.29.0
2. cocoapods-0.33.1
3. cocoapods-0.34.4
4. cocoapods-0.36.3
5. All versions
> 5
Successfully uninstalled cocoapods-0.29.0
Successfully uninstalled cocoapods-0.33.1
Successfully uninstalled cocoapods-0.34.4
Remove executables:
pod, sandbox-pod
in addition to the gem? [Yn] n
stevet-2:iPhoneGeo strefethen$ sudo gem install cocoapods

UPDATE 10/1: The next issue I’m seeing is this error appearing in deviceconsole which is something I haven’t yet resolved.
<Error>:  SecOSStatusWith error:[-34018] Error Domain=NSOSStatusErrorDomain Code=-34018 "client has neither application-identifier nor keychain-access-groups entitlements" UserInfo={NSDescription=client has neither application-identifier nor keychain-access-groups entitlements}
UPDATE #2 10/1: I’ve recently upgraded to an iPhone 6s Plus which is running iOS 9.0.2 and following a reinstall of Xcode 6.4 as I was wanting to get back to work on our app but it seems I’ve now gone a step too far:

The Developer Disk image could not be mounted. Steve's iPhone 6s may be running a version of iOS that is not supported by this version of Xcode.
Xcode 6.4 error trying to run on an iPhone 6s Plus with iOS 9.0.2.

UPDATE #3 10/5: Our Jenkins build started failing with the following error from CocoaPods:

Sending stats
      Failed to send stats:  SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: sslv3 alert handshake failure

Found a Stack Overflow post with the same issue however on our build server I’m hesitant to jump to any beta release so I opted to use the CocoaPods environment variable COCOAPODS_DISABLE_STATS. Once it looks like things clear up I can removed this from Jenkins.
export COCOAPODS_DISABLE_STATS=1

4 thoughts on “Upgrading an iOS project from Xcode 6 to 7

  1. Hey,
    Since this is the only place on the whole internet that knew something about the issue I was having migrating to Xcode 7, I thought I’d share a line as well.
    The “DVTAssertions” issue with “pod install” seems to have originated in me having a stale version of cocoapods. The “gem uninstall” command didn’t properly do it for me. I had to first isntall the latest cocoapods
    “$ gem install cocoapods”
    then remove the old versions
    “$ gem clean”
    and check the results
    “$ gem list”
    Only one cocoapods version should be listed (0.38.2 in my case).
    Thanks for sharing btw, you showed me where to dig.

    1. Glad I could help. I ended up repeating these steps multiple times working through issues and eventually upgrading our Jenkins machine. I didn’t have to go through the Cocoapods “dance” you did so thanks for adding that note for anyone else who finds this.

Comments are closed.