Can't assign a value to variable inside of closure Swift [duplicate]

冷暖自知 提交于 2021-02-17 06:24:08

问题


I'm trying to get current document count belongs to spesific user from Firebase. Whenever i try to assign count value to my variable in closure, value is always shown as nill. So that i did couple of research, as a result i figured out networking sometimes takes so long and it happens asynchronously. So if i'm not wrong due to asynchronous returning a value inside a fucntion might happen before assign value .

I tried to add dispatchqueue.main.async but it didn't work for me...

Here is my code

 func getEventCount () -> Int? {
    var count: Int?
    db.collection("Events").whereField("owner", isEqualTo: currentUser.email).getDocuments { (snapshot, error) in
        if error != nil {
            print(error)
        }else {
            DispatchQueue.main.async {

                if let snapshot = snapshot {
                    count = snapshot.count
                }

            }
        }
    }
    return count
}

My main goal is getting count data from database and assign it to 'count' variable. So why do i need that count variable? Because i'm going to pass that count value to tableView datasource method numberOfRowsInSection which is expecting a int value. With that value i'm going to represent some data in Events document from firestore in table views.

note: When i try to print count value in closure it shows desired value, but when function return value it's shown nill...


回答1:


Once it is a Async call - you cannot synchronously return the value from the function. You should accept a callback to the function that will accept the count. That callback function or closure will be passed the value asynchronously.

func getEventCount (callback: @escaping(Result<Int, Error>) -> Void) {
    db.collection("Events").whereField("owner", isEqualTo: currentUser.email).getDocuments { (snapshot, error) in
        if error != nil {
            let result = Result.failure(error)
            callback(result)
        }else if let snapshot = snapshot {
               let result = Result.success(snapshot.count)
               callback(result)
        } else {
            let result = Result.failure(SomeCustomAppError)
            callback(result)
        }
    }
}

Then you can call this function passing in a callback

self.getCount() { result in
  switch result {
   case .success(let count): /// use count
   print(count)
   // only here u can assign the count value to ur variable
   case .error(let error): /// handle error
   print(error.localizedDescription)
  }
}

Note: In the above I've used the Result datatype from Swift standard library - https://developer.apple.com/documentation/swift/result so that both error or result can be passed back



来源:https://stackoverflow.com/questions/61758094/cant-assign-a-value-to-variable-inside-of-closure-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!