【问题标题】:how to properly send async request using NSURLSession?如何使用 NSURLSession 正确发送异步请求?
【发布时间】:2015-12-13 22:39:09
【问题描述】:

由于 NSURLConnection 在 iOS 9 中已被弃用,我尝试将我的代码覆盖到 NSURLSession 中,但没有成功。这是我的旧代码:

class Book: NSObject {

    var pfBook : PFObject
    var coverImage : UIImage!

    init(pfBook: PFObject) {
        self.pfBook = pfBook
    }

    func fetchCoverImage(completion: (image: UIImage?, error: NSError?) -> Void) {
        let urlString = self.pfBook["s3thumbnailUrl"] as! String
        let url = NSURL(string: urlString)
        let request = NSURLRequest(URL: url!)
        let queue = dispatch_get_main_queue()

        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response: NSURLResponse?, data: NSData?, error: NSError?) in
            if error == nil {
                dispatch_async(dispatch_get_main_queue()){
                self.coverImage = UIImage(data: data!)
                completion(image: self.coverImage, error: nil)
                }
            } else {
                completion(image: nil, error: error)
            }
        }
    }
}

这是我尝试的新 NSURLSession:

class Book: NSObject {

    var pfBook : PFObject
    var coverImage : UIImage!

    init(pfBook: PFObject) {
        self.pfBook = pfBook
    }

    func fetchCoverImage(completion: (image: UIImage?, error: NSError?) -> Void) {
        let urlString = self.pfBook["s3thumbnailUrl"] as! String
        let url = NSURL(string: urlString)
        let request = NSURLRequest(URL: url!)
        let session = NSURLSession.sharedSession()

        let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
            if error == nil {
                dispatch_async(dispatch_get_main_queue()){
                    self.coverImage = UIImage(data: data!)
                    completion(image: self.coverImage, error: nil)
                }
            }else {
                completion(image: nil, error: error)
            }

        })

        task.resume()
    }
}

当我运行应用程序时,我的调试器只是吐出错误,如下所示:

`2015-09-17 03:05:15.270 MyApp[562:59901] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
2015-09-17 03:05:15.331 My App[562:59936] This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.  This will cause an exception in a future release.
 Stack:(
    0   CoreFoundation                      0x0000000183da4f74 <redacted> + 148
    1   libobjc.A.dylib                     0x0000000198997f80 objc_exception_throw + 56
    2   CoreFoundation                      0x0000000183da4ea4 <redacted> + 0
    3   Foundation                          0x0000000184dbe5d8 <redacted> + 88
    4   Foundation                          0x0000000184c40a1c <redacted> + 36
    5   UIKit                               0x00000001893ff958 <redacted> + 64
    6   UIKit                               0x00000001893ffb9c <redacted> + 548
    7   UIKit                               0x00000001893ff968 <redacted> + 80
    8   UIKit                               0x00000001892f62d8 <redacted> + 240
    9   UIKit                               0x000000018943f35c <redacted> + 640
    10  UIKit                               0x00000001893fc79c <redacted> + 144
    11  UIKit                               0x00000001893fc79c <redacted> + 144
    12  UIKit                               0x00000001893fc6d4 <redacted> + 68
    13  UIKit                               0x00000001893fc228 <redacted> + 120
    14  UIKit                               0x00000001893fc194 <redacted> + 280
    15  UIKit                               0x0000000189400d68 <redacted> + 1048
    16  UIKit                               0x00000001893fcc3c <redacted> + 244
    17  UIKit                               0x0000000189b25e8c <redacted> + 460
    18  UIKit                               0x0000000189b260f4 <redacted> + 200
    19  UIKit                               0x0000000189b25dbc <redacted> + 252
    20  UIKit                               0x0000000189b260f4 <redacted> + 200
    21  UIKit                               0x0000000189b25dbc <redacted> + 252
    22  UIKit                               0x00000001893ff968 <redacted> + 80
    23  UIKit                               0x0000000189b260c8 <redacted> + 156
    24  UIKit                               0x000000018940083c <redacted> + 100
    25  UIKit                               0x00000001893ff968 <redacted> + 80
    26  UIKit                               0x0000000189400470 <redacted> + 244
    27  UIKit                               0x0000000189b2397c <redacted> + 352
    28  UIKit                               0x0000000189af0f24 <redacted> + 200
    29  UIKit                               0x0000000189aefdec <redacted> + 72
    30  UIKit                               0x0000000189aefd88 <redacted> + 48
    31  UIKit                               0x0000000189ad6cf4 <redacted> + 104
    32  UIKit                               0x0000000189ad7264 <redacted> + 1108
    33  UIKit                               0x0000000189ae26f4 <redacted> + 436
    34  UIKit                               0x00000001894dd6f8 <redacted> + 4108
    35  UIKit                               0x0000000189ae4128 <redacted> + 132
    36  UIKit                               0x0000000189309dc0 <redacted> + 80
    37  UIKit                               0x0000000189ae3830 <redacted> + 2656
    38  UIKit                               0x0000000189ae1af8 <redacted> + 12448
    39  UIKit                               0x00000001894d87d8 <redacted> + 364
    40  MyApp                   0x0000000100101934 _TFFC17MyApp29ThirdCollectionViewController14collectionViewFS0_FTCSo16UICollectionView22cellForItemAtIndexPathCSo11NSIndexPath_CSo20UICollectionViewCellU_FTGSqCSo7UIImage_GSqCSo7NSError__T_ + 316
    41  MyApp                   0x00000001000b25fc`
