2016-11-22 5 views
0

Also ich habe einige Code, den ich verwendet habe, Dateien in meiner App zu laden, nach dem Vorbild dieser:Hochladen große Dateien über URLSession

var mutableURLRequest = URLRequest(url: url) 
var uploadData = try! Data(contentsOf: dataUrl) 
session.uploadTask(with: mutableURLRequest, from: uploadData).resume() 

ist es ein wenig mehr zu bieten als das, aber die sind die relevanten Teile. Allerdings habe ich festgestellt, dass für einige große Videodateien Data(contentsOf: dataUrl) fehlschlägt, da die Datei zu groß in den Speicher geladen werden soll. Ich möchte das so umstrukturieren, dass ich Stück für Stück zum Server streamen kann, ohne die ganze Datei in den Speicher laden zu müssen.

Ich habe bereits dies von meinem Server herausgefunden, das einzige Stück, das ich nicht herausgefunden habe ist, wie man ein chunkSize Stück aus den Daten in einer URL, ohne es in ein Datenobjekt zu setzen. Ich möchte im Wesentlichen dieses Konstrukt:

let chunkSize = 1024 * 1024 
let offset = 0 
let chunk = //get data from dataUrl of size chunkSize offset by offset 

//Upload each chunk and increment offset 

NSInputStream vielversprechend schien in der Lage zu sein, dies zu tun, aber ich war nicht in der Lage, die Mindest eingerichtet, um herauszufinden, Bytes aus einer Datei auf der Festplatte auf diese Weise zu ziehen. Welchen Code kann ich oben verwenden, um die Zeile let chunk = für eine solche Aufgabe auszufüllen?

+0

Haben Sie 'uploadTask (mit: fromFile:)' versucht? Es könnte schlau genug sein, von der Datei zu streamen, anstatt das Ganze in 'Data' zu laden. Oder vielleicht 'uploadTask (withStreamedRequest:)'. – rmaddy

+0

Ich nehme an, dass das für mich nicht funktionieren wird, da ich jeden Block mit anderem HTTP-Müll dekorieren muss, damit mein Server weiß, was vor sich geht. Aber was immer ich unter den Deckeln verwende, mag das sein, was ich brauche. –

Antwort

0

ich eine funktionierende Lösung haben, könnte ein wenig Gefummel brauchen, scheint aber für große Dateien, die ich versucht habe zu arbeiten:

public func getNextChunk() -> Data?{ 
    if _inputStream == nil { 
     _inputStream = InputStream(url: _url) 
     _inputStream?.open() 
    } 
    var buffer = [UInt8](repeating: 0, count: CHUNK_SIZE) 
    var len = _inputStream?.read(&buffer, maxLength: CHUNK_SIZE) 
    if len == 0 { 
     return nil 
    } 
    return Data(buffer) 
} 

Ich nenne auch _inputStream?.close() auf deinit meiner Klasse, die die Chunking eines verwaltet Datei auf der Festplatte.