标签: nsurlsessiondatatask

NSURLSession for HTTP data task(NSURLSessionDataTask)是否在后台线程中运行,或者我们必须提供队列?

我现在开始使用NSURLSession,NSURLConnection因为它是Apple提供的一种新的优雅API.以前,我曾经NSURLRequestGCD块中调用来在后台执行它.以下是我过去的做法:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSURLRequest *request = [NSURLRequest requestWithURL:
                             [NSURL URLWithString:@"www.stackoverflow.com"]];
    NSURLResponse *response;
    NSError *error;
    NSData *data = [NSURLConnection sendSynchronousRequest:request 
                                         returningResponse:&response 
                                                     error:&error];
    if (error) {
        // handle error
        return;
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        // do something with the data
    });
});
Run Code Online (Sandbox Code Playgroud)

现在,我的使用方法NSURLSession如下:

- (void)viewDidLoad 
{
    [super viewDidLoad];

    /*-----------------*
        NSURLSession
     *-----------------*/

    NSURLSession *session = [NSURLSession sharedSession];

    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:
                                  [NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"] 
                                     completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
{
    NSDictionary *json …
Run Code Online (Sandbox Code Playgroud)

multithreading ios nsurlsession nsurlsessiontask nsurlsessiondatatask

12
推荐指数
1
解决办法
7296
查看次数

NSURLSessionDataTask超时后续请求失败

我正在创建一个NSMutableRequest:

self.req = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0];
Run Code Online (Sandbox Code Playgroud)

超时设置为10秒,因为我不希望用户等待太长时间来获得反馈.之后我创建了一个NSURLSessionDataTask:

NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response;
    if (error) {
        // this is where I get the timeout
    } 
    else if (httpResp.statusCode < 200 || httpResp.statusCode >= 300) {
        // handling error and giving feedback
    } 
    else {
        NSError *serializationError = nil;
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&serializationError];
    }
    [task resume];
}
Run Code Online (Sandbox Code Playgroud)

问题是服务器进入Gateway Timeout并且需要花费很多时间.我收到超时错误并向用户提供反馈,但由于超时错误,以下所有API调用都以相同方式失败.阻止它的唯一方法是杀死应用程序并重新开始.在超时错误后,我应该做些什么来终止任务或连接?如果我没有设置超时并且我等到从服务器收到错误代码,则以下所有调用都能正常工作(但是用户会等待很多!).

我试图取消任务:

NSURLSessionDataTask …
Run Code Online (Sandbox Code Playgroud)

objective-c nsmutableurlrequest ios nsurlsessiondatatask

11
推荐指数
1
解决办法
2376
查看次数

使用NSURLSession自定义NSURLProtocol

我正在尝试实现本教程,该教程使用NSURLConnection实现自定义NSURLProtocol.

https://www.raywenderlich.com/76735/using-nsurlprotocol-swift

它按预期工作,但现在在iOS9中不推荐使用NSURLConnection,我试图将其转换为NSURLSession.

不幸的是,它没有用.

我正在uiwebview中加载一个网站,如果我使用NSURLConnection加载并且一切都按预期工作,则会捕获来自webview的所有http请求,但在使用NSURLSession时则不会.

任何帮助表示赞赏.

