我想开发一个可能需要支持可恢复文件上传的应用程序。有没有办法支持可恢复的文件上传。请注意,我也可能排队文件上传。
我正在使用 AFNetworking。服务器:IIS。
如果可能,请提供一个强大的解决方案。我对两种(服务器 - 客户端)解决方案都持开放态度。
我想开发一个可能需要支持可恢复文件上传的应用程序。有没有办法支持可恢复的文件上传。请注意,我也可能排队文件上传。
我正在使用 AFNetworking。服务器:IIS。
如果可能,请提供一个强大的解决方案。我对两种(服务器 - 客户端)解决方案都持开放态度。
对于可恢复的上传,魔术必须在服务器端进行。我用于开发此上传的服务器使用的是 tusd 库https://github.com/tus/tusd
很抱歉,在服务器端我无法为您提供更多帮助。
在 iOS 上你只需要实现三个 HTTP 请求
用于生成文件标识符的 HTTP 请求。您应该检索文件的标识符并将其与您的文件相关联(例如在核心数据中)。
传递文件标识符的 HTTP GET 请求以查找文件的偏移量(服务器上接收到的文件的最后一个字节)。
上传文件的 HTTP POST 请求。如果您正在处理大文件,则必须使用 NSInputStream 才能不分配内存。
func uploadFileStream(file: MyFileClass, fileStream: NSInputStream){
self.initialOffset = Double(file.offset)
self.currentFile = file
self.fileStream = fileStream
let url = NSURL(string: self.file.url)!
var error: NSError?
let request = NSMutableURLRequest(URL: url, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.addValue(file.identifier, forHTTPHeaderField: Constants.HEADER_FILE_IDENTIFIER)
request.addValue(Constants.CONTENT_TYPE_DEFAULT, forHTTPHeaderField: Constants.HEADER_FILE_CONTENT_TYPE)
var task = session.uploadTaskWithStreamedRequest(request)
fileStream.open()
currentTask = task
task.resume()
}
你还必须实现 NSURLSessionTaskDelegate 来为 streamRequest 提供一个 Body:
func URLSession(session: NSURLSession, task: NSURLSessionTask, needNewBodyStream completionHandler: (NSInputStream!) -> Void) {
if let stream = self.fileStream{
// set the current offset as the starting point of the stream
stream.setProperty(Int(self.currentFile.offset), forKey: NSStreamFileCurrentOffsetKey)
// Set the stream as the request body
completionHandler(stream)
}
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
// Save current offset in database. This offset only indicates the amount of bytes sent, not the received in server.
let currentOffset = Double(self.initialOffset + Double(totalBytesSent))
FilesDAO.saveOffset(fromFile: self.currentFile, offset: currentOffset)
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?){
if let err = error{
// An error ocurred. You can retry the process of uploading
}else{
// The file was uploaded successfully
}
}
基本上,这就是您的客户所需要的一切。然后,您将不得不根据服务器实现设置不同的标头或请求正文