2016-06-29 59 views
8

this question解決方案不再與斯威夫特3.數據寫到NSOutputStream斯威夫特3

作品不再有屬性的Databytes(以前NSData

let data = dataToWrite.first! 
self.outputStream.write(&data, maxLength: data.count) 

有了這個代碼,我得到的錯誤:

Cannot convert value of type 'Data' to expected argument type 'UInt8' 

你怎麼能寫DataNSOutputStream在Swift 3中?

回答

10

NSDatabytes屬性來訪問字節。 Swift 3中新的Data值類型有一個withUnsafeBytes() 方法,它使用指向字節的指針調用閉包。

因此,這是怎麼寫的DataNSOutputStream (不含鑄造NSData):

let data = ... // a Data value 
let bytesWritten = data.withUnsafeBytes { outputStream.write($0, maxLength: data.count) } 

注: withUnsafeBytes()是一個通用的方法:

/// Access the bytes in the data. 
/// 
/// - warning: The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure. 
public func withUnsafeBytes<ResultType, ContentType>(_ body: @noescape (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType 

在上面的電話中, ContentTypeResultType都由 編譯器自動推斷出來(如UInt8Int),使得額外的 轉換不必要。

outputStream.write()返回實際寫入的字節數。 一般來說,你應該檢查那個值。如果 寫入操作失敗,則可以爲-1;如果將 寫入套接字,管道或其他具有流量控制的對象,則該值可能小於data.count

0

DataNSData是Swift 3中的兩個獨立類,並且Data不具有bytes屬性。

的解決方案是定義data爲類型NSData

let data: NSData = dataToWrite.first! 
self.outputStream.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length) 

的根據Migrating to Swift 2.3 or Swift 3 from Swift 2.2

The migrator will convert most uses of NSData to the new value type Data. However, there are certain methods on NSData that operate on UnsafeMutablePointer, while the corresponding methods on Data use UnsafeMutablePointer. (For example, NSData.getBytes(:length:) is more accepting than Data.copyBytes(:length:).) As a reminder, the in-memory layout of Swift types is not guaranteed.

3

Martin R,謝謝你的回答。這是完整解決方案的基礎。那就是:

extension OutputStream { 

    /// Write String to outputStream 
    /// 
    /// - parameter string:    The string to write. 
    /// - parameter encoding:    The String.Encoding to use when writing the string. This will default to UTF8. 
    /// - parameter allowLossyConversion: Whether to permit lossy conversion when writing the string. 
    /// 
    /// - returns:       Return total number of bytes written upon success. Return -1 upon failure. 

    func write(_ string: String, encoding: String.Encoding = String.Encoding.utf8, allowLossyConversion: Bool = true) -> Int { 
     if let data = string.data(using: encoding, allowLossyConversion: allowLossyConversion) { 
      var bytesRemaining = data.count 
      var totalBytesWritten = 0 

      while bytesRemaining > 0 { 
       let bytesWritten = data.withUnsafeBytes { 
        self.write(
         $0.advanced(by: totalBytesWritten), 
         maxLength: bytesRemaining 
        ) 
       } 
       if bytesWritten < 0 { 
        // "Can not OutputStream.write(): \(self.streamError?.localizedDescription)" 
        return -1 
       } else if bytesWritten == 0 { 
        // "OutputStream.write() returned 0" 
        return totalBytesWritten 
       } 

       bytesRemaining -= bytesWritten 
       totalBytesWritten += bytesWritten 
      } 

      return totalBytesWritten 
     } 

     return -1 
    } 
} 
2

只要使用這個擴展(SWIFT 4)

extension OutputStream { 
    func write(data: Data) -> Int { 
    return data.withUnsafeBytes { write($0, maxLength: data.count) } 
    } 
} 

而對於InputStream的

extension InputStream { 
    func read(data: inout Data) -> Int { 
    return data.withUnsafeMutableBytes { read($0, maxLength: data.count) } 
    } 
}