这是我的代码

    import UIKit

    class MyProtocol: NSURLProtocol, NSURLSessionDataDelegate, NSURLSessionTaskDelegate, NSURLSessionDelegate {

    //var connection: NSURLConnection!
    var mutableData: NSMutableData!
    var response: NSURLResponse!

    var dataSession: NSURLSessionDataTask!

    override class func canInitWithRequest(request: NSURLRequest) -> Bool {

        if NSURLProtocol.propertyForKey("MyURLProtocolHandledKey", inRequest: request) != nil {
            return false
        }

        return true
    }

    override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest {
        return request
    }

    override class func requestIsCacheEquivalent(aRequest: NSURLRequest,
        toRequest bRequest: NSURLRequest) -> Bool {
            return super.requestIsCacheEquivalent(aRequest, toRequest:bRequest)
    }

    override func startLoading() {
        let …
Run Code Online (Sandbox Code Playgroud)

nsurlprotocol ios nsurlsession swift nsurlsessiondatatask

10
推荐指数
3
解决办法
9226
查看次数

NSURLSession HTTP/2内存泄漏

这个My Test案例指出,当使用带有HTTP/2连接的NSURLSession时,存在内存问题.

test1:iOS 9. HTTP/2服务器

我使用NSURLSession将10M文件上传到HTTP/2服务器,如果上传的文件完成一切正常,但如果我在完成之前取消上传任务,10M将永远不会释放.

test2:iOS 9. HTTPs1.1服务器

我用https1.1文件服务器测试相同的代码,我是否取消上传任务,一切正常,内存恢复正常.(10M数据发布)

test3 iOS 8. HTTP/2服务器

这种情况一切正常.(NSURLSession没有协议协商到HTTP/2)

所以,即使有一些不适合我使用NSURLSession的东西,NSURLSession的性能也不适用于HTTP/2.

除了内存问题,当使用带有HTTP/2的NSURLSession上传文件时,进度段大小是巨大的(一次回调可能是5M'addSendBodyData')

我也读过这个页面.SSL可能会缓存一些东西,但不应该缓存整个文件.(当我取消任务或请求超时时,10M文件大小的内存泄漏)

任何人都知道导致问题的原因,可以给我一些帮助.谢谢.


问题更新0912:添加测试项目链接

测试项目:https://github.com/upyun/swift-sdk/tree/testleak

file:UPUtils.swift
//Change the url to make comparison test. 

//let DEFAULT_UPYUN_FORM_API_DOMAIN = "http://v0.api.upyun.com"//http1.1
//let DEFAULT_UPYUN_FORM_API_DOMAIN = "https://httpbin.org/post" //https1.1
let DEFAULT_UPYUN_FORM_API_DOMAIN = "https://v0.api.upyun.com"//http2
Run Code Online (Sandbox Code Playgroud)

memory-leaks ios nsurlsession http2 nsurlsessiondatatask

10
推荐指数
1
解决办法
424
查看次数

NSMutableURLRequest setTimeoutInterval在ios 11.0中不起作用

我正在使用URL后台会话将pdf上传作为数据流,使用ios版本> 9.0.我将超时间隔设置为300秒.它根本不起作用.10秒后,它会出现超时错误.

下面给出了一段代码

  NSTimeInterval reqTimeInterval = 300.0f;

- (NSURLSession *)uploadSessionForMrNo:(NSString *)mrNo
                            userRoleId:(NSString *)userRoleId
                             timestamp:(NSString *)timestamp {

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = 4;

    NSString *backgroundSessionIdentifier = [NSString stringWithFormat:@"backgroundPdfUploadIdentifier_%@",mrNo];

    NSURLSessionConfiguration *backgroundSession = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:backgroundSessionIdentifier];
    backgroundSession.discretionary = true;

    NSURLSession *session = [NSURLSession sessionWithConfiguration:backgroundSession delegate:self delegateQueue:queue];

    [session setAccessibilityLabel:mrNo];
    [session setAccessibilityValue:userRoleId];
    [session setAccessibilityHint:timestamp];

    return session;
}


- (void)uploadPdfRequest:(NSURLRequest *)request
                 forMrNo:(NSString *)mrNo
              userRoleId:(NSString *)userRoleId
             andTimestamp:(NSString *)timestamp {

    NSURLSession *session = [self uploadSessionForMrNo:mrNo userRoleId:userRoleId timestamp:timestamp];
    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request];
    NSLog(@"postDataTask %@ timeout %f",postDataTask,request.timeoutInterval); …
Run Code Online (Sandbox Code Playgroud)

objective-c nsurlsession nsurlsessiondatatask ios11

8
推荐指数
1
解决办法
638
查看次数

下载前获取 AVAssetDownloadTask 的大小

我目前正在使用 FairPlay 流实现离线流。因此,我正在使用AVAssetDownloadTask.

我想向用户提供有关开始下载的大小的反馈:

您确定要下载此流吗?下载需要 2.4GB,您目前还有 14GB 的空间

我已经检查过类似countOfBytesReceived和的属性,countOfBytesExpectedToReceive但这些不会返回正确的值。

let headRequest = NSMutableURLRequest(URL: asset.streamURL)
headRequest.HTTPMethod = "HEAD"
let sizeTask = NSURLSession.sharedSession().dataTaskWithRequest(headRequest) { (data, response, error) in
    print("Expected size is \(response?.expectedContentLength)")
}.resume()
Run Code Online (Sandbox Code Playgroud)

打印大小为 2464,最后大小为 3GB。

在下载过程中,我记录了上述属性:

func URLSession(session: NSURLSession, assetDownloadTask: AVAssetDownloadTask, didLoadTimeRange timeRange: CMTimeRange, totalTimeRangesLoaded loadedTimeRanges: [NSValue], timeRangeExpectedToLoad: CMTimeRange) {
    print("Downloaded \( convertFileSizeToMegabyte(Float(assetDownloadTask.countOfBytesReceived)))/\(convertFileSizeToMegabyte(Float(assetDownloadTask.countOfBytesExpectedToReceive))) MB")
}
Run Code Online (Sandbox Code Playgroud)

但这些保持为零:

已下载 0.0/0.0 MB

fairplay nsurlsession nsurlsessiondatatask avassetdownloadtask

7
推荐指数
1
解决办法
1421
查看次数

重试URLSession dataTask的模式?

我是iOS/Swift开发的新手,我正在开发一个向REST API提出多个请求的应用程序.以下是检索"消息"的其中一个调用的示例:

func getMessages() {

    let endpoint = "/api/outgoingMessages"

    let parameters: [String: Any] = [
        "limit" : 100,
        "sortOrder" : "ASC"
    ]

    guard let url = createURLWithComponents(endpoint: endpoint, parameters: parameters) else {
        print("Failed to create URL!")
        return
    }

    do {
        var request = try URLRequest(url: url, method: .get)

        let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in

            if let error = error {
                print("Request failed with error: \(error)")
                // TODO: retry failed request
            } else if let …
Run Code Online (Sandbox Code Playgroud)

ios nsurlsession swift nsurlsessiondatatask retry-logic

7
推荐指数
2
解决办法
4324
查看次数

NSURLSessionTask.暂停不起作用

这就是Apple的文档中关于课程suspend方法的说法NSURLSessionTask

任务暂停时不会产生网络流量,也不会超时.

好.所以我运行以下简单代码:

        let url   = NSURL(string: "http://httpbin.org/delay/10")!
        let urlRequest = NSURLRequest(URL: url)

        self.task = NSURLSession.sharedSession().dataTaskWithURL(urlRequest.URL!, completionHandler: {

            data, response, error in print("completion ERROR \(error)")
        })

        self.task.resume()

        print("Start")
        delay(5, closure: {

            self.task.suspend()

            print("Suspend")
        })
Run Code Online (Sandbox Code Playgroud)

函数delay只是一个包装器dispatch_after,请求http://httpbin.org/delay/10在10秒后给出响应.在等待响应的过程中,我暂停了任务.然而,这不起作用.在60秒内,将调用完成块并显示超时错误.任何人都可以解释一下是什么问题吗?

ios nsurlsession swift nsurlsessiondatatask

6
推荐指数
1
解决办法
1593
查看次数

在 Swift 中,如何从 UrlSession 获取错误类型

我的网络逻辑中有以下代码:

let task = urlSession.dataTask(with: request) { [weak self] (data, response, error) in
  
  if let error = error {        
    if error.localizedDescription.contains("The request timed out") {
      // request timeout stuff ...
    } else {
      // other errors
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

字符串匹配localizedDescription不是好的代码实践。如何像 in 子句一样获取错误的类型catch

ios nsurlsession swift nsurlsessiondatatask urlsession

6
推荐指数
1
解决办法
4272
查看次数

如何告诉主线程 URLSessionDataTask 已经完成

使用 Swift 4,我有以下代码尝试向 REST API 发出 POST 请求:

spinner.startAnimation(self)
btnOk.isEnabled = false
btnCancel.isEnabled = false

attemptPost()

spinner.stopAnimation(self)
btnOk.isEnabled = true
btnCancel.isEnabled = true
Run Code Online (Sandbox Code Playgroud)

执行此操作的函数(Constants并且Request是我创建的用于创建请求对象并保存常用数据的类):

func attemptPost() {
    let url = Constants.SERVICE_URL + "account/post"
    let body: [String : Any] =
        ["firstName": txtFirstName.stringValue,
        "lastName": txtLastName.stringValue,
        "email": txtEmail.stringValue,
        "password": txtPassword.stringValue];
    let req = Request.create(urlExtension: url, httpVerb: Constants.HTTP_POST, jsonBody: body)
    let task = URLSession.shared.dataTask(with: req) { data, response, err in
        guard let data = data, err == nil else { …
Run Code Online (Sandbox Code Playgroud)

multithreading nsurlsession swift nsurlsessiondatatask

5
推荐指数
1
解决办法
3088
查看次数