Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Migrate Swift 4.2 to 5.2

Sho Masegi
September 20, 2020

Migrate Swift 4.2 to 5.2

Sho Masegi

September 20, 2020
Tweet

More Decks by Sho Masegi

Other Decks in Programming

Transcript

  1. Migrate Swift 4.2 to 5.2
    iOSDC 2020 09/20(Sun) 15:40-16:00 #iosdc #d
    ShoMasegi

    View full-size slide

  2. About me
    Sho Masegi
    @boc_sho @ShoMasegi
    Money Forward

    View full-size slide

  3. Swift versions
    Swift 5.0
    Swift 5.1
    Swift 5.2
    Swift 5.3
    Swift 6.0?
    2019/03/25 2019/09/19 2020/03/24 2020/09/?? 2020/??/??
    • Xcode 11.0
    • SwiftUI
    • Combine
    • Xcode 10.2 • Xcode 11.4
    • Xcode 12
    • Xcode 12.x ?
    • async / await

    View full-size slide

  4. • Result
    • Ordered Collection Diffing
    • Opaque Types
    • Property Wrappers
    • etc….
    Swift 5.x features

    View full-size slide

  5. Swift versions
    Swift 6.0?
    • Xcode 12.x ?
    • async / await
    Swift 5.0
    Swift 5.1
    Swift 5.2
    2019/03/25 2019/09/19 2020/03/24 2020/??/??
    • Xcode 11.0
    • SwiftUI
    • Combine
    • Xcode 10.2 • Xcode 11.4
    Swift 5.3
    2020/09/??
    • Xcode 12

    View full-size slide

  6. • Swift 5.xͷػೳΛ͋·Γ೺Ѳग़དྷ͍ͯͳ͍ํ
    • Swift 5.xͰϦϦʔε͞ΕͨػೳΛৼΓฦΓ͍ͨํ
    Target

    View full-size slide

  7. • Swift 5.xͰϦϦʔε͞Εͨػೳ͕ͳΜͱͳ͘Θ͔ͬͨঢ়ଶ
    • Swift 5.xͰϦϦʔε͞ΕͨػೳΛ೔ৗۀ຿ʹಋೖ͢Δ४උ͕ग़དྷͨ
    ঢ়ଶ
    Goal

    View full-size slide

  8. Swift 5.xͷओཁͳػೳͷ֓ཁͱ༻్
    • Result
    • Ordered Collection Diffing
    • Opaque Return Types
    • Property Wrappers
    Agenda

    View full-size slide

  9. “success” / “failure”
    2ύλʔϯ͚ͩΛ΋ͭenum
    ࣦഊ͢ΔՄೳੑ͕͋Δॲཧͷ
    ໭Γ஋΍ίʔϧόοΫͰ࢖༻͢Δ
    Result
    public enum Result {
    case success(Success)
    case failure(Failure)
    }
    public func map(
    _ transform: (Success) -> NewSuccess
    ) -> Result { ... }
    public func mapError(
    _ transform: (Failure) -> NewFailure
    ) -> Result { ... }
    public func flatMap(
    _ transform: (Success) -> Result
    ) -> Result { ... }
    public func flatMapError(
    _ transform: (Failure) -> Result
    ) -> Result { ... }

    View full-size slide

  10. “success”࣌ʹฦ͢
    ஋΍ͦͷܕΛม׵͢Δ
    Result
    //
    // public func map(
    // _ transform: (Success) -> NewSuccess
    // ) -> Result
    //
    let result: Result<[Item], Error>
    let newResult = result.map { items -> [Section] in
    return makeSections(from: items)
    }

    View full-size slide

  11. “success”࣌ʹ
    ผͷResultܕʹม׵͢Δ
    “success”࣌ʹ
    Optionalͳ஋ΛͱΔ
    Result͔Β
    Non Optionalͳ஋ΛͱΔ
    Resultʹม׵
    Result
    //
    // public func flatMap(
    // _ transform: (Success) -> Result
    // ) -> Result
    //
    let result: Result
    let newResult = result.flatMap { item -> Result in
    if let item = item {
    return .success(item)
    } else {
    return .failure(CustomError.requiredIsNil)
    }
    }

    View full-size slide

  12. Ordered Collection Diffing

    View full-size slide

  13. Standard Libraryʹ
    ௥Ճ͞Εͨ
    Collectionͷࠩ෼Λ
    ܭࢉ͢Δfunction
    @available(swift, introduced: 5.1)
    extension BidirectionalCollection {
    public func difference(
    from other: C,
    by areEquivalent: (Element, C.Element) -> Bool
    ) -> CollectionDifference where ...
    }
    extension BidirectionalCollection where Element: Equatable {
    public func difference(
    from other: C
    ) -> CollectionDifference where ...
    }
    Ordered Collection Diffing

    View full-size slide

  14. CollectionDifference͸
    ࡟আͱૠೖͷ2ύλʔϯͷ
    EnumͰߏ੒͞Ε͍ͯΔ
    @available(swift, introduced: 5.1)
    public struct CollectionDifference {
    public enum Change {
    case insert(offset: Int,
    element: ChangeElement,
    associatedWith: Int?)
    case remove(offset: Int,
    element: ChangeElement,
    associatedWith: Int?)
    }
    ...
    }
    Ordered Collection Diffing

    View full-size slide

  15. ΍ͬͱඪ४Ͱࠩ෼ܭࢉ͕
    ࣮૷͞Εͨʂ

    View full-size slide

  16. UITableView΍UICollectionView
    Ͱ࢖͓͏ʂ

    View full-size slide

  17. DiffableDataSourceΛ
    ࢖͍·͠ΐ͏ʂ

    View full-size slide

  18. Diffable Data Sources
    • UITableViewDiffableDataSource
    • UICollectionViewDiffableDataSource
    • NSCollectionViewDiffableDataSourceReference

    View full-size slide

  19. Ordered Collection Diffing
    • ʲSwiftʳ Swift5.1ͷ৽ػೳ Ordered Collection Diffingೖ໳
    https://qiita.com/shiz/items/0e363219a0151d790d03
    Diffable Data Sources
    • ࣌୅ͷมԽʹԠͯ͡ਐԽ͢ΔCollectionView ~Compositional LayoutsͱDiffable
    Data Sources~
    https://qiita.com/shiz/items/a6032543a237bf2e1d19
    References

    View full-size slide

  20. Opaque types

    View full-size slide

  21. ௚༁: “ෆಁ໌ͳܕ”
    ProtocolͷΑ͏ͳܕΛந৅తʹѻ͑ΔΑ
    ͏ʹ͢Δ΋ͷ
    ”some Shape”ͷΑ͏ʹ࢖༻ͯ͠
    ”Shape”Λܧঝͨ͋͠ΔҰͭͷܕΛࣔ͢
    // Opaque types
    func makeSomeShape() -> some Shape {
    return Triangle(size: 1)
    }
    // Not Opaque types (Protocol Types)
    func makeShape() -> Shape {
    return Circle(diameter: 2)
    }
    protocol Shape { }
    struct Triangle: Shape { ... }
    struct Circle: Shape { ... }
    Opaque types

    View full-size slide

  22. • Triangle
    • Square
    • Pentagon
    // Protocol types
    func makeShape() -> Shape


    // Opaque types
    func makeSomeShape() -> some Shape
    Opaque types
    • Circle
    • Ellipse
    Shape

    View full-size slide

  23. • Triangle
    • Square
    • Pentagon
    // Protocol types
    func makeShape() -> Shape


    // Opaque types
    func makeSomeShape() -> some Shape
    Opaque types
    • Circle
    • Ellipse
    Shape

    View full-size slide

  24. • Triangle
    • Square
    • Pentagon
    // Protocol types
    func makeShape() -> Shape


    // Opaque types
    func makeSomeShape() -> some Shape
    Opaque types
    • Circle
    • Ellipse
    Shape

    View full-size slide

  25. ͳΔ΄Ͳʁʁ

    View full-size slide

  26. ͳʹ͕خ͍͠ͷʁʁ

    View full-size slide

  27. • Protocolʹassociated type͕͍͍ͭͯͯ΋ܕΛࢦఆͤͣʹ஋Λฦ
    ͤΔ
    • function (property)ࣗମ͕”ந৅తͳܕ”ͷ࣮ଶΛࢦఆͰ͖Δ
    • Φʔόʔϔουແ͘”ந৅తͳܕ”Λએݴग़དྷΔ
    Opaque types

    View full-size slide

  28. • Protocolʹassociated type͕͍͍ͭͯͯ΋ܕΛࢦఆͤͣʹ஋Λฦ
    ͤΔ
    • function (property)ࣗମ͕”ந৅తͳܕ”ͷ࣮ଶΛࢦఆͰ͖Δ
    • Φʔόʔϔουແ͘”ந৅తͳܕ”Λએݴग़དྷΔ
    Opaque types

    View full-size slide

  29. • Protocolʹassociated type͕͍͍ͭͯͯ΋ܕΛࢦఆͤͣʹ஋Λฦ
    ͤΔ
    Opaque types
    protocol GameObject {
    associatedtype Shape
    var shape: Shape { get }
    }
    func makeGameObject() -> GameObject { ... } // Compile Error
    func makeSomeGameObject() -> some GameObject { ... } // OK

    View full-size slide

  30. • Protocolʹassociated type͕͍͍ͭͯͯ΋ܕΛࢦఆͤͣʹ஋Λฦ
    ͤΔ
    • function (property)ࣗମ͕”ந৅తͳܕ”ͷ࣮ଶΛࢦఆͰ͖Δ
    • Φʔόʔϔουແ͘”ந৅తͳܕ”Λએݴग़དྷΔ
    Opaque types

    View full-size slide

  31. • Protocolʹassociated type͕͍͍ͭͯͯ΋ܕΛࢦఆͤͣʹ஋Λฦ
    ͤΔ
    • function (property)ࣗମ͕”ந৅తͳܕ”ͷ࣮ଶΛࢦఆͰ͖Δ
    • Φʔόʔϔουແ͘”ந৅తͳܕ”Λએݴग़དྷΔ
    Opaque types

    View full-size slide

  32. • function (property)ࣗମ͕”ந৅తͳܕ”ͷ࣮ଶΛࢦఆͰ͖Δ
    Opaque types
    func generic() -> T { ... }
    let r: Rectangle = generic() // ݺͼग़͠ଆ͕࣮ଶΛࢦఆ͍ͯ͠Δ
    let c: Circle = generic()
    func reverseGeneric() -> some Shape { return Rectangle(...) }
    let s = reverseGeneric()// function͕࣮ଶΛࢦఆ͍ͯ͠Δ

    View full-size slide

  33. • Protocolʹassociated type͕͍͍ͭͯͯ΋ܕΛࢦఆͤͣʹ஋Λฦ
    ͤΔ
    • function (property)ࣗମ͕”ந৅తͳܕ”ͷ࣮ଶΛࢦఆͰ͖Δ
    • Φʔόʔϔουແ͘”ந৅తͳܕ”Λએݴग़དྷΔ
    Opaque types

    View full-size slide

  34. • Protocolʹassociated type͕͍͍ͭͯͯ΋ܕΛࢦఆͤͣʹ஋Λฦ
    ͤΔ
    • function (property)ࣗମ͕”ந৅తͳܕ”ͷ࣮ଶΛࢦఆͰ͖Δ
    • Φʔόʔϔουແ͘”ந৅తͳܕ”Λએݴग़དྷΔ
    Opaque types

    View full-size slide

  35. • Φʔόʔϔουແ͘”ந৅తͳܕ”Λએݴग़དྷΔ
    Opaque types
    let triangle: Triangle = Triangle()
    MemoryLayout.size(ofValue: triangle) // 1
    let square: Square = Square()
    MemoryLayout.size(ofValue: square) // 8
    var shape: Shape = Triangle()
    MemoryLayout.size(ofValue: shape) // 40
    var someShape: some Shape = Triangle()
    MemoryLayout.size(ofValue: someShape) // 1

    View full-size slide

  36. • Protocolʹassociated type͕͍͍ͭͯͯ΋ܕΛࢦఆͤͣʹ஋Λฦ
    ͤΔ
    • function (property)ࣗମ͕”ந৅తͳܕ”ͷ࣮ଶΛࢦఆͰ͖Δ
    • Φʔόʔϔουແ͘”ந৅తͳܕ”Λએݴग़དྷΔ
    Opaque types

    View full-size slide

  37. Ͳ͜Ͱ࢖͏ͷʁʁ

    View full-size slide

  38. Opaque types
    struct LandmarkRow: View {
    var landmark: Landmark
    var body: some View {
    HStack {
    landmark.image
    .resizable()
    .frame(width: 50, height: 50)
    Text(landmark.name)
    Spacer()
    }
    }
    }

    View full-size slide

  39. Opaque types
    struct LandmarkRow: View {
    var landmark: Landmark
    var body: HStack> {
    HStack {
    landmark.image
    .resizable()
    .frame(width: 50, height: 50)
    Text(landmark.name)
    Spacer()
    }
    }
    }

    View full-size slide

  40. Opaque types
    struct LandmarkRow: View {
    var landmark: Landmark
    var body: HStack> {
    HStack {
    landmark.image
    .resizable()
    .frame(width: 50, height: 50)
    Text(landmark.name)
    Spacer()
    Text(landmark.id)
    }
    }
    }

    View full-size slide

  41. Opaque types
    struct LandmarkRow: View {
    var landmark: Landmark
    var body: some View {
    HStack {
    landmark.image
    .resizable()
    .frame(width: 50, height: 50)
    Text(landmark.name)
    Spacer()
    }
    }
    }

    View full-size slide

  42. Opaque types
    struct LandmarkRow: View {
    var landmark: Landmark
    var body: some View {
    HStack {
    landmark.image
    .resizable()
    .frame(width: 50, height: 50)
    Text(landmark.name)
    Spacer()
    }
    }
    }

    View full-size slide

  43. Opaque types
    struct LandmarkRow: View {
    var landmark: Landmark
    var body: some View {
    HStack {
    landmark.image
    .resizable()
    .frame(width: 50, height: 50)
    Text(landmark.name)
    Spacer()
    }
    }
    }

    View full-size slide

  44. Opaque types
    struct LandmarkRow: View {
    var landmark: Landmark
    var body: some View {
    HStack {
    landmark.image
    .resizable()
    .frame(width: 50, height: 50)
    Text(landmark.name)
    Text(landmark.id)
    Spacer()
    }
    }
    }

    View full-size slide

  45. Opaque types
    struct LandmarkRow: View {
    var landmark: Landmark
    var body: some View {
    HStack {
    landmark.image
    .resizable()
    .frame(width: 50, height: 50)
    Text(landmark.name)
    Spacer()
    }
    }
    }

    View full-size slide

  46. Opaque types
    struct LandmarkRow: View {
    var landmark: Landmark
    var body: some View {
    HStack {
    landmark.image
    .resizable()
    .frame(width: 50, height: 50)
    Text(landmark.name)
    Spacer()
    }
    }
    }

    View full-size slide

  47. Property Wrapper

    View full-size slide

  48. ϓϩύςΟ΁ͷΞΫηεํ๏Λ
    ಠࣗʹఆٛ͢Δ͜ͱ͕ग़དྷΔ࢓૊Έ
    ಠࣗͷ getter / setter Λڞ௨Խग़དྷΔ
    wrappedValueͷ getter / setter Λ
    ࣮૷͢Δ͜ͱͰಠࣗͷΞΫηεํ๏Λ
    ఆٛ͢Δ
    Property Wrapper
    @propertyWrapper
    struct ForcedUpperCase {
    private var upperCased: String = ""
    private var wrappedValue: String {
    get { return upperCased }
    set {
    upperCased = newValue.uppercased()
    }
    }
    }
    @ForcedUpperCase var string: String
    string = "uppercase" // string = “UPPERCASE"

    View full-size slide

  49. ࡞Γํ
    Property Wrapper
    @propertyWrapper
    struct ForcedUpperCase {
    private var upperCased: String = ""
    private var wrappedValue: String {
    get { return upperCased }
    set {
    upperCased = newValue.uppercased()
    }
    }
    }
    @ForcedUpperCase var string: String
    string = "uppercase" // string = “UPPERCASE"

    View full-size slide

  50. @propertyWrapper
    struct ForcedUpperCase {
    private var upperCased: String = ""
    private var wrappedValue: String {
    get { return upperCased }
    set {
    upperCased = newValue.uppercased()
    }
    }
    }
    @ForcedUpperCase var string: String
    string = "uppercase" // string = “UPPERCASE"
    ࡞Γํ
    1. @propertyWrapperΛ struct / class /
    enumʹ͚ͭΔ
    Property Wrapper

    View full-size slide

  51. ࡞Γํ
    1. @propertyWrapperΛ struct / class /
    enumʹ͚ͭΔ
    2. wrappedValueϓϩύςΟΛఆٛ͠
    getter / setter Λ࣮૷͢Δ
    @propertyWrapper
    struct ForcedUpperCase {
    private var upperCased: String = ""
    private var wrappedValue: String {
    get { return upperCased }
    set {
    upperCased = newValue.uppercased()
    }
    }
    }
    @ForcedUpperCase var string: String
    string = "uppercase" // string = “UPPERCASE"
    Property Wrapper

    View full-size slide

  52. ࡞Γํ
    1. @propertyWrapperΛ struct / class /
    enumʹ͚ͭΔ
    2. wrappedValueϓϩύςΟΛఆٛ͠
    getter / setter Λ࣮૷͢Δ
    ͚ͩʂʂ
    @propertyWrapper
    struct ForcedUpperCase {
    private var upperCased: String = ""
    private var wrappedValue: String {
    get { return upperCased }
    set {
    upperCased = newValue.uppercased()
    }
    }
    }
    @ForcedUpperCase var string: String
    string = "uppercase" // string = “UPPERCASE"
    Property Wrapper

    View full-size slide

  53. GenericsΛ࢖ͬͯwrappedValueͷܕΛ
    ҙਤͨ͠΋ͷʹࢦఆ͢Δ͜ͱ΋Մೳ
    @propertyWrapper
    struct Atomic {
    private var value: Value
    init(wrappedValue: Value) {
    self.value = wrappedValue
    }
    var wrappedValue: Value {
    get { return load() }
    set { store(newValue: newValue) }
    }
    ...
    }
    Property Wrapper

    View full-size slide

  54. Property Wrapper - UserDefaults
    @propertyWrapper
    struct UserDefault {
    let key: String
    let defaultValue: T
    var wrappedValue: T {
    get {
    return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
    }
    set {
    UserDefaults.standard.set(newValue, forKey: key)
    }
    }
    }

    View full-size slide

  55. Property Wrapper - Dependency Injection
    @propertyWrapper
    struct Inject {
    var component: Component
    init(){
    self.component = Resolver.shared.resolve(Component.self)
    }
    public var wrappedValue:Component {
    get { return component}
    mutating set { component = newValue }
    }
    }
    From https://medium.com/swlh/dependency-injection-in-swift-with-property-wrappers-c1f02f06cd51

    View full-size slide

  56. Swift 5.xͷओཁͳػೳͱ༻్
    • Result
    • Ordered Collection Diffing
    • Opaque Types
    • Property Wrappers
    ·ͱΊ

    View full-size slide

  57. Swift versions
    Swift 6.0?
    • Xcode 12.x ?
    • async / await
    Swift 5.0
    Swift 5.1
    Swift 5.2
    2019/03/25 2019/09/19 2020/03/24 2020/??/??
    • Xcode 11.0
    • SwiftUI
    • Combine
    • Xcode 10.2 • Xcode 11.4
    Swift 5.3
    2020/09/??
    • Xcode 12

    View full-size slide

  58. https://swift.org/

    View full-size slide

  59. ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View full-size slide