Does not conform to protocol BindableObject - Xcod

2020-05-31 12:48发布

问题:

Playing around with examples out there. Found a project that had a class that was a bindableobject and it didn't give any errors. Now that Xcode 11 beta 4 is out, I'm getting the error:

Type 'UserSettings' does not conform to protocol 'BindableObject'

It has a fix button on the error which when you click on that, it adds

typealias PublisherType = <#type#>

It expects you to fill in the type.

What would the type be?

class UserSettings: BindableObject {

    let didChange = PassthroughSubject<Void, Never>()

    var score: Int = 0 {
        didSet {
            didChange.send()
        }
    }
}

回答1:

Beta 4 Release notes say:

The BindableObject protocol’s requirement is now willChange instead of didChange, and should now be sent before the object changes rather than after it changes. This change allows for improved coalescing of change notifications. (51580731)

You need to change your code to:

class UserSettings: BindableObject {

    let willChange = PassthroughSubject<Void, Never>()

    var score: Int = 0 {
        willSet {
            willChange.send()
        }
    }
}

In Beta 5 they change it again. This time they deprecated BindableObject all together!

BindableObject is replaced by the ObservableObject protocol from the Combine framework. (50800624)

You can manually conform to ObservableObject by defining an objectWillChange publisher that emits before the object changes. However, by default, ObservableObject automatically synthesizes objectWillChange and emits before any @Published properties change.

@ObjectBinding is replaced by @ObservedObject.

class UserSettings: ObservableObject {
    @Published var score: Int = 0
}

struct MyView: View {
    @ObservedObject var settings: UserSettings
}


回答2:

in Xcode 11.X, I verify is fine in Xcode 11.2.1, 11.3.

BindableObject is changed to ObservableObject.

ObjectBinding is now ObservedObject.

didChange should be changed to objectWillChange.

List(dataSource.pictures, id: .self) { }

You can also now get rid of the did/willChange publisher and the .send code and just make pictures @Published

The rest will be autogenerated for you.

for example:

import SwiftUI
import Combine
import Foundation

class RoomStore: ObservableObject {
    @Published var rooms: [Room]
    init(rooms: [Room]) {
        self.rooms = rooms
    }
}

struct ContentView: View {
    @ObservedObject var store = RoomStore(rooms: [])
}

ref: https://www.reddit.com/r/swift/comments/cu8cqk/getting_the_errors_pictured_below_when_try_to/