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. 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
  2. • Result • Ordered Collection Diffing • Opaque Types •

    Property Wrappers • etc…. Swift 5.x features
  3. 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
  4. “success” / “failure” 2ύλʔϯ͚ͩΛ΋ͭenum ࣦഊ͢ΔՄೳੑ͕͋Δॲཧͷ ໭Γ஋΍ίʔϧόοΫͰ࢖༻͢Δ Result public enum Result<Success,

    Failure: Error> { case success(Success) case failure(Failure) } public func map<NewSuccess>( _ transform: (Success) -> NewSuccess ) -> Result<NewSuccess, Failure> { ... } public func mapError<NewFailure>( _ transform: (Failure) -> NewFailure ) -> Result<Success, NewFailure> { ... } public func flatMap<NewSuccess>( _ transform: (Success) -> Result<NewSuccess, Failure> ) -> Result<NewSuccess, Failure> { ... } public func flatMapError<NewFailure>( _ transform: (Failure) -> Result<Success, NewFailure> ) -> Result<Success, NewFailure> { ... }
  5. “success”࣌ʹฦ͢ ஋΍ͦͷܕΛม׵͢Δ Result // // public func map<NewSuccess>( // _

    transform: (Success) -> NewSuccess // ) -> Result<NewSuccess, Failure> // let result: Result<[Item], Error> let newResult = result.map { items -> [Section] in return makeSections(from: items) }
  6. “success”࣌ʹ ผͷResultܕʹม׵͢Δ “success”࣌ʹ Optionalͳ஋ΛͱΔ Result͔Β Non Optionalͳ஋ΛͱΔ Resultʹม׵ Result //

    // public func flatMap<NewSuccess>( // _ transform: (Success) -> Result<NewSuccess, Failure> // ) -> Result<NewSuccess, Failure> // let result: Result<Item?, Error> let newResult = result.flatMap { item -> Result<Item, Error> in if let item = item { return .success(item) } else { return .failure(CustomError.requiredIsNil) } }
  7. Standard Libraryʹ ௥Ճ͞Εͨ Collectionͷࠩ෼Λ ܭࢉ͢Δfunction @available(swift, introduced: 5.1) extension BidirectionalCollection

    { public func difference<C>( from other: C, by areEquivalent: (Element, C.Element) -> Bool ) -> CollectionDifference<Element> where ... } extension BidirectionalCollection where Element: Equatable { public func difference<C>( from other: C ) -> CollectionDifference<Element> where ... } Ordered Collection Diffing
  8. CollectionDifference͸ ࡟আͱૠೖͷ2ύλʔϯͷ EnumͰߏ੒͞Ε͍ͯΔ @available(swift, introduced: 5.1) public struct CollectionDifference<ChangeElement> {

    public enum Change { case insert(offset: Int, element: ChangeElement, associatedWith: Int?) case remove(offset: Int, element: ChangeElement, associatedWith: Int?) } ... } Ordered Collection Diffing
  9. 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
  10. ௚༁: “ෆಁ໌ͳܕ” 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
  11. • Triangle • Square • Pentagon // Protocol types func

    makeShape() -> Shape 
 
 // Opaque types func makeSomeShape() -> some Shape Opaque types • Circle • Ellipse Shape
  12. • Triangle • Square • Pentagon // Protocol types func

    makeShape() -> Shape 
 
 // Opaque types func makeSomeShape() -> some Shape Opaque types • Circle • Ellipse Shape
  13. • Triangle • Square • Pentagon // Protocol types func

    makeShape() -> Shape 
 
 // Opaque types func makeSomeShape() -> some Shape Opaque types • Circle • Ellipse Shape
  14. • Protocolʹassociated type͕͍͍ͭͯͯ΋ܕΛࢦఆͤͣʹ஋Λฦ ͤΔ Opaque types protocol GameObject { associatedtype

    Shape var shape: Shape { get } } func makeGameObject() -> GameObject { ... } // Compile Error func makeSomeGameObject() -> some GameObject { ... } // OK
  15. • function (property)ࣗମ͕”ந৅తͳܕ”ͷ࣮ଶΛࢦఆͰ͖Δ Opaque types func generic<T: Shape>() -> T

    { ... } let r: Rectangle = generic() // ݺͼग़͠ଆ͕࣮ଶΛࢦఆ͍ͯ͠Δ let c: Circle = generic() func reverseGeneric() -> some Shape { return Rectangle(...) } let s = reverseGeneric()// function͕࣮ଶΛࢦఆ͍ͯ͠Δ
  16. • Φʔόʔϔουແ͘”ந৅తͳܕ”Λએݴग़དྷΔ 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
  17. 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() } } }
  18. Opaque types struct LandmarkRow: View { var landmark: Landmark var

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

    body: HStack<TuppleView<(Image, Text, Spacer, Text)>> { HStack { landmark.image .resizable() .frame(width: 50, height: 50) Text(landmark.name) Spacer() Text(landmark.id) } } }
  20. 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() } } }
  21. 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() } } }
  22. 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() } } }
  23. 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() } } }
  24. 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() } } }
  25. 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() } } }
  26. ϓϩύςΟ΁ͷΞΫηεํ๏Λ ಠࣗʹఆٛ͢Δ͜ͱ͕ग़དྷΔ࢓૊Έ ಠࣗͷ 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"
  27. ࡞Γํ 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"
  28. @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
  29. ࡞Γํ 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
  30. ࡞Γํ 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
  31. GenericsΛ࢖ͬͯwrappedValueͷܕΛ ҙਤͨ͠΋ͷʹࢦఆ͢Δ͜ͱ΋Մೳ @propertyWrapper struct Atomic<Value> { private var value: Value

    init(wrappedValue: Value) { self.value = wrappedValue } var wrappedValue: Value { get { return load() } set { store(newValue: newValue) } } ... } Property Wrapper
  32. Property Wrapper - UserDefaults @propertyWrapper struct UserDefault<T> { 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) } } }
  33. Property Wrapper - Dependency Injection @propertyWrapper struct Inject<Component> { 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
  34. 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