LoginSignup
17
16

More than 5 years have passed since last update.

Swift1.2からSwift2.0へ自動変換できなかったエラーの対応(Xcode7 + Swift2)

Posted at

qitta_20151101-2.jpg

Xcode7.1にアップデートしたら、上のダイアログが表示されました。
どうやら、Swift1.2を使い続けるという選択肢はないようなので、しぶしぶ対応することに……。

環境

項目
OS Yosemite(10.10) El Capitan(10.11)
Xcode 6.4 7.1
Target iOS 8.2 9.1
Swift 1.2 2.0

プラクテイス

地道に、Xcodeのbetaを追いかけていた方は、Swift2.0の文法に少しずつ書き直していって、緩やかに移行したと思います。
が、私みたいにとりあえず、xcodeの正式版が出てから対応しようと考えた人は、xcode自体のアップデート、iOSのアップデート、Swiftのアップデートと3つ重なり、数十のエラーと警告が表示されているのではないでしょうか。

  • とりあえず、自動変換を行ってみる
    • Swift1.2のプロジェクトを開くと、前述の"Convert to Latest Swift Syntax?"ダイアログが表示ます
    • 手順に従って、機械的に修正できる部分を修正する
    • ビルドを行い、エラー&警告がないか確認します
    • この時点で、問題なくビルドが通り、実行できた場合にはラッキー
  • 自動変換後、エラー&警告が出た場合には、内容を確認して切り分けます
    • Swiftの文法の問題なのか?(後述)
    • iOS9に関する問題なのか?(実行は出来るけどネットワークで落ちるなどは、ATSの問題かもしれません)
    • 外部ライブラリの問題なのか?(CocoaPodを使っている場合には、Podfileの『platform :ios, '9.1'』をxcodeのTargetOSに合わせるなどして試してみる)

自動変換されたケース

言語仕様として新しく追加されたもの

  • do
  • try, catch

戻り値で明らかに型がわかるもの

  • 『as!』でのダウンキャスト指定が削除されていました
    • うろ覚えだけど、『as!』自体、Swift1.1から、1.2にアップデートした際に追加されたような気が……。
sample_1_1.swift
// 1.2
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! UITableViewCell
    return cell
}

// 2.0
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath)
    return cell
}

その他

  • println() -> print()

自動変換はされないけど、QuickFixが効いたケース

varからletへ

  • とにかく一度しか使われない値は、すべて定数(let)へ。安全性第一という言語仕様なのでしょう
  • エラーではなく、警告レベルだったと思います
sample_2_1.swift
// 1.2
var iconNum:Int = 2
// 2.0
let iconNum:Int = 2

自動変換しきれなかったエラーと対応

そのものズバリな回答にはならないかもしれませんが、どのようなメッセージが、どのような理由で表示されているか、イメージできるようになると思います。

Value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?

  • 非オプショナル型への代入で、Forced Unwrapping(!)か、Optional Chaining(?)のどちらかを選択させられる
  • う〜ん、これも安全性への配慮でしょうか
sample_3_1.swift
// 1.2
var title:String = textField.text
// 2.0
var title:String = textField.text!

Use of unresolved identifier 'EKEventEditViewActionCanceled'

EKEventEditViewDelegate

  • EKEventは、カレンダーやリマインダーの操作をするクラスですが、微妙に定数が変更されていました
  • ドキュメントに『This information is subject to change,〜』と書いてあるので責められません……。
sample_3_2.swift
// 1.2
EKEventEditViewActionCanceled.rawValue
// 2.0
EKEventEditViewAction.Canceled.rawValue

// 2.0
enum EKEventEditViewAction : Int {
    case Canceled
    case Saved
    case Deleted
    static var Cancelled: EKEventEditViewAction { get }
}

Redundant conformance of 'HogeMainViewController' to protocol 'AdViewDelegate'

  • プロトコルの 冗長定義(二重定義)
  • たぶん、親クラスで同じクラスを呼び出しているので、子クラスで呼び出しをやめる(削除する)
sample_3_3.swift
// 1.2
class HogeMainViewController: HigeViewController, AdViewDelegate, UIScrollViewDelegate, WSCoachMarksViewDelegate {
}

// 2.0
class HogeMainViewController: HigeViewController, UIScrollViewDelegate, WSCoachMarksViewDelegate {
}

Nil is not compatible with expected argument type '()'

  • 一部オプションに nil が指定できなくなりました
sample_3_4.swift
// 1.2
item.managedObjectContext!.save(nil);
// 2.0
item.managedObjectContext!.save();
17
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16