在重新加载 table 视图之前完成了两个服务器请求
Two server requests completed before reloading the table view
我有这两个请求要在重新加载 table 视图之前完成(table 视图取决于它们)。
我试过下面的方法,但没有用。
请求 1 完成,然后 table 视图在请求 2 完成之前重新加载。
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
//1. request 1:
self.serverRequestAuth("/request1")
//2. request 2:
self.serverRequestAuth("/request2")
DispatchQueue.main.async{
//3. reload the table view
self.tableView.reloadData()
}
}
我应该如何进行?
提到:serverRequestAuth包含服务器请求,json的解析,里面字典的解析
方法 serverRequestAuth:
func serverRequestAuth(_ requestName: String){
let requestNameEscaped = requestName.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
var request = NSMutableURLRequest()
request = NSMutableURLRequest(url: URL(string: "\(self.view.getServerPath())\(requestNameEscaped)")!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 5)
request.httpMethod = "GET"
request.setValue(self.view.getAuth(), forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) {data, response, err in
if data != nil {
if let dictionary = self.parseJSONData(data!) {
self.parseDictionary(dictionary, typeOfRequest: requestName)
}
}
}
task.resume()
}
尝试使用DispatchSemaphore
func serverRequestAuth(_ requestName: String){
let requestNameEscaped = requestName.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
let semaphore = DispatchSemaphore(value: 0);
var request = NSMutableURLRequest()
request = NSMutableURLRequest(url: URL(string: "\(self.view.getServerPath())\(requestNameEscaped)")!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 5)
request.httpMethod = "GET"
request.setValue(self.view.getAuth(), forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) {data, response, err in
if data != nil {
if let dictionary = self.parseJSONData(data!) {
self.parseDictionary(dictionary, typeOfRequest: requestName)
semaphore.signal();
}
}
}
task.resume()
semaphore.wait(timeout: .distantFuture)
}
试试这个:
func serverRequestAuth(_ requestName: String, control:@escaping (_ check : Bool)-> Void){
let requestNameEscaped = requestName.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
var request = NSMutableURLRequest()
request = NSMutableURLRequest(url: URL(string: "\(self.view.getServerPath())\(requestNameEscaped)")!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 5)
request.httpMethod = "GET"
request.setValue(self.view.getAuth(), forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) {data, response, err in
if data != nil {
if let dictionary = self.parseJSONData(data!) {
self.parseDictionary(dictionary, typeOfRequest: requestName)
control(true)
}else{
control(false)
}
}
}
task.resume()
}
你可以这样调用它:
serverRequestAuth("myStringRequest1", control: {(check)in
if check {
self.serverRequestAuth("myStringRequest2", control: {(check) in
if check {
self.tableView.reloadData()
}else{
print("error Request 2")
}
})
}else {
print("error request 1")
}
})
我曾经遇到过类似的问题。为了提供一个简单的解决方案,我编写了这个小型库:
https://github.com/prine/ROConcurrency
您可以将请求分组到任务中,等待所有请求完成,然后重新加载 table。
var taskRequest1 = TaskComplex { (finished) -> () in
self.serverRequestAuth("/request1", finished)
}
var taskRequest2 = TaskComplex { (finished) -> () in
self.serverRequestAuth("/request2", finished)
}
var reloadTable = TaskComplex { (finished) -> () in
DispatchQueue.main.async{
// 3. reload the table view
self.tableView.reloadData()
finished()
}
}
var barrierComplex = BarrierComplex(tasks: [taskRequest1, taskRequest2], afterTask: reloadTable)
barrierComplex.startTasks()
您的 serverRequestAuth 方法需要告知其异步完成的时间,因此您需要添加完成的回调:
func serverRequestAuth(_ requestName: String, _ finished:(Bool) -> ()) {
let requestNameEscaped = requestName.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
var request = NSMutableURLRequest()
request = NSMutableURLRequest(url: URL(string: "\(self.view.getServerPath())\(requestNameEscaped)")!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 5)
request.httpMethod = "GET"
request.setValue(self.view.getAuth(), forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) {data, response, err in
if data != nil {
if let dictionary = self.parseJSONData(data!) {
self.parseDictionary(dictionary, typeOfRequest: requestName)
// Here you call finished to tell the Barrier that its finished
finished()
}
}
}
task.resume()
}
我有这两个请求要在重新加载 table 视图之前完成(table 视图取决于它们)。
我试过下面的方法,但没有用。
请求 1 完成,然后 table 视图在请求 2 完成之前重新加载。
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
//1. request 1:
self.serverRequestAuth("/request1")
//2. request 2:
self.serverRequestAuth("/request2")
DispatchQueue.main.async{
//3. reload the table view
self.tableView.reloadData()
}
}
我应该如何进行?
提到:serverRequestAuth包含服务器请求,json的解析,里面字典的解析
方法 serverRequestAuth:
func serverRequestAuth(_ requestName: String){
let requestNameEscaped = requestName.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
var request = NSMutableURLRequest()
request = NSMutableURLRequest(url: URL(string: "\(self.view.getServerPath())\(requestNameEscaped)")!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 5)
request.httpMethod = "GET"
request.setValue(self.view.getAuth(), forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) {data, response, err in
if data != nil {
if let dictionary = self.parseJSONData(data!) {
self.parseDictionary(dictionary, typeOfRequest: requestName)
}
}
}
task.resume()
}
尝试使用DispatchSemaphore
func serverRequestAuth(_ requestName: String){
let requestNameEscaped = requestName.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
let semaphore = DispatchSemaphore(value: 0);
var request = NSMutableURLRequest()
request = NSMutableURLRequest(url: URL(string: "\(self.view.getServerPath())\(requestNameEscaped)")!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 5)
request.httpMethod = "GET"
request.setValue(self.view.getAuth(), forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) {data, response, err in
if data != nil {
if let dictionary = self.parseJSONData(data!) {
self.parseDictionary(dictionary, typeOfRequest: requestName)
semaphore.signal();
}
}
}
task.resume()
semaphore.wait(timeout: .distantFuture)
}
试试这个:
func serverRequestAuth(_ requestName: String, control:@escaping (_ check : Bool)-> Void){
let requestNameEscaped = requestName.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
var request = NSMutableURLRequest()
request = NSMutableURLRequest(url: URL(string: "\(self.view.getServerPath())\(requestNameEscaped)")!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 5)
request.httpMethod = "GET"
request.setValue(self.view.getAuth(), forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) {data, response, err in
if data != nil {
if let dictionary = self.parseJSONData(data!) {
self.parseDictionary(dictionary, typeOfRequest: requestName)
control(true)
}else{
control(false)
}
}
}
task.resume()
}
你可以这样调用它:
serverRequestAuth("myStringRequest1", control: {(check)in
if check {
self.serverRequestAuth("myStringRequest2", control: {(check) in
if check {
self.tableView.reloadData()
}else{
print("error Request 2")
}
})
}else {
print("error request 1")
}
})
我曾经遇到过类似的问题。为了提供一个简单的解决方案,我编写了这个小型库:
https://github.com/prine/ROConcurrency
您可以将请求分组到任务中,等待所有请求完成,然后重新加载 table。
var taskRequest1 = TaskComplex { (finished) -> () in
self.serverRequestAuth("/request1", finished)
}
var taskRequest2 = TaskComplex { (finished) -> () in
self.serverRequestAuth("/request2", finished)
}
var reloadTable = TaskComplex { (finished) -> () in
DispatchQueue.main.async{
// 3. reload the table view
self.tableView.reloadData()
finished()
}
}
var barrierComplex = BarrierComplex(tasks: [taskRequest1, taskRequest2], afterTask: reloadTable)
barrierComplex.startTasks()
您的 serverRequestAuth 方法需要告知其异步完成的时间,因此您需要添加完成的回调:
func serverRequestAuth(_ requestName: String, _ finished:(Bool) -> ()) {
let requestNameEscaped = requestName.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
var request = NSMutableURLRequest()
request = NSMutableURLRequest(url: URL(string: "\(self.view.getServerPath())\(requestNameEscaped)")!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 5)
request.httpMethod = "GET"
request.setValue(self.view.getAuth(), forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) {data, response, err in
if data != nil {
if let dictionary = self.parseJSONData(data!) {
self.parseDictionary(dictionary, typeOfRequest: requestName)
// Here you call finished to tell the Barrier that its finished
finished()
}
}
}
task.resume()
}