Xcode

Xcode 8のプロジェクトをXcode 9に移行するときのメモ

More than 1 year has passed since last update.

今更ですがXcode 9に移行するときの作業メモ。

Xcode 9はこれまでのバージョンアップと比較して、比較的素直にコンパイルまで終わらせられそうです。
ただ、どういう理由で変更が必要かわからんのでざっくりと調べてみました。

@objcディレクティブの追加

Swift 4では、これまで暗黙的に付与されていた @objc ディレクティブを明示的に書くように変更されました。

// Swift 3
func closeDial() {
  // do something
}

// Swift 4
@objc
func closeDial() {
  // do something
}

この変更は、Xcode9でプロジェクト設定を自動更新する際に(ある程度)自動変換させることができます。
変換時に、"Minimize Interface"と"Match Swift 3 Behavior"のどちらかを選択できます。前者の"Minimize Interface"を選択した場合、自分で必要な箇所に @objc を追加する必要があります。後者の"Match Swift 3 Behavior"を選択すると、Swift 3で暗黙的に付与されていた時と同様に @objc を付与します。

後者を選択するとバイナリサイズが大きくなるので、基本的には前者を選択するのが良いでしょう。

タプル型引数の呼び出し方が変わった

Swift 4ではSE-0110の変更に伴い、引数と戻り値の型の宣言をする際に (Void) -> Void と書く場合は () -> Void と宣言するよう変わりました。

この影響で、以下のように変更を加える必要が出ています。

// Swift 3
DispatchQueue.main.async { [weak self] _ in
  // Void型の引数なので、"_"をつけていてもコンパイルエラーにはならない
  // do something
}  

// Swift 4
DispatchQueue.main.async { [weak self] in
  // Void型の引数なので、"_"は必要ない
  // do something
}

NSAttributedStringKey への変換 (Xcode9が自動変換)

NSAttributedStringの仕様が変わりました。
これまでは NSFontAttributeNameNSParagraphStyleAttributeName のように定数が設定されていましたが、NSAttributedStringKey.fontNSAttributedStringKey.paragraphStyle のように、enumに変更されています。

この箇所はXcode 9が自動変換してくれる項目ですが、NSAttributedStringKey.font.rawValueのように変換してしまうので正直恰好悪い。
NSAttributeStringKeyの型を使って書くほうがシンプルに書けます。

//Swift 3
let textAttributes: [String : AnyObject] = [
    NSFontAttributeName: someAtttributeName,
    NSParagraphStyleAttributeName: paragraphStyle
]

//Swift 4 自動変換だとこうなる
let textAttributes: [String : AnyObject] = [
    NSAttributedStringKey.font.rawValue: someAtttributeName,
    NSAttributedStringKey.paragraphStyle.rawValue: paragraphStyle
]

//Swift 4 こう書くほうがベター
let textAttributes: [NSAttributedStringKey : AnyObject] = [
    .font: someAttributeName,
    .paragraphStyle: paragraphStyle
]