Reputation: 401
I try to initial a value under init() method, but I got this error Escaping closure captures mutating 'self' parameter
It work if I put it under onAppear() but it won't call if the screen is on back-group, so It is not what I needed . Attached my coding ..
struct GameRowForDemo: View {
let game : Game
var user : User?
init(game:Game){
self.game = game
let uid = "123"
User.getById(id: uid).then { user in
self.user = user!
}
}
var body: some View {
Text("Text")
}
}
static func getById(id: String) -> Promise<User?> {
let p = Promise<User?> { (resolve , reject) in
let db = Firestore.firestore()
let ref = db.collection("users").document(id)
ref.getDocument { (snapshot, err) in
if let err = err{
reject(err)
}
guard let dict = snapshot?.data() else {
print("No User found")
resolve(nil)
return
}
do {
let data = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
let group = try JSONDecoder.init().decode(User.self, from: data)
resolve(group)
}catch{
reject(error)
}
}
}
return p
}
Upvotes: 3
Views: 2151
Reputation: 258345
As view is non-mutating here, I would refactor provided code by decomposing related things into explicit view model as below
import Combine
class GameViewModel: ObservableObject {
@Published var game : Game
@Published var user : User?
init(game: Game) {
self.game = game
}
func fetchUser(uid: String) {
User.getById(id: uid).then {[weak self] user in
DispatchQueue.main.async {
self?.user = user!
}
}
}
}
struct GameRowForDemo: View {
@ObservedObject var viewModel: GameViewModel
init(viewModel: GameViewModel) {
self.viewModel = viewModel
viewModel.fetchUser(uid: "123")
}
var body: some View {
Text("Text")
}
}
Upvotes: 1