本文主要想解决的问题是,当你在前台点击上传文件,当用户进入到后台时你仍然想继续将文件上传完,而不是中断文件上传。如果你是打算直接在后台创建任务,那么会有延时的问题,当任务非常多的时候,靠后的任务延时将会非常严重(参考文章),因此这种情况也不在本文考虑范围内。
-
后台上传需要创建后台session,需要通过一个标识符Identifier,如果你每次只需要上传一个文件,那么你可以创建一个全局的session,所有的文件都可以通过该session创建task上传,文件依次上传即可。如果你需要每次同时上传多个文件,那么可以根据你的需要创建多个session,但是session的Identifier必须不一样,否则运行过程当中会出错。以下代码可创建多个session
//MARK: - 创建后台请求session func creatBackgroundSession(){ let nowDate = Date() let dateFormatter = DateFormatter() dateFormatter.dateFormat = "YYYYMMddHHMMSS" let dateStr = dateFormatter.string(from: nowDate) let randomNum = Int(arc4random()%10000)+1 let configrationIdentifier = "test" + dateStr + String(randomNum) let backgroundSessionConfigration = URLSessionConfiguration.background(withIdentifier: configrationIdentifier) //设置后台上传时的超时timeoutIntervalForResource,默认值为1周 backgroundSessionConfigration.timeoutIntervalForResource = 24*60*60 backgroundSession = URLSession(configuration: backgroundSessionConfigration, delegate: self, delegateQueue: OperationQueue.main) }
-
创建上传的task,urlsession后台上传一定是文件流的形式,而不是数据流的形式,因此除了前端需要注意还应当与后台进行沟通,让他们以接受文件流的形式存储收到的流。
var request = URLRequest(url: URL(string: url )!) request.httpMethod = "POST" let contentType = "multipart/form-data; boundary=\(XYboundary)" request.setValue(contentType, forHTTPHeaderField: "Content-Type") request.addValue("text/html,application/json,text/json", forHTTPHeaderField: "Accept") //创建上传的 let backgroundTask = backgroundSession.uploadTask(with: request, fromFile: URL(fileURLWithPath: filePath)) // 开始下载 backgroundTask.resume()
-
需要实现URLSessionDelegate,URLSessionTaskDelegate,URLSessionDataDelegate等代理方法
func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { //对进度进行监控 } func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { //用来接收上传完成后后台返回的数据 } //MARK: - 上传结束操作,不管是否成功都会调用 func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { //用来处理上传结束流程 } //MARK: - 后台上传完执行代理方法 func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { //如果是在后台上传的还会调用这个方法 }
-
当然,在AppDelegate中你还得实现如下方法
//MARK: - 后台下载上传完成处理 func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) { }
-
如果你想停止上传,那么可以通过如下两种方式结束这个session
-
backgroundSession.finishTasksAndInvalidate()
,这个方法会在完成已开启的task后,结束这个session -
backgroundSession.invalidateAndCancel()
,该方法是立即停止task并结束session
-
这里有一个完整的Demo,参考Demo相信你可以加深理解,如果对你有帮助,给个Star,让更多人可以得到帮助。Demo在这里
本文谢绝转载,如需转载请联系我授权,原创不易,还请理解
iOS通过URLSession进行多文件后台上传
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 概览 缓存组件应该说是每个客户端程序必备的核心组件,试想对于每个界面的访问都必须重新请求势必降低用户体验。但是如何...
- 一.概述 NSURLSession始于ios7.它具有访问接口,上传/下载数据,断点继传和后台下载等功能:其使用步...
- 什么样的访谈,才算成功的?我想对于大部分来说,应该是“有备而来”的吧。接到“采访”的任务,我顿感压力山大。原因有三...