我在使用NSURLSession时如何访问数据?

时间:2014-07-24 17:38:01

标签: json swift nsurlsession

我是iOS开发的新手。我使用的是Swift,而且我对Objective-C的经验很少,所以其他一些可能相关的答案很难理解。我试图了解如何使用NSURLSession从Web上的JSON文件中获取一些数据。我找到了一些有关从URL获取文件的有用信息,但与其他StackOverflow用户(NSURLSessionDataTask dataTaskWithURL completion handler not getting called)一样,我听说NSURLConnection不是当前获取数据的方式,所以我是试图使用NSURLSession

当我从捆绑包中获取JSON时,我正在使用此扩展名 字典(我很确定我从教程中得到了这个代码):

static func loadJSONFromBundle(filename: String) -> Dictionary<String, AnyObject>? {
    let path = NSBundle.mainBundle().pathForResource(filename, ofType: ".json")
    if !path {
        println("Could not find level file: \(filename)")
        return nil
    }
    var error: NSError?
    let data: NSData? = NSData(contentsOfFile: path, options: NSDataReadingOptions(),
        error: &error)
    if !data {
        println("Could not load level file: \(filename), error: \(error!)")
        return nil
    }
    let dictionary: AnyObject! = NSJSONSerialization.JSONObjectWithData(data,
        options: NSJSONReadingOptions(), error: &error)
    if !dictionary {
        println("Level file '\(filename)' is not valid JSON: \(error!)")
        return nil
    }
    return dictionary as? Dictionary<String, AnyObject>
}

我想做类似的事情,从网上的JSON文件中获取字典,因为我不希望在包中包含我的所有JSON文件。到目前为止,我有这个:

static func loadJSONFromWeb(urlstring: String) -> Dictionary<String, AnyObject>? {

    let url = NSURL(string: urlstring)
    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    let session = NSURLSession(configuration: config, delegate: nil, delegateQueue: NSOperationQueue())

    var error: NSError?
    //I think I am using the completionHandler incorrectly. I'd like to access the data from the download
    let task = session.downloadTaskWithRequest(NSURLRequest(URL: url), {(url, response, error) in println("The response is: \(response)")
        })
    task.resume()

    //Isn't this contentsOfURL thing supposed to go with the connection stuff rather than the session stuff?
    //How can I do this with a session? How can I create and use a completionHandler? This way seems clunky.
    let data: NSData? = NSData(contentsOfURL: url)
    if !data {
        println("Could not load data from file: \(url), error: \(error!)")
        return nil
    }
    println("The data is: \(data)")

    let dictionary: AnyObject! = NSJSONSerialization.JSONObjectWithData(data,
        options: NSJSONReadingOptions(), error: &error)
    if !dictionary {
        println("The file at '\(url)' is not valid JSON, error: \(error!)")
        return nil
    }

    return dictionary as? Dictionary<String, AnyObject>   
}

我认为我最需要回答的实际问题是:哪里 是数据吗?我不认为我正在使用会话和任务。我觉得我很喜欢 开始会话以连接到特定网址并使用resume() 开始我想要发生的下载任务,但我不知道该怎么做 从该JSON文件中获取数据。

如果我需要以类似于我在此处找到的方式使用completionHandler和请求: (popViewControllerAnimated work slow inside NSURLSessionDataTask)有人可以解释一下&#39;数据&#39; completionHandler中的数据与我试图阅读/下载的数据有关吗?我对completionHandler以及如何正确使用它感到困惑。

我也查看了NSData的文档,但是我没有看到任何有助于我了解如何从会话中获取数据的内容(或者如何初始化NSData的实例鉴于我的会议)。至于我可以告诉NSURLDownloadTask的文档,任务本身不是我可以访问数据的方式。看起来数据来自会话和任务completionHandler


编辑: 我还查看了NSURLSessionDownloadDelegate的文档,但我可以在Swift中使用一个示例,并提供有关如何使用委托的一些解释。这使我得到了URL加载系统编程指南。如果文档很复杂,我猜测使用会话的好处必定是巨大的。我将继续寻找有关URL加载系统的更多信息。

我发现这个答案很有帮助(但是我很新,我还不能推荐任何东西):https://stackoverflow.com/a/22177659/3842582它帮助我看到我可能需要学习使用代表

我还查看了URL加载系统编程指南。我认为我真正需要的是有关completionHandler的帮助。我怎样才能获得我的数据?或者,我是否已经使用NSData(contentsOfURL: url)正确地做到了(因为我不认为我是)。


提前感谢您提供任何帮助!

2 个答案:

答案 0 :(得分:0)

首先,让数据:NSData? = NSData(contentsOfURL:url)将同步返回您的JSON。你试过这个并且让这个工作简单吗?通过这种方式,您可以在计算NSURLSession的同时开始其余的处理。

如果您要在iOS中使用NSURLSession或许多其他内容,则需要学习代理。幸运的是,他们很容易。在语法方面,您只需将其添加到类声明中,就像您继承它一样。这样做是说您将至少为代表实现所需的功能。这些是回调函数,通常都有很好的文档记录。一旦你理解它就很简单。

如果这不是&#34;重量级&#34;真正需要NSURLSession的项目,你应该看看这个Swift库。除了作为处理JSON的一种非常好的方法之外,还有一个同步调用来直接从URL加载JSON。 https://github.com/dankogai/swift-json/

答案 1 :(得分:0)

为什么NSURLConnection不是获取数据的正确方法?你应该小心同步请求。以下是如何从网址获取数据的示例。

func synchronousExampleRequest() -> NSDictionary {

            //creating the request
            let url: NSURL! = NSURL(string: "http://exampledomain/apiexample.json")
            var request = NSMutableURLRequest(URL: url)
            request.HTTPMethod = "GET"
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")


            var error: NSError?

            var response: NSURLResponse?

            let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)

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

            return resultDictionary
        }