I would like to create Observable object of User. This is my structure
import Foundation
struct User {
let email: String
let username: String
}
When i do network request I get response of type Observable<[String:Any]>, that works fine, but I have no idea how to transform that into Observable<[User]>. I tried
func loadUsers() -> Observable<[User]> {
return fetchUserData(cUser: Master.users).map(([String : Any]) throws -> [User])
}
But I get this error
Cannot convert value of type '(([String : Any]) throws -> [User]).Type' to expected argument type '([String : Any]) throws -> [User]'
I don't know where Observable
comes from, there's no class like that in Foundation. Combine has observables, but they're not called that there, they're various types of publishers. Are you using another library like RxSwift?
For the sake of getting you closer to answering the question, let's imagine that fetchUserData returns an array instead.
map
needs to take a function that will transform the input from [String:Any]
to User
. In your case, something like
fetchUserData(...).compactMap { dict in
// I am making "username" and "email" up below,
// you did not mention which keys would exist in the dictionary.
if let username = dict["username"] as? String,
let email = dict["email"] as? String {
return User(email:email, username:username)
} else {
return nil
}
}
I used compactMap
, which does the same thing as map
, except that when you return an optional (User?
in this case), it removes the nil entries.
The reactive framework you're using will have similar calls to do the same thing on Observable, on Publisher, etc. They will also allow you to throw an error instead of returning nil, but they all handle it differently (Combine includes the error type in the type of the Publisher, for example).