我一直在为watchos 2开发一个应用程序,结果发现我的函数使用NSData(contentsOfUrl)下载一些json数据,可能太重,导致应用程序崩溃。我的研究让我相信NSURLSession是一条路要走,但是我很难弄清楚如何转换我的函数,使结果以同样的方式返回。
在我的应用程序中,我有一行let data = myData()。这就叫mydata.swift;

class myData {

   var datas = myData.fetchData()

   class func fetchData() -> [myData] {

        let myURL = "http://www.url.com/json/"

        let dataURL = NSURL(string: myURL)

        var optData:NSData? = nil

        do {
            optData = try NSData(contentsOfURL: dataURL!, options: NSDataReadingOptions.DataReadingMappedIfSafe)
        }
        catch {
            print("Handle \(error) here.")
        }

        var datas = [myData]()

        if let data = optData {

            do {

                let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! NSArray

                for item in json {
                    //Do JSON stuff and
                    //Append to datas array
                    datas.append(dataSet)
                }
            } catch {
                print(error)
            }
        }
        return datas
    }
  }
}

此代码已被稍微截断,但在模拟器中运行时没有问题。但是,在设备上,当调用此代码时,它会崩溃。
这是我将mydata.swift转换为nsurlsession的尝试;
class myData {

    class func fetchData() -> [myData] {

        var task: NSURLSessionDataTask?

        let myURL = "http://www.url.com/json/"

        let dataURL = NSURL(string: myURL)

        let conf = NSURLSessionConfiguration.defaultSessionConfiguration()

        let session = NSURLSession(configuration: conf)

        task = session.dataTaskWithURL(dataURL!) { (data, res, error) in
            if let e = error {
                print("dataTaskWithURL fail: \(e.debugDescription)")
                return
            }


            var datas = [myData]()

            do {

                let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray

                for item in json {
                    //Do JSON stuff
                    //Append to datas array

                    datas.append(dataSet)
                }
            } catch {
                print(error)
            }
            return datas
            //Unexpected return value in non-void function
        }
    }
}

有没有可能有人建议我如何成功地消除错误,以及我如何仍然能够调用let data = myData()并让它以NSData(contentsofUrl)相同的方式返回。我确实理解nsurlsession将需要一个完成处理程序或其他东西,因为它运行在同一个线程上,但我无法理解它!谢谢!

最佳答案

恐怕你不能照你说的做。在传输整个文件之前,contentsOfURL方法不会返回。如果连接速度慢或文件很大,则由于主线程正忙,ui将冻结。只对本地文件使用该方法。
看来你的第二次尝试有两个问题:
首先,出于安全原因,默认情况下只能加载安全(https:)url。请参阅此注释:https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/
其次,dataTaskWithURL不会启动传输;在您指示datatask通过调用task.resume()启动之前,它不会执行任何操作。传输完所有数据后,闭包代码将由另一个线程执行。这就是为什么不能返回值。
您仍然可以创建数据数组,但需要将声明移到类的顶层。记住闭包是由不同的线程执行的,所以您需要从闭包中引用数组作为self.datas
如果需要在闭包中加载数据后更新ui元素,则需要通过主线程发出更新。要强制表与新数据一起显示,可以将其添加到闭包的末尾:
self.myTable.performSelectorOnMainThread( "reloadData", withObject: nil, waitUntilDone: false)

关于swift - 将NSData(contentsOfUrl)转换为NSURLSession吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32500715/

10-14 23:36