[英]How to use asynchronous methods (JSON Restful services) in iOS?
我有一個iOS
應用程序,可以sync
來自JSON
restful web service
。 從外部類(不是UI controller
)調用此方法。 這個類有一個sync方法,它可以毫無問題地發送和檢索數據。 我的問題是如何在獲得結果之前暫停UI。
以下將提供有關代碼的想法。
UIController類
let C : Customer = Customer(UserName: UserName!, Password: Password!)
let S : Syncronization = Syncronization()
S.Sync(C)
同步類
Class Syncronization : NSObject, NSURLSessionDataDelegate
func Sync(C : Customer){
var datastr = ""
datastr = "http://192.168.248.134:8008/MobileWeb.svc/GetFirstTimeSync/" + C.UserName + "/" + C.Password
let url:NSURL = NSURL(string: datastr)!
self.buffer = NSMutableData()
let defaultConfigObject:NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session:NSURLSession = NSURLSession(configuration: defaultConfigObject, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
let req:NSMutableURLRequest = NSMutableURLRequest(URL: url)
req.HTTPMethod = "POST"
session.dataTaskWithURL(url).resume()
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
print("Recieved with data")
buffer.appendData(data)
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if error == nil {
print("Download Successful")
print("Done with Bytes " + String(buffer.length))
self.parseJSONA(self.buffer)
}
else {
print("Error %@",error!.userInfo);
print("Error description %@", error!.localizedDescription);
print("Error domain %@", error!.domain);
}
}
func parseJSONA(data:NSMutableData) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! Array<AnyObject>
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
}
我已經嘗試過dispacther方法,但我相信我到目前為止還不知道如何使用它,因為大多數示例都關閉了UI控制器上的服務和數據交換。
任何形式的幫助表示贊賞。 謝謝
您可以為Sync類提供完成處理程序閉包。
在你的UIViewController
:
S.completion = {
information in
UIElement.updateWith(information)
}
當然,您需要在Syncronization
類中添加一個成員:
var completion:((information:String)->())!
你可以從Syncronization
類的parseJSON()
或URLSession()
內部調用completion("here's some info!")
這可能會幫助你https://thatthinginswift.com/background-threads/
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
// do downloading or sync task here
dispatch_async(dispatch_get_main_queue()) {
// update some UI with downloaded data/sync data
}
}
如果我理解正確,您希望能夠根據您對S.Sync(C)
調用結果在您的UI中執行某些操作
一種方法是將閉包作為Sync
函數的參數。
這是我將如何做到的(免責聲明......我沒有檢查編譯器中的所有內容,因此可能會出現錯誤。看看你得到了多少,如果有問題,只需再寫一次:-)):
enum SynchronizationResult {
case Success(Array<AnyObject>)
case Failure(NSError)
}
class Syncronization : NSObject, NSURLSessionDataDelegate {
var functionToExecuteWhenDone: ((SynchronizationResult) -> Void)?
func Sync(C : Customer, callback: (SynchronizationResult) -> Void){
functionToExecuteWhenDone = callback
var datastr = ""
datastr = "http://192.168.248.134:8008/MobileWeb.svc/GetFirstTimeSync/" + C.UserName + "/" + C.Password
let url:NSURL = NSURL(string: datastr)!
self.buffer = NSMutableData()
let defaultConfigObject:NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session:NSURLSession = NSURLSession(configuration: defaultConfigObject, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
let req:NSMutableURLRequest = NSMutableURLRequest(URL: url)
req.HTTPMethod = "POST"
session.dataTaskWithURL(url).resume()
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
print("Recieved with data")
buffer.appendData(data)
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if error == nil {
print("Download Successful")
print("Done with Bytes " + String(buffer.length))
self.parseJSONA(self.buffer)
} else {
print("Error %@",error!.userInfo);
print("Error description %@", error!.localizedDescription);
print("Error domain %@", error!.domain);
let result = SynchronizationResult.Failure(error!)
if let functionToExecuteWhenDone = functionToExecuteWhenDone {
functionToExecuteWhenDone(result)
}
}
}
func parseJSONA(data:NSMutableData) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! Array<AnyObject>
let result = SynchronizationResult.Success(json)
if let functionToExecuteWhenDone = functionToExecuteWhenDone {
functionToExecuteWhenDone(result)
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
let result = SynchronizationResult.Failure(error)
if let functionToExecuteWhenDone = functionToExecuteWhenDone {
functionToExecuteWhenDone(result)
}
}
}
}
所以...我們引入了一個名為SynchronizationResult的Enum來處理獲取數據的結果。
然后我們添加一個要在完成時調用的函數,作為Sync
函數的參數:
func Sync(C : Customer, callback: (SynchronizationResult) -> Void)
將使用SynchronizationResult
作為參數調用此方法,並返回void。
我們將該回調存儲在functionToExecuteWhenDone
供以后使用。
根據您是否看到任何錯誤或一切都是陽光,我們在此過程中生成不同的SynchronizationResult
值,並在我們准備好時(當解析完成或我們失敗時)使用當前的SynchronizationResult
調用functionToExecuteWhenDone
在你的ViewController中,你可以做一些事情
let C : Customer = Customer(UserName: UserName!, Password: Password!)
let S : Syncronization = Syncronization()
S.Sync(C) { (result) in
switch result {
case .Success(let json):
//Your code to update UI based on json goes here
case .Failure(let error):
//Your code to handle error goes here
}
}
我希望這是有道理的,也是你需要的。
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
print("This is run on the background queue")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("This is run on the main queue, after the previous code in outer block")
})
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.