【问题标题】:How do I access the data when I am using NSURLSession?使用 NSURLSession 时如何访问数据?
【发布时间】:2014-07-24 17:38:00
【问题描述】:

我是 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>   
}

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

如果我需要使用completionHandler 和类似于我在这里找到的请求: (popViewControllerAnimated work slow inside NSURLSessionDataTask) 有人能解释一下completionHandler 中的“数据”与我要读取/下载的文件中的数据有何关系吗?我对completionHandler 以及如何正确使用它感到有些困惑。

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


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

我发现这个答案很有帮助(但我太新了,我还不能投票):https://stackoverflow.com/a/22177659/3842582 它帮助我看到我可能需要学习使用委托。

我还查看了 URL 加载系统编程指南。我认为我真正需要的是完成处理程序的帮助。如何获取我的数据?或者,我是否已经使用NSData(contentsOfURL: url) 正确地做到了(因为我不认为我是)。


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

【问题讨论】:

    标签: json swift nsurlsession


    【解决方案1】:

    首先,让数据:NSData? = NSData(contentsOfURL: url) 将同步返回您的 JSON。您是否尝试过并让它简单地工作?这样你就可以在找出 NSURLSession 的同时开始进行其余的处理。

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

    如果这不是一个真正需要 NSURLSession 的“重量级”项目,你应该看看这个 Swift 库。除了是处理 JSON 的一种非常好的方式之外,还有一个同步调用可以直接从 url 加载 JSON。 https://github.com/dankogai/swift-json/

    【讨论】:

    • 我确实有let data = NSData(contentsOfURL: url),但我希望通过适当使用NSURLSession 来替换它。这目前可以让我看到来自 URL 的数据,但我认为我应该利用这个机会了解更多关于委托(或至少关于完成处理程序)的信息。在重量级项目中同步传递我的数据有什么危险?我可能应该使用安全的方法。你能想出一个有用的资源来了解更多关于代表的信息吗?您是否知道有用的教程或答案?感谢您的帮助!
    • 简单地说,如果你说你是一个特定协议的代表,你只是承诺至少在协议中实现所需的功能。这些是回调。对于像 NSURLSession 这样的东西,它们通常是进度指示器或部分下载(以块的形式下载数据)。在这些情况下,您可以先更新进度指示器,然后将新下载的数据添加到已下载的数据中。
    • 最后一个样本:raywenderlich.com/67081/cookbook-using-nsurlsession。这是一个很好的简短示例。如果您要进行大量会话工作,我强烈建议您使用 AFNetworking。它包装了 NSURLSession 和其他东西。很好。这是我们在工作中使用的:raywenderlich.com/59255/afnetworking-2-0-tutorial
    【解决方案2】:

    为什么 NSURLConnection 不是获取数据的正确方法?你应该小心同步请求。这是一个如何从 url 获取数据的示例。

    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
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-18
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多