Swift 4 の変更点

Swift 4 の変更点

5c7098ba415787c52a017cf5ec2a4cc8?s=128

Yasuhiro Hatta

June 16, 2017
Tweet

Transcript

  1. Swift 4 の変更点 MOBILE ACT NAGOYA #6 2017/6/16 (FRI)

  2. ⾃⼰紹介 ◦ ⼋⽥ 泰弘 ◦ Fenrir Inc. ◦ ⼤阪勤務 ◦

    iOS アプリ開発担当エンジニア
  3. 今⽇の内容 ◦ Swift 4 でどのような変更があったか調べてみました ◦ Xcode 9 beta 1

    で試せる範囲のみ
  4. ⽂字列が使いやすくなった ◦ Swift 3 では good.characters.count のように String.CharacterView を経由して⽂字列操作 をしていた

    ◦ Swift 4 では String が BidirectionalCollection と RangeReplaceableCollection を実装 ◦ String が Collection になった let good = "Good!!" _ = good.count // 7 SE-0163 String Revision: Collection Conformance, C Interop, Transcoding
  5. 複数⾏⽂字列リテラル ◦ ””” (ダブルクォーテーション 3 つ) で囲って複数⾏⽂字列を定義できるようになった SE-0168 Multi-Line String

    Literals let str1 = "Multi-Line¥nString" let str2 = """ Multi-Line String ""” print(str1 == str2) // true
  6. 異なる数値型を⽐較 ◦ 数値型にプロトコルが追加され、できることが増えた let a: Int = 100 let b:

    UInt = 50 if a > b { // ... } SE-0104 Protocol-oriented integers
  7. Key-Value ペアの Sequence から Dictionary を作れるようになった SE-0165 Dictionary & Set

    Enhancements let pairs: [(String, Int)] = [("a", 10), ("b", 20), ("c", 30)] let dict = Dictionary(uniqueKeysWithValues: pairs) dict["a"] // 10 dict["b"] // 20
  8. Dictionary のフィルタ結果が Dictionary で返ってくるようになった ◦ Swift 3 では Array<(K, V)>

    で返ってきていた let pairs: [(String, Int)] = [("a", 10), ("b", 20), ("c", 30)] let dict = Dictionary(uniqueKeysWithValues: pairs) let filtered = dict.filter { $0.value == 20 } filtered["a"] // nil filtered["b"] // 20
  9. Dictionary の mapValues() で Value を置換 let pairs: [(String, Int)]

    = [("a", 10), ("b", 20), ("c", 30)] let dict = Dictionary(uniqueKeysWithValues: pairs) let mapped = dict.mapValues { $0 * 10 } mapped["a"] // 100 mapped["b"] // 200
  10. Dictionary の Default Value を指定 let dict = ["a": 10]

    _ = dict["b"] ?? 0 _ = dict["b", default: 0] // New!!
  11. Sequence からグループを作る let array = ["a", "", "b", ""] let

    dict: Dictionary<Bool, [String]> = Dictionary(grouping: array, by: { $0.isEmpty }) dict[true] // ["", ""] dict[false] // ["a", "b"]
  12. オブジェクトのシリアライズ ◦ 標準ライブラリに Codable というプロトコルが追加された ◦ public typealias Codable =

    Decodable & Encodable ◦ JSON と Plist のシリアライザは標準で提供される SE-0166 Swift Archival & Serialization SE-0167 Swift Encoders
  13. struct User: Codable { let name: String let age: Int

    } let originalUser = User(name: "xx yy", age: 20) // オブジェクトから JSON データにエンコード let jsonData: Data = try! JSONEncoder().encode(originalUser) // => {"name":"xx yy","age":20} // JSON データをオブジェクトにデコード let decodedUser: User = try! JSONDecoder().decode(User.self, from: jsonData)
  14. One-sided Ranges SE-0172 One-sided Ranges let array = ["a", "b",

    "c", "d", "e"] let subArray1 = array[2...] // ["c", "d", "e"] let subArray2 = array[...2] // [“a”, “b”, "c"] for i in 0... { // 無限ループ。このコードを Playground 貼り付けないでください }
  15. extension から private な定義へア クセス可能 (同じファイル内のみ) SE-0169 Improve Interaction Between

    private Declarations and Extensions class C { private var value: Int = 0 } extension C { func add(_ v: Int) { // extension から private 変数にアクセス value += v // ok (Swift 4) } } class OtherClass { func f() { let c = C() // 同じファイル内でも、別のクラスからは private 変数にアクセスできない let v = c.value // error (従来通り) } }
  16. 変数宣⾔時に class と protocol を 同時に指定 ◦ Swift 3 ではプロトコルを

    & でつないで複数指定できたが、プロトコル以外と組み合わせるこ とができなかった ◦ Swift 4 ではプロトコル以外と組み合わせることができるようなった SE-0156 Class and Subtype existentials protocol P {} class C {} class D: C, P {} let d: C & P = D()
  17. subscript が Generics に対応 class MyContainer { subscript<T: MyKeyConvertible>(key: T)

    -> Element { // ... } } SE-0148 Generic Subscripts
  18. ⧵ で KeyPath ◦ #keyPath() という書き⽅がある ◦ Darwin (iOS, macOS,

    …) でしか使えない ◦ NSObject を継承していないと使えない ◦ コンパイル後、⽂字列になる → 型情報がない、⽂字列をパースするので遅い ◦ などの問題 ◦ Swift 4 でこの問題を解決 ◦ 書き⽅ ◦ ⧵<Type>.<path> ◦ ⧵.<path> ◦ ⽂脈から型がわかる場合は <Type> を省略可能 ◦ Xcode 9 beta 1 ではまだ完全に実装されていませんでした・・・ SE-0161 Smart KeyPaths: Better Key-Value Coding for Swift
  19. @objc の⾃動判別に制限 ◦ @objc メソッドのオーバーライド、@objc プロトコルの実装、@IBAction、@IBOutlet、 @IBInspectable、@GKInspectable、@NSManaged、dynamic 変数は @objc が⾃動的に

    付与されていた ◦ このうち、dynamic は @objc が⾃動的に付与されなくなった class MyClass { dynamic func foo() { } // error: 'dynamic' method must be '@objc' @objc dynamic func bar() { } // okay } SE-0160 Limiting @objc inference
  20. NSNumber のキャストがより厳格 に SE-0170 NSNumber bridging and Numeric types _

    = NSNumber(value: 2) as? Bool // nil (Swift 3 は true) _ = NSNumber(value: 1) as? Bool // true _ = NSNumber(value: Int64.max) as? Int32 // nil (Swift 3 は -1)
  21. ご静聴ありがとうございました