Swift 5.6, built into Xcode 13.3, adds the following new features.

#unavailable

Before Swift 5.6, only #available means available, and after Swift 5.6, #unavailable means unavailable, which means the opposite.

if #unavailable(iOS 15) {
    // iOS15 is not available, i.e. the code before iOS15 works properly
} else {
    // The iOS15 code works fine
}
Copy the code

Note: The biggest difference in usage from #available is that #unavailable cannot use the platform wildcard *.

Type placeholder _

Use the _ / _? The compiler can then infer from type inference that _/_? The type of.

/ / _? Instead of a Double?
var a: _? = 3.14
a = nil

// Array elements are of type Int, _ instead of Int
let array: Array<_> = [1.2.3.4.6]

// The dictionary value is of type UIColor, _ instead of UIColor
let colors: [String: _] = ["red": UIColor.red, "green": UIColor.green, "blue": UIColor.blue]
Copy the code

CodingKeyRepresentable

  • Before Swift 5.6, if the dictionary Key is notIntorStringType, which does not yield expected results in Codable coding.
enum Student: String.Codable {
    case name
    case age
    case sex
}

/ / a dictionary
let dict: [Student: String] = [.name: "zhangsan", .age: "20", .sex: "male"]
/ / code
let encoder = JSONEncoder(a)do {
    let student = try encoder.encode(dict)
    print(String(decoding: student, as: UTF8.self)) // ["name","zhangsan","age","20","sex","male"]
} catch {
    fatalError(error.localizedDescription)
}
Copy the code
  • CodingKeyRepresentable has been added since Swift 5.6, and is used to get the expected result.
// Implement the CodingKeyRepresentable protocol
enum Student: String.Codable.CodingKeyRepresentable {
    case name
    case age
    case sex
}

/ / a dictionary
let dict: [Student: String] = [.name: "zhangsan", .age: "20", .sex: "male"]
/ / code
let encoder = JSONEncoder(a)do {
    let student = try encoder.encode(dict)
    print(String(decoding: student, as: UTF8.self)) // {"sex":"male","name":"zhangsan","age":"20"}
} catch {
    fatalError(error.localizedDescription)
}
Copy the code

@ MainActor warning

  • There is no problem with the following code before Swift 5.6, but after Swift 5.6, a warning is issued.
import SwiftUI

@MainActor
class ViewModel: ObservableObject {}struct ContentView: View {
    // warning: expression requiring global actor 'MainActor' cannot appear in default-value expression of property '_viewModel'; this is an error in Swift 6
    @StateObject private var viewModel = ViewModel(a)var body: some View {
        Text("Hello, world!")}}Copy the code

Note: this is only a warning in Swift 5.6, but could be an error in the future.

  • To avoid warnings, you can modify it as follows.
import SwiftUI

@MainActor
class ViewModel: ObservableObject {}struct ContentView: View {
    @StateObject private var viewModel: ViewModel

    init(a) {
        _viewModel = StateObject(wrappedValue: ViewModel()}var body: some View {
        Text("Hello, world!")}}Copy the code

Existence any

  • Use of agreements prior to Swift 5.6.
protocol SomeProtocol {
    func work(a)
}

class Student: SomeProtocol {
    func work(a) {
        print("Study")}}class Teacher: SomeProtocol {
    func work(a) {
        print("Teach")}}// Generic functions, generics comply with the protocol
func generic<T> (who: T) where T: SomeProtocol {
    who.work()
}

/ / right
generic(who: Student())
generic(who: Teacher())

/ / error
let student: SomeProtocol = Student(a)Protocol' SomeProtocol' as a type cannot conform to the Protocol itself
generic(who: student)

let teacher: SomeProtocol = Teacher(a)Protocol' SomeProtocol' as a type cannot conform to the Protocol itself
generic(who: teacher)
Copy the code
  • A new type has been added after Swift 5.6 —There are types ofDenoted byAny type. Modify the above function and initialize the partialSomeProtocolChange to an existing typeany SomeProtocolThe error code becomes correct.
protocol SomeProtocol {
    func work(a)
}

class Student: SomeProtocol {
    func work(a) {
        print("Study")}}class Teacher: SomeProtocol {
    func work(a) {
        print("Teach")}}// Change the generic function to any
func existential(who: any SomeProtocol) {
    who.work()
}

/ / right
existential(who: Student())
existential(who: Teacher())

/ / right
let student: any SomeProtocol = Student()
existential(who: student)

let teacher: any SomeProtocol = Teacher()
existential(who: teacher)
Copy the code