snarik
snarik

Reputation: 1225

Swift/Combine- Assign a filtered object to a property on a class

I have a list of objects.

let arr = [[1, 2, 3, 4, 5]]

It lives in a repository.

class ArrayRepository: ObservableObject { 
     @Published let arr = [1,2,3,4,5]
} 

I have a class with a property that needs it assigned at initialization.

class MyClass: ObservableObject { 
    var id: String = ""
    var myProperty: Int? 
}

My class is created through an asynchronous process that is itself a repository.

class myClassRepository { 
   
    func buildClass -> MyClass { 
        myClassInstance = MyClass()
        self.arrayRepository.$arr.map { arr in 
            arr.filter{ $0 == someOther.Value }
        }.assign(to: \.myProperty, on: myClassInstance).store(in: &subscriptions)
       return myClassInstance
    }
} 

The problem is my pattern returns an array of elements that I cant make conform to to the singular property on the class? Whats the best way to get it out?

The error I get is essentially

Declared closure result '[Int]' is incompatible with contextual type 'Int??'

Upvotes: 0

Views: 886

Answers (1)

Jon Shier
Jon Shier

Reputation: 12790

Due to a limitation of Swift's type system, you cannot currently assign to an Optional property with a non-Optional value. You can, however, create your own version of assign that does:

func assign<Root: AnyObject>(to path: ReferenceWritableKeyPath<Root, Output?>, on root: Root) -> AnyCancellable {
    sink { [weak root] in root?[keyPath: path] = $0 }
}

This implementation also has the bonus of preventing a reference cycle.

Upvotes: 1

Related Questions