概要
Xcode7.3にアップデートしたことで、Swiftのバージョンが2.2になりました。
これにより既存プロジェクトに大量にWarning, Errorが出たので対応したものをまとめました。
WarningのほとんどがSwift 3に向けてdeprecatedになったものの警告でした。
ここにある以外のWarningについても、GitHubのapple/swift-evolution をチェックすると原因がわかる思います。
Warning
'var' parameters are deprecated and will be removed in Swift 3
swift-evolution: SE-0003
修正前
func sayHelloTo(var name: String) {
name = "Hello, \(name)."
print(name)
}
修正後
func sayHelloTo(name: String) {
var name = name
name = "Hello, \(name)."
print(name)
}
'++' is deprecated: it will be removed in Swift 3
swift-evolution: SE-0007
修正前
var index: Int = 0
index++
修正後
var index: Int = 0
index += 1
--
についても同様。
C-style for statement is deprecated and will be removed in a future version of Swift
swift-evolution: SE-0007
修正前
// 昇順ループ
let array1: [Int] = [10, 20, 30, 40, 50]
for var i = 0; i < array1.count; i++ {
print("\(i): \(array1[i])")
}
// 降順ループ
var array2: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for var i = array2.count - 1; i >= 0; i -= 1 {
array2.removeAtIndex(i)
}
print(array2) // []
修正後
対応方法はたくさんあります。
// 昇順ループ
let array1: [Int] = [10, 20, 30, 40, 50]
// 0 ..< array1.count の Rangeに対して for-in
for index in 0 ..< array1.count {
print("\(index): \(element)")
}
// array1.enumerate()に対して for-in
for (index, element) in array1.enumerate() {
print("\(index): \(element)")
}
// array1.enumerate()に対して forEach
array1.enumerate().forEach { (index, element) in
print("\(index): \(element)")
}
// 降順ループ
var array2: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in (0 ..< array2.count).reverse() {
array2.removeAtIndex(i)
}
print(array2) // []
// 配列のインデックス配列を逆順にforEach
var array3: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9]
array3.indices.reverse().forEach {
array3.removeAtIndex($0)
}
print(array3) // []
Use '#selector' instead of explicitly constructing a 'Selector'
Use of string literal for Objective-C selectors is deprecated; use '#selector' instead
swift-evolution: SE-0022
NSNotificationCenter や UIControl などにメソッド名を渡す方法が変更になりました。
修正内容
文字列で指定されていたメソッド名を#selector(<Class>.<MethodName>)
を使って指定します。
今までは文字列だけで参照されていたメソッドは、Xcode上でメソッドが呼び出されていることが捕捉できませんでしたが、#selector()
に変わることで、メソッドが呼び出されていることがわかるようになります。
修正前
class SomeTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
refreshControl = UIRefreshControl()
refreshControl.addTarget(
self,
action: "refresh",
forControlEvents: .ValueChanged)
tableView.addSubview(refreshControl)
}
func refresh() {
}
修正後
class SomeTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
refreshControl = UIRefreshControl()
refreshControl.addTarget(
self,
action: #selector(SomeTableViewController.refresh),
forControlEvents: .ValueChanged)
tableView.addSubview(refreshControl)
}
func refresh() {
}
__FILE__ is deprecated and will be removed in Swift 3. please use #file
__LINE__ is deprecated and will be removed in Swift 3. please use #line
__FUNCTION__ is deprecated and will be removed in Swift 3. please use #function
swift-evolution: SE-0028
デバッグ用識別子の呼び出しが変わった。
This proposal renames the following identifiers:
__FILE__ -> #file
__LINE__ -> #line
__COLUMN__ -> #column
__FUNCTION__ -> #function (Added during review)
__DSO_HANDLE__ -> #dsohandle
修正前
print("\(__FILE__), \(__FUNCTION__), \(__LINE__)")
修正後
print("\(#file), \(#function), \(#line)")
Error
Use of unresolved identifier 'SomeEnumType'
Objective-Cの .h ファイルで定義している enum が Swiftファイルから参照できなくなりました。
@interface
の内側で定義していたものを、外側に移動させるとエラーがなくなりました。
修正前
@interface Feedback : NSObject
typedef NS_ENUM(NSInteger, SomeEnumType) {
SomeEnumTypeNone = 0,
SomeEnumTypeA = 1,
SomeEnumTypeB = 2,
SomeEnumTypeC = 3,
}
修正後
typedef NS_ENUM(NSInteger, SomeEnumType) {
SomeEnumTypeNone = 0,
SomeEnumTypeA = 1,
SomeEnumTypeB = 2,
SomeEnumTypeC = 3,
}
@interface Feedback : NSObject
'(name: String, size: CGSize) -> UIFont' is not convertible to '(name: String, size: CGFloat) -> UIFont?'
UILabel
のfont
プロパティにUIFontオブジェクトを代入しているところでエラーが発生しました。
原因は不明。
修正前
let label = UILabel()
if let font = UIFont(name: "AvenirNext-Medium", size: 12.0) { // UIFontのイニシャライザでエラー
label.font = font
}
修正後
let label = UILabel()
let descriptor = UIFontDescriptor(name: "AvenirNext-Medium", size: 12.0)
label.font = UIFont(descriptor: descriptor, size: 12.0)