Возобновляемая многочастная загрузка файлов с использованием AFNetworking в Objective - C
Я хочу разработать приложение, в котором мне может понадобиться поддержка возобновляемой загрузки файлов. Есть ли способ поддержать возобновляемую загрузку файлов. Пожалуйста, обратите внимание, что я также могу поставить в очередь загрузки файлов.
Я использую AFNetworking. Сервер: IIS.
Если возможно, предоставьте надежное решение. Я открыт для обоих (сервер-клиент) решений.
1 ответ
Для возобновляемых загрузок магия должна идти на стороне сервера. Серверы, которые я использовал для разработки этих загрузок, использовали библиотеку 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
}
}
В основном это все, что вам нужно на вашем клиенте. Затем вам нужно будет установить разные заголовки или тело запроса в зависимости от реализации сервера.