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

时间:2016-03-22 04:48:56

标签: ios swift nsurlsession completionhandler

我有一个调用API的框架,它返回一个JSON给我。问题是我的SDK中有一个函数,它使用NSURLSession并调用DataTaskWithRequest来获取数据。问题是我的函数甚至在正确获取数据之前返回值。我已经尝试使用具有DataTaskWithRequest的Completion Handler并且当前使用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

    }
}

2 个答案:

答案 0 :(得分:0)

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

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启动会话,并在完成时使用block2启动下载验证。 block1在完成时[几乎立即按你所说]触发block2,但是在下载了块1中完成的数据结构之前,块2不会触发。

答案 1 :(得分:0)

您的问题是您正在尝试将异步转换为同步的东西。在伪代码中总结一下,你这样做: -

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回答可能会有所帮助。