当前位置: 首页 > 知识库问答 >
问题:

如何在iOS中使用异步方法(JSON Restful服务)?

虞唯
2023-03-14

我有一个iOS应用程序,可以从JSON的restful web服务中同步数据。此方法是从外部类(而不是UI控制器)调用的。这个类有一个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)")
        }
   }

我已经尝试过方法,但我相信我不知道如何使用,到目前为止,因为大多数例子都关闭了服务

感谢您的任何帮助。谢谢

共有3个答案

公羊灿
2023-03-14

这可能对你有帮助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

    }
}
龙俊德
2023-03-14
匿名用户

如果我理解正确,您希望能够根据调用S.Sync(C)

一种方法是将闭包作为参数包含到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的枚举来处理获取数据的结果。

然后我们添加一个要在完成时调用的函数,作为Sync函数的参数:

func Sync(C:客户,回调:(同步结果)-

此方法将以同步结果作为参数调用,并返回void。

我们将回调存储在函数toexecutewhendone中,以供以后使用。

根据您在过程中是否看到任何错误或一切都很顺利,我们会在过程中生成不同的同步结果值,并在准备就绪时(解析完成或失败时)使用当前的同步结果调用您的函数来执行whendone

在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
    }
}

我希望这是有意义的,也是你需要的。

房唯
2023-03-14

您可以给同步类一个完成处理程序闭包。

在您的UIViewController中:

S.completion = {
 information in
 UIElement.updateWith(information)
}

当然,您需要向您的同步类添加一个成员:

var完成:((信息:字符串)-

您可以调用“完成”(“这里有一些信息!”) 从类的Syncronization的内部parseJSON()URLSession()

这里有一些关于Swift闭包的阅读

 类似资料:
  • 没有await并且在非异步方法中调用异步方法的行为是什么?我这样问是因为我看到Visual Studio在调用异步方法时没有显示任何警告,好像这是一件非常正常的事情。在这种情况下,异步方法的行为是否像是同步的?

  • 我正在尝试在从CrudRepository扩展的存储库接口上执行我试图在方法中使用存储库实现来执行此操作。当我运行以下代码时,线程在 UpdateTasksService List 中永久等待

  • 我是web服务开发的初学者。我们正在使用Spring3用java构建RESTWeb应用程序。 我们正在使用的Web服务具有异步登录方法。我们为他们提供了一个回调监听器URL,他们的服务在其中发回响应。 因此,当我们发送登录请求时,我们会收到一个空白响应作为确认。和服务发送一个响应,其中包含侦听器URL上的实际数据。 请帮助,我应该如何设计/实现调用登录服务作为同步调用?谢谢 编辑:下面是回发消息的

  • 我有三项任务。任务1、任务2和任务3。task1和task2是异步任务,即它们同时执行任务,返回完成结果的时间不可预测。最初,我希望task1和task2同时执行,并在得到结果后执行task3。 我设计的结构如上所述,但我总是得到不好的结果,比如如果task2是一个url发布请求,使用afnet,我不能得到成功块参与。 任何帮助我的人我都会感激的。

  • 注意:还有一个类似的问题,如何在task.run中调用异步方法?但是对于C#来说,选择的答案有反对票,并且没有地址configureaWait。

  • 我有一个链接生成器服务,它能够生成到特定内容类型的链接(用户的详细信息页面,内容项目的详细信息页面等)。 这个服务真的很好用,而且有同步功能: 现在,我必须为登录用户引入单独的路由,以便将更改为。 我需要添加到链接生成器服务中的唯一更改是检查并返回不同的路由URL。这不是一个问题,只要我的登录用户的信息将是同步可用的。但这不是... 我有一个返回一个承诺。第一次调用它时,它实际上发出了一个服务器请