简体   繁体   中英

Asynchronous Issue JSON Swift

let task = session.dataTaskWithURL(url!, completionHandler: {
    data, response, error -> Void in

    if (error != nil) {
        println(error)


    } else {


        let jsonresult = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

        var dummyfeed:AnyObject

       //println(jsonresult)
        for var i = 0; i <  jsonresult["feed"]!.count; i++ {

            self.feeds.append([String:String]())

            dummyfeed = jsonresult["feed"]![i] as NSDictionary

           self.feeds[i]["id"] = dummyfeed["id"] as? String
           self.feeds[i]["name"] = dummyfeed["name"] as? String
           self.feeds[i]["status"] = dummyfeed["status"] as? String
           self.feeds[i]["profilePic"] = dummyfeed["profilePic"] as? String
            self.feeds[i]["timeStamp"] = dummyfeed["timeStamp"] as? String
            self.feeds[i]["url"] = dummyfeed["url"] as? String

        }

    }
})
task.resume()

So Feeds is a global variable, so that I display the picture of each entry in Feeds on a table view. But it's calling asynchronously println(self.feeds) inside the task variable and println(feeds) outside of the task variable are differnent. How do I make it synchronously?

Do not make it run synchronously. Run it asynchronously, but then synchronize the interaction with feeds. The simplest way to achieve that it to dispatch the updating of the feeds back to the main queue and reloadData for the table view. This eliminates the possibility that you'll be using it from the main queue while it's mutating in the background, but avoids the horrible UX of doing this network request synchronously:

let task = session.dataTaskWithURL(url!) { data, response, error in
    if (error != nil) {
        println(error)
    } else {
        var parseError: NSError?
        if let jsonresult = NSJSONSerialization.JSONObjectWithData(data, options:nil, error: nil) as? NSDictionary {
            if let receivedFeeds = jsonresult["feed"] as? [[String: AnyObject]] {
                dispatch_async(dispatch_get_main_queue()) {
                    self.feeds = [[String: String]]()
                    for receivedFeed in receivedFeeds {
                        var outputFeed = [String : String]()
                        outputFeed["id"] = receivedFeed["id"] as? String
                        outputFeed["name"] = receivedFeed["name"] as? String
                        outputFeed["status"] = receivedFeed["status"] as? String
                        outputFeed["profilePic"] = receivedFeed["profilePic"] as? String
                        outputFeed["timeStamp"] = receivedFeed["timeStamp"] as? String
                        outputFeed["url"] = receivedFeed["url"] as? String
                        self.feeds.append(outputFeed)
                    }
                    self.tableView.reloadData()
                }
            } else {
                println("did not find `feed`")
            }
        } else {
            println("problem parsing JSON: \(parseError)")
        }
    }
}
task.resume()

That should be a little more robust handling errors and employs asynchronous pattern of letting request run asynchronously, but dispatch updating of model object and UI back to the main thread.

  let task = session.dataTaskWithURL(url!, completionHandler: {
        data, response, error -> Void in

        if (error != nil) {
            println(error)


        } else {


            let jsonresult = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

            var dummyfeed:AnyObject

           //println(jsonresult)
            for var i = 0; i <  jsonresult["feed"]!.count; i++ {

                self.feeds.append([String:String]())

                dummyfeed = jsonresult["feed"]![i] as NSDictionary
                dispatch_async(dispatch_get_main_queue()) {

                    self.feeds[i]["id"] = dummyfeed["id"] as? String
                    self.feeds[i]["name"] = dummyfeed["name"] as? String
                    self.feeds[i]["status"] = dummyfeed["status"] as? String
                    self.feeds[i]["profilePic"] = dummyfeed["profilePic"] as? String
                    self.feeds[i]["timeStamp"] = dummyfeed["timeStamp"] as? String
                    self.feeds[i]["url"] = dummyfeed["url"] as? String
                }

            }
            self.tableView.reloadData()
        }

    })

        task.resume()

Hey Rob, I did what I think you tell me to do, and feeds is still empty :(

I have same problem my code is was working fine, but now, using dataTaskWithURL it didn't return any data, or even error. I think issue is iOS 8.2 I upgraded.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM