Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Swift3とObjective-Cのブリッジでハマったこと

1,194 views

Published on

集まれSwift好き!Swift愛好会 Vol12の内容です。

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Swift3とObjective-Cのブリッジでハマったこと

  1. 1. Swift3とObjective-Cのブ リッジでハマったこと @yousan 集まれSwift好き!Swift愛好会 Vol12
  2. 2. 自己紹介 • @yousan • iOSアプリエンジニア • 趣味 テニス
  3. 3. Swift3移行中 Objective-Cでクラッシュ
  4. 4. let person = Person(nickname: "yousan") let uppercaseNickname = ObjCUtils.convert(toUppercase: person.nickname) print(uppercaseNickname) @implementation ObjCUtils + (nonnull id)convertToUppercase:(nonnull id)string { return [string uppercaseString]; } @end Swift Objective-C
  5. 5. Terminating app due to uncaught exception 'NSInvalidArgumentException
  6. 6. let person = Person(nickname: "yousan") let uppercaseNickname = ObjCUtils.convert(toUppercase: person.nickname) print(uppercaseNickname) @implementation ObjCUtils + (nonnull id)convertToUppercase:(nonnull id)string { return [string uppercaseString]; } @end Swift Objective-C struct Person { let nickname: String? } オプショナルでした Swift2のときはAnyObjectだったので コンパイル時にエラーになっていた
  7. 7. id → Anyの注意 + (nonnull id)convertToUppercase:(nonnull id)string; class func convert(toUppercase string: Any) -> Any class func convertToUppercase(string: AnyObject) -> AnyObject Swift2 Swift3 オプショナルは引数に渡せない オプショナルも引数に渡せる Objective-C nonnullでもコンパイルエラーにならない
  8. 8. idである必要がなければ型を指定 + (nonnull NSString *)convertToUppercase:(nonnull NSString *)string; class func convert(toUppercase string: String) -> String Objective-C Swift3 NSArray, NSDictionary, NSSetはジェネリクスを指定 + (nonnull NSArray<NSString *>)convertToUppercase:(nonnull NSArray<NSString *>)strings; class func convert(toUppercase strings: [String]) -> [String] Objective-C Swift3 外部ライブラリは気をつけるしかない
  9. 9. なぜこんな改変を?
  10. 10. • SE-0116 https://github.com/apple/swift-evolution/blob/master/proposals/0116-id-as-any.md • Objective-C id as Swift Any - Swift Blog https://developer.apple.com/swift/blog/?id=39 • 5分でわかるSE-0116(id-as-any) // Speaker Deck https://speakerdeck.com/takasek/5fen-dewakaruse-0116-id-as-any
  11. 11. Swift2 // StringがAnyObjectに暗黙的に変換されている let converted = ObjCUtils.convertToUppercase("yousan") 書きやすいように暗黙的にAnyObjectに変換している 本来関係のない型に、しかも暗黙的に変換されるのは 色々な問題を生むのではないか?
  12. 12. Swift3 let name: AnyObject = "yousan" as AnyObject // AnyObjectへの変換を明示 let converted = ObjCUtils.convert(toUppercase: name) let uppercaseNickname: String = converted as! String print(uppercaseNickname) 該当する場所全てにこれを書くのは大変 SE-0072 Fully eliminate implicit bridging conversions from Swift
  13. 13. AnyObjectをAnyにすれば • AnyObjectへの暗黙変換は発生しない • AnyObjectへの変換処理も書く必要がない • 全てのSwiftの型をObjective-Cに渡せる ※ 渡した結果どうなるかはコンパイラに任せる 将来的には全てのSwiftの型をブリッジしたい
  14. 14. Objective-Cに対応する型がな い場合どうなるか • _SwiftValueというクラスとして受け取る • 今後もObjective-Cに対応づけられるSwiftの型は 増えていくので、この型に依存するべきではな い
  15. 15. 例えば https://github.com/apple/swift-evolution/blob/master/proposals/0139-bridge-nsnumber-a • Int16 → _SwiftValue • CGRect → _SwiftValue Swift 3.0.1 • Int16 → NSNumber • CGRect → NSValue Swift 3.0
  16. 16. まとめ • Objective-Cでidに値を渡すときはオプショナル に注意 • Objective-Cに渡せるSwiftの型は今後も増えてい くと思われます

×