在 iOS Swift 中使用 Delegated 和 Protocols 从 dataTaskWithRequest 返回数据

Posted

技术标签:

【中文标题】在 iOS Swift 中使用 Delegated 和 Protocols 从 dataTaskWithRequest 返回数据【英文标题】:Using Delegated and Protocols to return data from dataTaskWithRequest in iOS Swift 【发布时间】:2016-03-22 04:48:55 【问题描述】:

我有一个框架,它调用一个返回 JSON 给我的 API。问题是我的 SDK 中有一个函数,它使用 NSURLSession 并调用 DataTaskWithRequest 来获取数据。问题是我的函数甚至在正确获取数据之前就返回了值。我曾尝试将 Completion Handler 与 DataTaskWithRequest 一起使用,目前正在使用 while 循环来等待接收数据。有没有其他可能的方法来做到这一点

代码

public func getDetails() -> AnyObject 
    if Reachability.isConnectedToNetwork()
    
        received = false
        let baseUrl = "API_URL  Here"
        let url = NSURL(string: baseUrl)
        let request = NSURLRequest(URL: url!)
        let session = NSURLSession.sharedSession()

        print("Starting the connection")
        let task = session.dataTaskWithRequest(request, completionHandler : 
            (data, response, error ) in

            //Proper JSON Form

            do
            
                self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
            
            catch
            
                print("Error")
                return
            

            self.received = true

        )
        task.resume()

        print("Going through the loop")
        while(!received)
        
            print("Searching")
        
        print(JSON)
            return JSON
    
    else
    

        let alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK")
        alert.show()
        return 0

    

【问题讨论】:

发布您的代码... 【参考方案1】:

您的问题是您试图将异步的东西变成同步的东西。用伪代码总结一下,你正在这样做:-

let myData = getDetails(blah)
doSomeAction(myData)

处理它的方法是使用完成块作为指示器本身并使一切异步。 此代码未经测试

public typealias CompletionHandler = (success: Bool, message: String, json: JSON?, error: NSError?) -> Void

func getDetailsAsync(completion: CompletionHandler) 
    if Reachability.isConnectedToNetwork()
    
        received = false
        let baseUrl = "API_URL  Here"
        let url = NSURL(string: baseUrl)
        let request = NSURLRequest(URL: url!)
        let session = NSURLSession.sharedSession()

        print("Starting the connection")
        let task = session.dataTaskWithRequest(request, completionHandler : 
            (data, response, error ) in

            //Proper JSON Form
            if error != nil 
                completion(false, "error", nil, error)
            
            else 
                do
                
                    self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
                    completion(true, "OK", self.JSON, nil)
                
                catch
                
                    print("Error")
                    completion(false, "JSON parsing failed", nil, nil)
                
            

        )
        task.resume()
    
    else 
        completion(false, "No network", nil, nil)
    

这样称呼它:

getDetailsAsync() 
    (success, message, json, error) in 
    if success == true 
        print(json)

    
    else 
        // Do your alert here
        print(message)
        print(error)
    

This 的回答可能会有所帮助。

【讨论】:

谢谢!解决了我的问题【参考方案2】:

是的,使用另一个线程来监视进程并让它通过您的协议发送消息。

newQueue = NSOperationQueue()

    let operation2 = NSBlockOperation(block: 


        )

    operation2.completionBlock = 
        print("Operation 2 completed")
    

    let operation1 = NSBlockOperation(block: 


        )

    operation1.completionBlock = 

        self.newQueue.addOperation(operation2)
    

    operation1.qualityOfService  = .UserInitiated
    newQueue.addOperation(operation1)

这里是代码的概要。简而言之,您使用块 1 启动会话,并在完成时使用块 2 启动您对下载的验证。 block1 在完成时会触发 block2 [几乎像你说的那样立即],但是在下载块 1 中正在完成的数据结构之前,块 2 不会触发。

【讨论】:

对swift中的线程不熟悉的能不能再解释一下 辛格非常直截了当。我在这里所做的只是编写不再从上到下流动的代码,而是从 op1 到 op2。所以 addOperation 启动 op1,当它完成时,它会触发它的完成块,然后添加 operation2 运行,然后触发它的完成块。您可以在操作 1 中启动会话,并在您知道会话在操作 2 中运行时监控其完成情况。 这里的服务质量是 swift 2.0 的一个特性,可以告诉你的 ios 所述进程的优先级是什么。因此,如果您只是监控和操作 1 提高一到两个等级,我会尽可能降低操作 2,检查服务质量是否为 NSOperations。 我喜欢这种方法,将对其进行测试

以上是关于在 iOS Swift 中使用 Delegated 和 Protocols 从 dataTaskWithRequest 返回数据的主要内容,如果未能解决你的问题,请参考以下文章

jQuery Direct and delegated events 直接事件与委托事件

“无效的 Swift 支持”在 Xamarin.iOS 中使用本机 Swift 库

iOS - 如何在 swift 中使用`NSMutableString`

iOS 图表子类 Markerview 使用 Swift 总是在“xxx-Swift.h”中构建错误

iOS 图表子类 Markerview 使用 Swift 总是在“xxx-Swift.h”中构建错误

在ios中使用swift删除文件