swiftuicombineprotocol-extension

Which is an appropriate protocol constraint to identify a property as being '@Published'


I want to establish a binding for an object in a collection so that I can pass it on downstream like a reference pointer. I want this to be a convenience function but I am having some trouble.

What constraint, if any, can I put on the following protocol 'Diskable' to eliminate the error I'm getting below?

final class PropertiesData: ObservableObject, Diskable {
    
    @Published var fetchedItems: [Property] = []
        
    var location: URL {
        let file = try! LocalStorage.rootFolder.createFileIfNeeded(withName: "properties.data")
        return file.url
    }
}

extension Diskable where T: Identifiable {
    
    func binding(for object: T) -> Binding<T> {
        let index = fetchedItems.firstIndex(where: { $0.id == object.id } )!
        return $fetchedItems[index] // cannot find 'fetchedItems' in scope
    }
}

protocol Diskable: AnyObject {
    associatedtype T: Codable
    var location: URL { get }
    var fetchedItems: [T] { get set }
}

Solution

  • As far as I could replicate your code here is a solution (tested with Xcode 12.1 / iOS 14.1)

    extension Diskable where T: Identifiable {
        func binding(for object: T) -> Binding<T> {
            let index = fetchedItems.firstIndex(where: { $0.id == object.id } )!
            return Binding(
                get: { self.fetchedItems[index] },
                set: { self.fetchedItems[index] = $0 }
            )
        }
    }