`_TFFC17MyApp4Book15fetchCoverImageFS0_FFT5imageGSqCSo7UIImage_5errorGSqCSo7NSError__T_T_U_FTGSqCSo6NSData_GSqCSo13NSURLResponse_GSqS2___T_ + 580

    2015-09-17 03:05:15.353 MyApp[562:59936] This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.  This will cause an exception in a future release.

我应该调整什么?

【问题讨论】:

  • 您的问题是什么?你的NSURLSession怎么了?
  • 我的调试器@Desdenova 出现大量错误
  • 请分享,以便获得帮助。
  • 检查更新的答案@Desdenova
  • 您得到的是一个安全错误。 errSSLFatalAlert = -9802&lt;Security/SecureTransport.h&gt; 标头中定义。 Check This

标签: ios swift parse-platform nsurlconnection


【解决方案1】:

首先我想提几点,

NSURLConnection 在 OS X 10.11 和 iOS 9.0 中已弃用,但是:

  • 不会消失,使用它的应用仍然可以运行

  • NSURLSession 将添加新功能

  • watchOS 不支持

其次,

使用 NSURLSession 和发送异步调用与使用 NSURLConnection 一样简单。

这是发送异步请求的示例代码。希望对您有所帮助。

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:londonWeatherUrl]
          completionHandler:^(NSData *data,
                              NSURLResponse *response,
                              NSError *error) {
            // handle response

  }] resume]; 

dataTaskWithURL 旨在替换 NSURLConnection 中的 sendAsynchronousRequest

【讨论】:

  • 无论如何你可以创建一个答案来绑定我在我的问题中提供的代码吗?
【解决方案2】:

使用 swift3,

let liveInfoUrl = URL(string: "http://192.168.1.66/api/cloud/app/liveInfo/7777")
let task = URLSession.shared.dataTask(with: liveInfoUrl! as URL) {data, response, error in
    guard let data = data, error == nil else { return }
    print(String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) ?? "aaaa")
}
task.resume()

【讨论】:

    【解决方案3】:

    下面的功能对我来说很好用。

    func fetchCoverImage(completion: (image: UIImage?, error: NSError?) -> Void) {

        //        let url = NSURL(string: urlString)
        var request = NSMutableURLRequest(URL: NSURL(string: "http://www.fnordware.com/superpng/pnggrad16rgb.png")!)
        let session = NSURLSession.sharedSession()
    
        let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
            if error == nil {
                dispatch_async(dispatch_get_main_queue()){
                    self.coverImage?.image = UIImage(data: data!)
                    completion(image: self.coverImage?.image, error: nil)
                }
            }else {
                completion(image: nil, error: error)
            }
    
        })
    
        task.resume()
    }   
    

    }

    如果您在使用它时遇到任何问题,请告诉我。我只是将网址更改为一些 png 图像。

    【讨论】:

    【解决方案4】:

    您的代码可能没有任何问题。如果您针对 iOS 9 SDK 进行编译,NSURLConnection 也会做同样的事情。您遇到了应用传输安全限制。在此处阅读:

    https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/

    基本上,如果你想访问没有强加密的 URL,你必须修改你的 Info.plist 文件来告诉 iOS 让你这样做。

    【讨论】:

      最近更新 更多