diff --git a/Enum extensions & tricks.playground/Pages/Enum Codable.xcplaygroundpage/Contents.swift b/Enum extensions & tricks.playground/Pages/Enum Codable.xcplaygroundpage/Contents.swift index ef7a7aa..7c9cebe 100644 --- a/Enum extensions & tricks.playground/Pages/Enum Codable.xcplaygroundpage/Contents.swift +++ b/Enum extensions & tricks.playground/Pages/Enum Codable.xcplaygroundpage/Contents.swift @@ -15,6 +15,14 @@ enum Direction: String, Codable { case west } //: ## `Enum` sans `RawValue` et `associated value` +//: Note : **Depuis Swift 5.5, ces enums sont Codable sans extra work** +enum Device: Codable { + case phone + case pad + case watch + case computer +} +//: Avant cette update, on devait faire cela en plusieurs étapes comme il suit //: * *Step 1* : Déclaration de l'`enum` enum Action { case run @@ -77,6 +85,13 @@ extension Action: Codable { } } //: ## `Enum` avec `associated values` mais sans `RawValue` +//: Note : **Depuis Swift 5.5, ces enums sont Codable sans extra work** +enum Weather: Codable { + case sun + case wind(speed: Int) + case rain(amount: Int, chance: Int) +} +//: Avant cette update, on devait faire cela en plusieurs étapes comme il suit //: * *Step 1* : Déclaration de l'`enum` enum Footballeur { case gardient(name: String) @@ -133,5 +148,4 @@ extension Footballeur: Codable { } } } - //: [< Previous: `for case` pattern matching](@previous)           [Home](Introduction)           [Next: `indirect enum` >](@next) diff --git a/Enum extensions & tricks.playground/playground.xcworkspace/xcuserdata/lucasabijmil.xcuserdatad/UserInterfaceState.xcuserstate b/Enum extensions & tricks.playground/playground.xcworkspace/xcuserdata/lucasabijmil.xcuserdatad/UserInterfaceState.xcuserstate index cc5dc73..b0205c7 100644 Binary files a/Enum extensions & tricks.playground/playground.xcworkspace/xcuserdata/lucasabijmil.xcuserdatad/UserInterfaceState.xcuserstate and b/Enum extensions & tricks.playground/playground.xcworkspace/xcuserdata/lucasabijmil.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/README.md b/README.md index 6dd8183..d711574 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ Here's the list: - Static properties & functions - Strings extensions & tricks - Swift Concurrency : `async await`, `async let` binding, `Task` & `TaskGroup`, `Actor` & `@MainActor` and more. +- Swift Updates : A file containing playgrounds for Swift updates. + - Swift 5.5 - try, throws & rethrows - Typealias - Unit Tests diff --git a/Swift Concurrency.playground/playground.xcworkspace/xcuserdata/labijmil.xcuserdatad/UserInterfaceState.xcuserstate b/Swift Concurrency.playground/playground.xcworkspace/xcuserdata/labijmil.xcuserdatad/UserInterfaceState.xcuserstate index 4e4e737..75ad355 100644 Binary files a/Swift Concurrency.playground/playground.xcworkspace/xcuserdata/labijmil.xcuserdatad/UserInterfaceState.xcuserstate and b/Swift Concurrency.playground/playground.xcworkspace/xcuserdata/labijmil.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Swift Updates/Swift 5.5.playground/Pages/Computed Property.xcplaygroundpage/Contents.swift b/Swift Updates/Swift 5.5.playground/Pages/Computed Property.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..d35b3cb --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/Pages/Computed Property.xcplaygroundpage/Contents.swift @@ -0,0 +1,59 @@ +import Foundation +/*: + # Computed property get only – Support async throws + * Les computed properties `get` only peuvent être `async` `await`, utilisé individuellement ou ensemble + */ +//: * Exemple de `get` `throws` : +enum FileError: Error { + case missing + case unreadable +} + +struct BundleFile { + + let filename: String + + var contents: String { + get throws { + guard let url = Bundle.main.url(forResource: filename, withExtension: nil) else { + throw FileError.missing + } + + do { + return try String(contentsOf: url) + } catch { + throw FileError.unreadable + } + } + } +} +//: * Exemple de `get` `async` +struct UserService { + + let username: String + + var id: String { + get async { + return await fetchUserId(for: username) ?? "" + } + } + + private func fetchUserId(for username: String) async -> String? { return nil } +} +//: * Exemple de `get` `async` `throws` +struct FetchService { + + let url: URL + + var result: Result { + get async throws { + do { + let (data, _) = try await URLSession.shared.data(from: url) + return .success(data) + } catch { + return .failure(error) + } + } + } +} +//: [Home](Home)           [Next: `Double` - `CGFloat` cast >](@next) diff --git a/Swift Updates/Swift 5.5.playground/Pages/Double - CGFloat.xcplaygroundpage/Contents.swift b/Swift Updates/Swift 5.5.playground/Pages/Double - CGFloat.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..e0994ba --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/Pages/Double - CGFloat.xcplaygroundpage/Contents.swift @@ -0,0 +1,22 @@ +import Foundation +import CoreGraphics +/*: + # Cast implicite Double vers CGFloat et CGFloat vers Double + * Pour rappel un `Double` est codé sur 64 bits et un `CGFloat` sur 32 bits + */ +//: * Exemple d'un `Double` converti en `CGFloat` implicitement +func foo(float: CGFloat) -> CGFloat { return float } +let doubleThree = 3.0 +let fooFloat = foo(float: doubleThree) +print("Type of the arg is : \(type(of: doubleThree)) | Type of the return is \(type(of: fooFloat))") +//: * Exemple d'un `CGFloat` converti en `Double` implicitement +func foo(double: Double) -> Double { return double } +let cgFloatThree: CGFloat = 3.0 +let fooDouble = foo(double: cgFloatThree) +print("Type of the arg is : \(type(of: cgFloatThree)) | Type of the return is \(type(of: fooDouble))") +//: * Remarque : Le compilateur préféreras **toujours utiliser un `Double` car il permet d'avoir un maximum de précision** +let randomDouble = Double.random(in: 0...100) +let randomCgFloat = CGFloat.random(in: 0...100) +let result = randomDouble + randomCgFloat +print("Type of the addition is : \(type(of: result))") +//: [< Previous: Computed Property `get` only](@previous)           [Home](Home)           [Next: `lazy var` in local context >](@next) diff --git a/Swift Updates/Swift 5.5.playground/Pages/Enum Codable without RawValue.xcplaygroundpage/Contents.swift b/Swift Updates/Swift 5.5.playground/Pages/Enum Codable without RawValue.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..0ec6b48 --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/Pages/Enum Codable without RawValue.xcplaygroundpage/Contents.swift @@ -0,0 +1,24 @@ +import Foundation +/*: + # Enum non conforme à RawRepresentable peuvent être Codable sans extra work + * Avant cela on devait (voir [Enum Extensions & tricks](https://github.com/LucasAbijmil/Swift-Playgrounds/tree/master/Enum%20extensions%20%26%20tricks.playground)) : + * Déclarer une enum conforme au protocol `CodingKey` + * Déclarer une enum conforme au protocol `Error` + * Ajouter l'init pour être conforme à `Decodable` + * Ajouter la fonction `encode(to:)` pour être conforme à `Encodable` + */ +//: * Exemple d'une `Enum` sans `RawValue` et sans associated values +enum Device: Codable { + case phone + case pad + case watch + case tv + case computer +} +//: * Exemple d'une `Enum` sans `RawValue` et avec associated values +enum Weather: Codable { + case sun + case wind(speed: Int) + case rain(amount: Int, chance: Int) +} +//: [< Previous: Extending static member lookup](@previous)           [Home](Home) diff --git a/Swift Updates/Swift 5.5.playground/Pages/Extending static member lookup.xcplaygroundpage/Contents.swift b/Swift Updates/Swift 5.5.playground/Pages/Extending static member lookup.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..054b410 --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/Pages/Extending static member lookup.xcplaygroundpage/Contents.swift @@ -0,0 +1,23 @@ +import SwiftUI +/*: + # Swift peut désormais trouver des membres conformes à un protocol dans une fonction générique + * Use principalement avec SwiftUI + * Permet d'utiliser une syntaxe semblable à celle des cases d'une `Enum` pour des protocols dans une fonction générique + */ +//: * Exemple avant l'update +struct SwitchToggleStyleView: View { + + var body: some View { + Toggle("Example", isOn: .constant(true)) + .toggleStyle(SwitchToggleStyle()) + } +} +//: * Grâce à cette évolution on peut désormais réduire le code à ceci. Noté comment la syntaxe est proche de celle d'un cas d'une enum +struct SwitchToggleStyleReducedView: View { + + var body: some View { + Toggle("Example", isOn: .constant(true)) + .toggleStyle(.switch) + } +} +//: [< Previous: `#if` postfix member expressions](@previous)           [Home](Home)           [Next: enum sans `RawValue` conforme à `Codable` sans extra work >](@next) diff --git a/Swift Updates/Swift 5.5.playground/Pages/Home.xcplaygroundpage/Contents.swift b/Swift Updates/Swift 5.5.playground/Pages/Home.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..73cc77c --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/Pages/Home.xcplaygroundpage/Contents.swift @@ -0,0 +1,11 @@ +/*: + # Swift 5.5 + * [Swift Concurrency](https://github.com/LucasAbijmil/Swift-Playgrounds/tree/master/Swift%20Concurrency.playground) + * [Computed Property](Computed%20Property) : Les computed properties `get` only supporte `async` & `throws` utilisé ensemble ou séparément + * [Double - CGFloat cast implicit](Double%20-%20CGFloat) : Cast implicite `CGFloat` vers `Double` et vice-versa + * [Lazy var dans un context local](Lazy%20var%20in%20Local%20Context) : `lazy var` désormais possible dans le scope de fonctions + * [#if check dans des expressions postfix](if%20postfix%20member%20expressions) : Il est désormais possible d'effectuer des `#if` checked dans des expressions postfixs + * [Protocols conformes à un protocol générique](Extending%20static%20member%20lookup) : Permet d'utiliser des protocols dans une fonction générique comme des cases d'une `Enum` + * [Enum sans RawValue conforme à Codable](Enum%20Codable%20without%20RawValue) : Les `enum` non conforme à `RawRepresentable` peuvent être conforme à `Codable` sans extra work + */ +//: La majorité des exemples sont tirés du site [What's new in Swift](https://www.whatsnewinswift.com/?from=5.4&to=5.5) diff --git a/Swift Updates/Swift 5.5.playground/Pages/Lazy var in Local Context.xcplaygroundpage/Contents.swift b/Swift Updates/Swift 5.5.playground/Pages/Lazy var in Local Context.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..37775d0 --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/Pages/Lazy var in Local Context.xcplaygroundpage/Contents.swift @@ -0,0 +1,45 @@ +import Foundation +/*: + # Lazy var dans un context local (fonction) + * Désormais les fonctions supportent les `lazy var` dans leur scope + * Voir [Lazy Property](https://github.com/LucasAbijmil/Swift-Playgrounds/tree/master/Lazy%20Property.playground) + */ +/*: + * Exemple d'une fonction avec une `lazy var`. Cette fonction print dans l'ordre : + * Before lazy + * After lazy + * In printGreeting() + * Hello, Lucas + */ +func printGreeting(to name: String) -> String { + print("In printGreeting()") + return "Hello, \(name)" +} + +func lazyDummyTest() { + print("Before lazy") + lazy var name = printGreeting(to: "Lucas") + print("After lazy") + print(name) +} + +lazyDummyTest() +/*: + * Exemple d'une fonction avec une `lazy var`. La variable sera calculée uniquement dans le cas où le `Bool.random()` renvoie true. La fonction print dans l'ordre : + * Before lazy + * After lazy + * Si `bool` est à true : + * In printGreeting() + * Hello, Lucas + */ +func lazyDummyBoolTest(_ bool: Bool) { + print("Before lazy") + lazy var name = printGreeting(to: "Lucas") + print("After lazy") + if bool { + print(name) + } +} + +lazyDummyBoolTest(Bool.random()) +//: [< Previous: `Double` - `CGFloat` cast](@previous)           [Home](Home)           [Next: `#if` postfix member expressions >](@next) diff --git a/Swift Updates/Swift 5.5.playground/Pages/if postfix member expressions.xcplaygroundpage/Contents.swift b/Swift Updates/Swift 5.5.playground/Pages/if postfix member expressions.xcplaygroundpage/Contents.swift new file mode 100644 index 0000000..f57640e --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/Pages/if postfix member expressions.xcplaygroundpage/Contents.swift @@ -0,0 +1,33 @@ +import SwiftUI +/*: + # #if checks supportés pour les expressions postfix + * Use case principalement pour l'utilisation avec SwiftUI + */ +//: * Exemple d'un use case classique pour une `View` SwiftUI +struct SomeText: View { + + var body: some View { + Text("Hello, World!") + #if os(iOS) + .font(.largeTitle) + #else + .font(.headline) + #endif + } +} +//: * Il est également possible de nester des checks +struct SomeTextWithDebug: View { + + var body: some View { + Text("Hello, World!") + #if os(iOS) + .font(.largeTitle) + #if DEBUG + .foregroundColor(.red) + #endif + #else + .font(.headline) + #endif + } +} +//: [< Previous: `lazy var` in local context](@previous)           [Home](Home)           [Next: Extending static member lookup >](@next) diff --git a/Swift Updates/Swift 5.5.playground/contents.xcplayground b/Swift Updates/Swift 5.5.playground/contents.xcplayground new file mode 100644 index 0000000..5b611ba --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/contents.xcplayground @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Swift Updates/Swift 5.5.playground/playground.xcworkspace/contents.xcworkspacedata b/Swift Updates/Swift 5.5.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ca3329e --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Swift Updates/Swift 5.5.playground/playground.xcworkspace/xcuserdata/labijmil.xcuserdatad/UserInterfaceState.xcuserstate b/Swift Updates/Swift 5.5.playground/playground.xcworkspace/xcuserdata/labijmil.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..ee01d2f Binary files /dev/null and b/Swift Updates/Swift 5.5.playground/playground.xcworkspace/xcuserdata/labijmil.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Swift Updates/Swift 5.5.playground/playground.xcworkspace/xcuserdata/lucasabijmil.xcuserdatad/UserInterfaceState.xcuserstate b/Swift Updates/Swift 5.5.playground/playground.xcworkspace/xcuserdata/lucasabijmil.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..78ac016 Binary files /dev/null and b/Swift Updates/Swift 5.5.playground/playground.xcworkspace/xcuserdata/lucasabijmil.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Swift Updates/Swift 5.5.playground/xcuserdata/labijmil.xcuserdatad/xcschemes/xcschememanagement.plist b/Swift Updates/Swift 5.5.playground/xcuserdata/labijmil.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..2c1bcfb --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/xcuserdata/labijmil.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,16 @@ + + + + + SchemeUserState + + Swift 5.5 (Playground).xcscheme + + isShown + + orderHint + 0 + + + + diff --git a/Swift Updates/Swift 5.5.playground/xcuserdata/lucasabijmil.xcuserdatad/xcschemes/xcschememanagement.plist b/Swift Updates/Swift 5.5.playground/xcuserdata/lucasabijmil.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..2c1bcfb --- /dev/null +++ b/Swift Updates/Swift 5.5.playground/xcuserdata/lucasabijmil.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,16 @@ + + + + + SchemeUserState + + Swift 5.5 (Playground).xcscheme + + isShown + + orderHint + 0 + + + +