Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSURLSessionTaskDelegate方法URLSession:task:DidCompleteWither错误:从未调用_Ios_Objective C_Nsurlsession - Fatal编程技术网

Ios NSURLSessionTaskDelegate方法URLSession:task:DidCompleteWither错误:从未调用

Ios NSURLSessionTaskDelegate方法URLSession:task:DidCompleteWither错误:从未调用,ios,objective-c,nsurlsession,Ios,Objective C,Nsurlsession,我所有的网络代码都依赖于NSURLSession委托方法,而不是完成处理程序。我的数据和下载任务都很好,但我的上传任务从来不会导致 URLSession:task:didcompletewitheror:正在调用。但是, 调用URLSession:dataTask:didReceiveData:和URLSession:dataTask:willCacheResponse:completionHandler:委托方法 如果我在会话对象上将资源超时设置为一个非常低的值,则会调用didpletewit

我所有的网络代码都依赖于NSURLSession委托方法,而不是完成处理程序。我的数据和下载任务都很好,但我的上传任务从来不会导致
URLSession:task:didcompletewitheror:
正在调用。但是, 调用
URLSession:dataTask:didReceiveData:
URLSession:dataTask:willCacheResponse:completionHandler:
委托方法

如果我在会话对象上将资源超时设置为一个非常低的值,则会调用
didpletewitherrs
,但这显然不是一个解决方案

有什么想法吗?我快疯了


谢谢。

如果实现了
willCacheResponse
,您将看不到调用了
didcompletewitheror
,但是如果实现未能实际调用
completionHandler
。您必须调用
completionHandler


提供
completionHandler
参数(例如身份验证质询、重定向等)的任何和所有
NSURLSession
委托方法也是如此。如果实现了这些方法,则必须确保调用了
completionHandler

Rob的回答是正确的,并给了我一个很大的线索。然而,对于我的具体问题,我没有意识到为什么不调用
NSURLSessionTaskDelegate
方法。如果我可以提供另一个不同重点的答案

许多
NSURLSession
任务创建方法有两种变体;一个带有
completionHandler
参数,另一个没有

例如:

func dataTaskWithRequest(_ request: NSURLRequest) -> NSURLSessionDataTask

func dataTaskWithRequest(_ request: NSURLRequest, completionHandler completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask
如果使用了
completionHandler
方法,则将忽略任何委托方法(在本例中为
NSURLSessionTaskDelegate
)。尽管在
NSURLSession
initialiser中指定了一个委托,但仍然存在这种情况

下面的代码演示了这一点。切换
任务
声明注释以查看是否调用了代理:

import UIKit
import XCPlayground

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true


class MyDelegate:NSObject, NSURLSessionTaskDelegate
{
    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        NSLog("Delegate called")
    }
}


let myDel = MyDelegate()
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config, delegate: myDel, delegateQueue: NSOperationQueue())
let url = NSURL(string: "http://httpbin.org")
let request: NSURLRequest = NSURLRequest(URL: url!)

// With completionHandler, delegate method above NOT called
let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
        NSLog("Task done")
})

// Without completionHandler, delegate method above IS called
//let task : NSURLSessionDataTask = session.dataTaskWithRequest(request)

task.resume()

TLDR:发疯想知道为什么不调用
NSURLSession
的委托方法?使用替代方法签名创建会话任务省略completionHandler参数的

在这里展开另一个答案,将调用
完成处理程序委托方法的状态

与大多数网络API一样,NSURLSession API也是高度异步的。它以两种方式之一将数据返回到应用程序,具体取决于您调用的方法:

  • 传输成功完成或出现错误时调用的完成处理程序块

  • 通过在接收数据和传输完成时调用会话委托上的方法

关于这个问题的一个更具体的问题是:


我解决了这个问题,就像在
willCacheResponse
函数中添加
completionHandler
一样

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse *__nullable cachedResponse))completionHandler {

    NSLog(@"%s", __FUNCTION__);
    completionHandler(proposedResponse);
}

在这种情况下,有人可能希望检查的另一种可能性是,您的URLSession委托方法没有标记为private。如果是,则不会调用这些方法。。。如果将修饰符保留在方法之外,然后在警告中使用“自动修复”来修复方法的修饰符(使其成为私有的),那么这很容易意外地做到

方法签名应为:

public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) 

非常感谢。我知道一定是这样的小事。在发布我的问题后,我注意到我的一些数据和下载任务也遇到了同样的问题。我猜short&sweet单元测试并不总是遇到同样的问题,这实际上使它成为一个更糟糕的问题,而且(似乎)没有文档记录。在为苹果的文档辩护时,它说,“如果你的委托实现了这个方法,它必须调用这个完成处理程序”(原始文档中的重点)。如果不调用此
completionHandler
(更糟糕的是,文档描述了将导致泄漏,但忽略了承认可能出现的更广泛的问题),它无法准确地说明将发生什么,但在他们的辩护中,他们相当明确地表示必须调用完成处理程序。但是我感觉到了你的痛苦:我知道这个问题的唯一原因是我自己也经历过。完成处理程序块没有引用委托方法中使用的
(NSURLSessionTask*)任务
参数。如果没有代理的
任务
,如何从块内重试任务?顺便说一下,这个答案是正确的…`
uploadTaskWithRequest:fromData:
点击委托方法,但
uploadTaskWithRequest:fromData:completionHandler:
不点击。在我的情况下,即使我没有使用completionHandler方法,也不会调用委托回调。您好@mph您如何设置此任务委托?事实上,我正面临一些问题,而这些代表没有接到电话。或“open func”-今天这对我来说有点小意思,感谢你给出了“正确”的答案,尽管其他问题也是完全正确的。打倒代理模式@蛇油关于开放性是有效的,只是一些可以看到的东西!很高兴它能帮上忙,因为这让我困惑了一段时间!就是这样。编译器没有警告我它们需要公开。但奇怪的是,有些委托函数被调用了。