Возобновляемая многочастная загрузка файлов с использованием AFNetworking в Objective - C

Я хочу разработать приложение, в котором мне может понадобиться поддержка возобновляемой загрузки файлов. Есть ли способ поддержать возобновляемую загрузку файлов. Пожалуйста, обратите внимание, что я также могу поставить в очередь загрузки файлов.

Я использую AFNetworking. Сервер: IIS.

Если возможно, предоставьте надежное решение. Я открыт для обоих (сервер-клиент) решений.

1 ответ

Для возобновляемых загрузок магия должна идти на стороне сервера. Серверы, которые я использовал для разработки этих загрузок, использовали библиотеку tusd https://github.com/tus/tusd

Извините, но я не могу вам больше помочь на стороне сервера.

На iOS вы должны реализовать только три HTTP-запроса

  1. HTTP-запрос для генерации идентификатора файла. Вы должны получить идентификатор файла и связать его с вашим файлом (например, в основных данных).

  2. HTTP-запрос GET, передающий идентификатор файла, чтобы найти смещение файла (последний байт файла, полученный на сервере).

  3. 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

    }
}

В основном это все, что вам нужно на вашем клиенте. Затем вам нужно будет установить разные заголовки или тело запроса в зависимости от реализации сервера.

Другие вопросы по тегам