Fehler („'()' ist nicht identisch mit ‚UInt8‘“) beim Schreiben von NSData-Bytes in NSOutputStream mithilfe der Schreibfunktion in Swift

StackOverflow https://stackoverflow.com//questions/25080661

  •  02-01-2020
  •  | 
  •  

Frage

Ich versuche, einen asynchronen Dateidownload in Swift basierend auf zu erstellen Erica Saduns Methode.Aber ich brauche es, um größere Dateien zu verarbeiten, also habe ich es gefunden Diese Antwort über die Verwendung eines NSOutputStream anstelle von NSData, macht Sinn.

Allerdings bekomme ich es nicht zum Laufen.Ich erhalte diese Fehlermeldung, wenn ich versuche, die NSData-Bytes (in meiner NSURLConnection didReceiveData-Funktion) zur NSOutputStream-Schreibfunktion hinzuzufügen: '()' is not identical to 'UInt8' in dieser Zeile: bytesWritten = self.downloadStream.write(data.bytes, maxLength: bytesLeftToWrite).

data.bytes ist vom Typ ConstUnsafePointer<()> und das .write() Die Funktion erwartet den Typ ConstUnsafePointer<UInt8>, In diesem Sinne macht der Fehler also durchaus Sinn.Aber da ich neu in iOS und natürlich in der Swift-Programmierung bin, kann ich mir nicht vorstellen, wie ich das beheben kann.

Also, wie konvertiere ich das data.bytes: ConstUnsafePointer<()> Zu ConstUnsafePointer<UInt8> alt.das auf eine andere Art und Weise zum Laufen bringen?

Mein didReceiveData Funktion:

func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {

    var bytesLeftToWrite: NSInteger = data.length
    var bytesWritten: NSInteger = 0

    while bytesLeftToWrite > 0 {

        bytesWritten = self.downloadStream.write(data.bytes, maxLength: bytesLeftToWrite)

        if bytesWritten == -1 {

            break

        }

        bytesLeftToWrite -= bytesWritten

        let responseExpectedlenght: NSNumber = NSNumber(longLong: self.downloadResponse!.expectedContentLength)
        let dataLength: NSNumber = NSNumber(long: data.length)

        self.downloadProgressPercentage = ((dataLength / responseExpectedlenght) * 100)

        println("Downloaded: \(self.downloadProgressPercentage)%")

    }

}
War es hilfreich?

Lösung

Sie können den Zeiger mit umwandeln UnsafePointer():

bytesWritten = self.downloadStream.write(UnsafePointer(data.bytes), maxLength: bytesLeftToWrite)

Es gibt auch ein Problem in Ihrer Schreibschleife, weil Sie immer schreibenanfänglich Bytes des Datenobjekts in den Ausgabestream.

Es sollte wahrscheinlich so aussehen (ungetestet):

var bytes = UnsafePointer<UInt8>(data.bytes)
var bytesLeftToWrite: NSInteger = data.length

while bytesLeftToWrite > 0 {
    let bytesWritten = self.downloadStream.write(bytes, maxLength: bytesLeftToWrite)
    if bytesWritten == -1 {
        break // Some error occurred ...
    }

    bytesLeftToWrite -= bytesWritten
    bytes += bytesWritten // advance pointer

    // ...
}

Andere Tipps

Ich würde vorschlagen, dass Sie davon Gebrauch machen enumerateByteRangesUsingBlock, Weil NSData garantiert nicht mehr, dass die zugrunde liegenden Daten in einem einzigen zusammenhängenden Speicherblock gespeichert werden.Zum Beispiel laut der Dokumentation für didReceiveData des NSURLSessionDataDelegate Protokoll:

Weil das NSData Objekt wird oft aus einer Reihe verschiedener Datenobjekte zusammengesetzt, wann immer dies möglich ist NSData'S enumerateByteRangesUsingBlock: Methode zum Durchlaufen der Daten, anstatt die zu verwenden bytes Methode (die die NSData Objekt in einen einzelnen Speicherblock).

So könnten Sie beispielsweise eine Erweiterung vornehmen NSOutputStream das schreibt den Inhalt von a NSData:

extension NSOutputStream {

    /// Write contents of NSData to `NSOutputStream`
    ///
    /// - parameter data:   The `NSData` being written to the stream.
    ///
    /// - returns:          The number of bytes written. In case of error, returns -1.

    func writeData(data: NSData) -> Int {
        var totalBytesWritten = 0

        data.enumerateByteRangesUsingBlock() {
            buffer, range, stop in

            var bytes = UnsafePointer<UInt8>(buffer)
            var bytesWritten = 0
            var bytesLeftToWrite = range.length

            while bytesLeftToWrite > 0 {
                bytesWritten = self.write(bytes, maxLength: bytesLeftToWrite)
                if bytesWritten < 0 {
                    stop.initialize(true)
                    totalBytesWritten = -1
                    return
                }

                bytes += bytesWritten
                bytesLeftToWrite -= bytesWritten
                totalBytesWritten += bytesWritten
            }
        }

        return totalBytesWritten
    }

}

Beachten Sie die Technik zum Stoppen der Aufzählung im Fehlerfall, nämlich stop.initialize(true), erfordert Xcode 6 Beta 4 oder höher.Frühere Versionen von Xcode (und dem zugehörigen Compiler) verwendeten eine umständlichere Konstruktion zum Aktualisieren der booleschen Referenz, um die Aufzählung zu stoppen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top