问题
I am trying to make dispatchgroup work in my code
let dispatchQueue:DispatchQueue = DispatchQueue(label: "com.dispatchgroup", attributes: .concurrent, target: .main)
var dispatchGroup:DispatchGroup = DispatchGroup()
func renewLoginIfRequired()->String{
self.dispatchGroup.enter()
dispatchQueue.async(group:dispatchGroup){
self.authorizeApplication(completionHandler: {
self.dispatchGroup.leave()
})
}
}
self.dispatchGroup.wait() // Stops execution here
return "Login Success"
}
Above code stops execution at self.dispatchGroup.wait(). I have tried the same code without dispatchQueue.async(group:dispatchGroup) around self.authorizeApplication as well with no luck I am not sure what am i doing wrong. One thing to mention here is that self.authorizeApplication will make an async web service request within that function
Edit 1:
To elaborate the problem even more. I will be returning a session token (String) from this method. Here is the function which is calling this
func processPOSTRequest(_ urlString : String, isAnAuthReq:Bool = false, requestObject: Data?, onSuccess: @escaping (NSDictionary?, NSError?) -> Void, onFailure: @escaping (Data?, NSError?) -> Void){
let manager = AFHTTPSessionManager()
let url = URL(string: urlString);
var request = URLRequest(url: url!);
if !isAnAuthReq{
let token = self.renewLoginIfRequired() //-- Get new token before processing a webservice request
request.setValue(token, forHTTPHeaderField: "Authorization")
}
print("processing URl : "+urlString)
request.httpMethod="POST";
request.httpBody = requestObject
request.setValue("application/json; charset=utf-8", forHTTPHeaderField:"Content-Type")
request.setValue("application/json; charset=utf-8", forHTTPHeaderField:"Accept")
let task = manager.dataTask(with: request, uploadProgress: nil, downloadProgress: nil, completionHandler:{ data, response, error in
if(error == nil){
if let responseCode = (data as? HTTPURLResponse)?.statusCode{
if responseCode != 200 || !((response as? [String: Any])?["success"] as? Bool)!{
let errorResponse = NSError()
print("Response received for URL: "+urlString)
onFailure(nil, errorResponse.addItemsToUserInfo(newUserInfo: ["errorCode":String(responseCode)]))
}
else{
onSuccess(response as! NSDictionary?, nil)
}
}
}
else{
onFailure(nil, error as NSError?)
}
})
task.resume()
}
If i use Notify or closure. How can i do that? I have tried both of them
回答1:
I don't know what is under the hood of the authorizeApplication
request, but it's likely that its callback performs in the main thread, that is, in the main queue. So you enter, leave and wait in the same queue, therefore you can't reach the self.dispatchGroup.leave()
after you've invoked self.dispatchGroup.wait()
.
To handle that you need to redesign the async request and call self.dispatchGroup.leave()
in a background queue.
来源:https://stackoverflow.com/questions/43215543/dispatchgroup-not-working-in-swift-3