iOS:didCompleteWithError、didReceive 响应未由 URLSession.uploadTask 触发
Posted
技术标签:
【中文标题】iOS:didCompleteWithError、didReceive 响应未由 URLSession.uploadTask 触发【英文标题】:iOS: didCompleteWithError, didReceive Response not triggered with URLSession.uploadTask 【发布时间】:2018-12-10 16:51:30 【问题描述】:我想添加一个进度条来准确了解我的视频的上传百分比,但无法调用 didCompleteWithError、didReceive 响应、didSendBodyData bytesSent: Int64、totalBytesSent: Int64、totalB 等...
我很好地添加了委托,但无法发现问题。
@objcMembers open class DAL : NSObject
var response: URLResponse?
var session: URLSession?
var uploadTask: URLSessionUploadTask?
let opQueue = OperationQueue()
static let sharedInstance = DAL()
fileprivate let showLogs = true
var WSURL:String = SERVER_PROTOCOL + DOMAIN_NAME_ADDRESS //"http://localhost:3000"
var eventKey:String = EVENT_TO_USE
在另一个班级:
extension DAL: URLSessionDelegate,URLSessionDataDelegate, URLSessionTaskDelegate
func uploadVideo(_ videoPath: String, fileName: String, eventId: Int, contactId: Int, type: Int, callback: @escaping (_ data:Data?, _ resp:HTTPURLResponse?, _ error:NSError?) -> Void)
// let filePath = video
// let videoFileURL = NSURL(fileURLWithPath: videoPath)
var video_data: NSData?
do
video_data = try NSData(contentsOfFile: (videoPath), options: NSData.ReadingOptions.alwaysMapped)
catch _
video_data = nil
return
let WSURL:String = "https://" + "ren.newp.fr/node"
let requestURLString = "\(WSURL)/regtions/lead/photo//"
let url = URL(string: requestURLString)
#if DEBUG
print(requestURLString)
#endif
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let boundary = generateBoundaryString()
//define the multipart request type
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
let mimetype = "video/mp4"
//define the data post parameter
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"eventId\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(eventId)\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"contactId\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(contactId)\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"type\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(type)\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"file\"; filename=\"\(fileName)\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(video_data! as Data)
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = body as Data
request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")
let config = URLSessionConfiguration.default
self.session = URLSession(configuration: config, delegate: self, delegateQueue: self.opQueue)
let fileUrl = URL(string:"\(videoPath)/\(fileName)")
if let task = session?.uploadTask(with: request as URLRequest, from: video_data! as Data)
task.resume()
private func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
// the task finished
if let err = error
print("Error: \(err.localizedDescription)")
else
print("The upload was successful.")
self.session?.finishTasksAndInvalidate()
// end if
// end func
private func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void)
print("did receive response")
self.response = response
print(self.response!)
completionHandler(URLSession.ResponseDisposition.allow)
// end func
private func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64)
let progress = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
print(progress)
// end func
public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
completionHandler(Foundation.URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
func generateBoundaryString() -> String
return "Boundary-\(UUID().uuidString)"
提前致谢
【问题讨论】:
在您的应用程序中,指向self
的委托指针是否设置为nil
?
不相关但不要在 Swift 中使用 NSMutable..
类。使用var request = URLRequest()
并将body
创建为var body = Data()
并附加body += Data("--\(boundary)\r\n".utf8)
。这个特殊的 Data
初始化器总是返回一个非可选的。
@Aaron Self 的信息不为零
【参考方案1】:
从你的类中移除 open 参数: https://***.com/a/38950955
简而言之:(来自其他帖子)
An open class is accessible and subclassable outside of the defining module. An open class member is accessible and overridable outside of the defining module.
A public class is accessible but not subclassable outside of the defining module. A public class member is accessible but not overridable outside of the defining module.
【讨论】:
哇,它起作用了,所有的委托函数都被触发了。很奇怪,我相信open就是open的意思……以上是关于iOS:didCompleteWithError、didReceive 响应未由 URLSession.uploadTask 触发的主要内容,如果未能解决你的问题,请参考以下文章
NSURLSession GET 请求:DidCompleteWithError - 错误为空
NSURLSessionTaskDelegate 方法 URLSession:task:didCompleteWithError: 从不调用
com.apple.AuthenticationServices.Authorization错误代码1000
NSURLSessionDownloadTask 在后台自动恢复所有任务