個人アプリを Xcode9 Swift4 対応した時にやったこと

個人アプリ2つを Xcode9 GM で動くようにした。
これは私のアプリの場合なので、違うプロジェクトでは不要なことや、他にもっとやらないといけないことがあると思う。

やったこと

1. Xcode9 DL

Xcode - Apple Developer から DL してインストール。
Xcode8もまだ使うので、8と9を同居させるため Xcode9GM.app にリネームした。

2. xcode-select で 9GM を使うようにする

$ sudo xcode-select -s /Applications/Xcode9GM.app/Contents/Developer/
$ xcode-select -p
/Applications/Xcode9GM.app/Contents/Developer

3. bundle update

念のため bundle update して cocoapods や fastlane を最新にした。

4. ライブラリ更新

$ pod update
$ carthage update --platform iOS --no-use-binaries

ここで Xcode 9 でプロジェクトをビルドすると動くようになった。 と言ってもこの時点ではまだ Swift3.2 のはなし。

5. Swift 4

メニュー > Edit > Convert > To Current Swift Syntax… を選ぶ、そうすると Xcode が自動でマイグレーションしてくれる。
マイグレーションしてくれたのはほとんどが dynamic@objc をつけるものだった。

あとはこんなところを手動で直した。

- let attributes = [NSFontAttributeName: UIFont.fontAwesome(ofSize: 20)] as [String: Any]
+ let attributes = [NSAttributedStringKey.font: UIFont.fontAwesome(ofSize: 20)]

- dismiss(animated: true, completion: { [weak self] _ in
+ dismiss(animated: true, completion: { [weak self] in

これだけで Swift4 のビルドは通った。 しかし起動したらエラー。

6. UIVisualEffectView を修正

let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .extraLight))
- effectView.addSubview(UILabel())
+ effectView.contentView.addSubview(UILabel())

UIVisualEffectView は contentView に subview を追加しないといけなくなった。
これは実行時エラーなのでコンパイルは通ってしまう。

これを直したら起動した。

7. warning 対応

Swift3 @objc InterfaceOff にした。
また、 substring が使えなくなったり CGFloat(truncating: String) を使うように修正した。

7. Runtime Error

これは Swift4 対応とは特に関係ないと思われる。

アプリは問題なく動いているのだが、 UIApplication あたりでなんか出てた。

runtime: UI API called from background thread: -[UIApplication delegate] must be used from main thread only
runtime: UI API called from background thread: -[UIApplication applicationState] must be used from main thread only
runtime: UI API called from background thread: -[UIApplication keyWindow] must be used from main thread only
runtime: UI API called from background thread: -[UIApplication supportedInterfaceOrientationsForWindow:] must be used from main thread only

画像で見るとこんな感じ。

f:id:star__hoshi:20170917232741p:plain

ググったら Firebase が古い時のエラーのようで、 Firebase を新しくすれば消える。

  pod 'Firebase' , '~> 4.0'
  pod 'Firebase/AdMob' , '~> 4.0'
  pod 'Firebase/RemoteConfig' , '~> 4.0'

これで pod update すれば OK。

8. 新しい Google Analytics, Firebase 修正。

Firebase を新しくしたら依存する Google Analytics の書き方も変わったみたいなので、 Bridging-Header.h を直した。

+ #import <Google/Analytics.h>
- #import <GoogleAnalytics/GAI.h>
- #import <GoogleAnalytics/GAIFields.h>
- #import <GoogleAnalytics/GAILogger.h>
- #import <GoogleAnalytics/GAITracker.h>
- #import <GoogleAnalytics/GAIDictionaryBuilder.h>

あと Firebaes の FIR のプレフィックスを消す必要があった。

9. おわり

これで Simulator で Run したらエラーも消えてめでたし ㊗️