Запись строки в NSOutputStream в Swift
Я пытаюсь написать String
в NSOutputStream
в Swift. Написание строк таким образом с Objective C обычно работает, передавая его как NSDatap >
NSData *data = [[NSData alloc] initWithData:[mystring dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
Это не работает с быстрым
var data: NSData = mystring.dataUsingEncoding(NSUTF8StringEncoding)!
outputStream.write(data, maxLength: data.length)
это дает ошибку
'NSData' не конвертируется в 'UnsafePointer'
для строки, которая записывает данные в поток.
Как вы напишете String для NSOutputStream в Swift?
Ответы
Ответ 1
Здесь есть две проблемы. Во-первых, вы передаете data
в outputStream.write()
, а не data.bytes
(например, вы прошли [data bytes]
в коде Objective-C). Вторая проблема заключается в том, что data.bytes
возвращает UnsafePointer<Void>
, но NSOutputStream.write()
принимает UnsafePointer<UInt8>
. К счастью, UnsafePointer
имеет способ конвертировать между типами:
/// Convert from a UnsafePointer of a different type.
///
/// This is a fundamentally unsafe conversion.
init<U>(_ from: UnsafePointer<U>)
Объединение этих вещей делает ваш код похожим на это:
let data: NSData = mystring.dataUsingEncoding(NSUTF8StringEncoding)!
outputStream.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
Ответ 2
В недавнем Swift это должно быть еще проще, и NSData больше не требуется.
let s = "String to encode"
let encodedDataArray = [UInt8](s.utf8)
outputstream.write(encodedDataArray, maxLength: encodedDataArray.count)
Массивы могут быть доступны как буферы правильного их типа (см. withUnsafeBufferPointer
). Я думаю, что массив необходим, потому что представление utf8 фактически не создается как полный массив, а просто представление в исходную строку.
В производственном коде вы должны проверить возвращаемое значение записи в выходной поток, и в зависимости от проверки вашего сценария есть место перед записью, но фокус этого ответа - это кодировка строки Swift, чтобы она могла быть записана.
Ответ 3
Надеюсь, что этот пример поможет. Он записывает строку в каталог документов. Обратите внимание, что outputStream тестируется с использованием Swift 1.1 с отказоустойчивым инициализатором.
var myString = "Hello world!"
var docPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
var path = docPath.stringByAppendingPathComponent("doc")
var outputStream = NSOutputStream(toFileAtPath: path, append: false)
var data: NSData = myString.dataUsingEncoding(NSUTF8StringEncoding)!
var buffer = [UInt8](count:data.length, repeatedValue:0)
data.getBytes(&buffer)
outputStream?.open()
outputStream?.write(&buffer, maxLength: data.length)
outputStream?.close()
Привет