خطأ ("'() 'ليست متطابقة إلى 'وينت 8'") كتابة بايت نسداتا إلى نسوتبوستريم باستخدام وظيفة الكتابة في سويفت

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

  •  02-01-2020
  •  | 
  •  

سؤال

أحاول إنشاء تنزيل ملف غير متزامن في سويفت بناء على طريقة إيريكا سادون.ولكن أنا في حاجة إليها للتعامل مع ملفات أكبر ، لذلك وجدت هذه الإجابة حول استخدام نسوتبوتستريم بدلا من نسداتا, ، من المنطقي.

ومع ذلك ، لا أستطيع الحصول عليه للعمل.أحصل على هذا الخطأ عندما أحاول إضافة بايت نسداتا (في بلدي نسورلكونكتيون ديدريسيفيداتا وظيفة) إلى وظيفة الكتابة نسوتبوتستريم: '()' is not identical to 'UInt8' في هذا الصف: bytesWritten = self.downloadStream.write(data.bytes, maxLength: bytesLeftToWrite).

data.bytes هو من النوع ConstUnsafePointer<()> و ال .write() تتوقع الوظيفة أن يكون النوع ConstUnsafePointer<UInt8>, ، لذلك بهذا المعنى ، فإن الخطأ منطقي تماما.ولكن بما أنني جديد على دائرة الرقابة الداخلية وبالطبع البرمجة السريعة ، لا أستطيع الحصول على رأسي حول كيفية إصلاح هذا.

لذلك ، كيف يمكنني تحويل data.bytes: ConstUnsafePointer<()> إلى ConstUnsafePointer<UInt8> البديل.جعل هذا العمل بطريقة أخرى?

بلدي didReceiveData وظيفة:

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)%")

    }

}
هل كانت مفيدة؟

المحلول

يمكنك يلقي المؤشر مع UnsafePointer():

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

هناك أيضا مشكلة في حلقة الكتابة الخاصة بك ، لأنك تكتب دائما الأولي بايت من كائن البيانات إلى دفق الإخراج.

ربما ينبغي أن تبدو مشابهة لهذا (لم تختبر):

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

    // ...
}

نصائح أخرى

أود أن أقترح الاستفادة من نفسك enumerateByteRangesUsingBlock, ، لأن NSData لم يعد يضمن أن البيانات الأساسية سيتم الاحتفاظ بها في كتلة ذاكرة متجاورة واحدة.على سبيل المثال ، وفقا للوثائق الخاصة بـ didReceiveData من NSURLSessionDataDelegate البروتوكول:

لأن NSData غالبا ما يتم تجميع الكائن معا من عدد من كائنات البيانات المختلفة ، كلما أمكن ذلك ، استخدم NSDataفي enumerateByteRangesUsingBlock: طريقة للتكرار من خلال البيانات بدلا من استخدام bytes الطريقة (التي تسطيح NSData كائن في كتلة ذاكرة واحدة).

وهكذا ، على سبيل المثال ، يمكنك القيام بتمديد NSOutputStream أن يكتب محتويات 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
    }

}

ملاحظة ، تقنية إيقاف التعداد في حالة الخطأ ، وهي stop.initialize(true), ، يتطلب كسكودي 6 بيتا 4 أو في وقت لاحق.الإصدارات السابقة من كسكودي (والمترجم المرتبطة بها) تستخدم بناء أكثر حرج لتحديث إشارة منطقية لوقف التعداد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top