2017-04-13 114 views
1

我想將我的nsData解碼爲字符串數組。我現在有這樣的代碼:將nsData解碼爲字符串數組

func nsDataToStringArray(data: NSData) -> [String] { 
      var decodedStrings = [String]() 

      var stringTerminatorPositions = [Int]() 

      var currentPosition = 0 
      data.enumerateBytes() { 
       buffer, range, stop in 

       let bytes = UnsafePointer<UInt8>(buffer) 
       for i in 0 ..< range.length { 
        if bytes[i] == 0 { 
         stringTerminatorPositions.append(currentPosition) 
        } 

        currentPosition += 1 
       } 
      } 

      var stringStartPosition = 0 
      for stringTerminatorPosition in stringTerminatorPositions { 
       let encodedString = data.subdata(with: NSMakeRange(stringStartPosition, stringTerminatorPosition - stringStartPosition)) 
       let decodedString = NSString(data: encodedString, encoding: String.Encoding.utf8.rawValue)! as String 
       decodedStrings.append(decodedString) 
       stringStartPosition = stringTerminatorPosition + 1 
      } 

      return decodedStrings 
     } 

但我得到這一行的錯誤:讓字節= UnsafePointer<UInt8>(buffer)

不能調用類型「UnsafePointer」初始化與類型的 參數列表「( UnsafeRawPointer)'

我是否需要將緩衝區轉換爲UnsafePointer?如果是這樣,我該怎麼做?

回答

2

enumerateBytes()關閉bufferUnsafeRawPointer ,你必須在斯威夫特3「重新綁定」它的UInt8指針:

// let bytes = UnsafePointer<UInt8>(buffer) 
let bytes = buffer.assumingMemoryBound(to: UInt8.self) 

但爲什麼這麼複雜?您可以使用

func nsDataToStringArray(nsData: NSData) -> [String] { 
    let data = nsData as Data 
    return data.split(separator: 0).flatMap { String(bytes: $0, encoding: .utf8) } 
} 

這是如何工作的?

  • DataUInt8一個Sequence,因此
  • split(separator: 0)可以在其上被調用,返回的 「數據切片」(這是視圖到源數據,而不是拷貝)的陣列。
  • 每個「數據片」又是SequenceUInt8,從中可以用String(bytes: $0, encoding: .utf8)創建 String。 這是一個failable初始值設定項(因爲數據可能是無效的UTF-8)。
  • flatMap { ... }返回一個數組,其中包含所有非零結果,即 ,即包含所有字符串的數組,該數組可以從零個字節之間的有效UTF-8代碼序列創建爲 。
+0

在斯威夫特3我寧願簽名'FUNC字符串數組(從NSData的:NSData的)';-) – vadian

+0

@vadian:的確!如果可能的話,或者'func stringArray(來自data:Data)'。 - 我保留這個名字,以便OP可以用他/她的代碼直接測試它。 –

+0

我們不需要討論在Swift 3中濫用過時的'NS ...'基礎類...... – vadian