2017-04-13 14 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に変換する必要がありますか?もしそうなら、どうしたらいいですか? enumerateBytes()閉鎖中

答えて

2

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) } 
} 

これはどのように機能しますか?

  • Data従って
  • split(separator: 0)が(ソースデータに図ではなく、コピー) 「データスライス」の配列を返し、それを呼び出すことができ、UInt8Sequenceあります。
  • 各「データスライス」は、で Stringを作成することができるUInt8Sequenceです。 これは有効なイニシャライザです(データが無効なUTF-8である可能性があるため)。
  • flatMap { ... }は、0以外のすべての結果を含む配列 を返します。つまり、ゼロバイト間の有効なUTF-8コードシーケンス から作成できるすべての文字列を含む配列です。
+0

Swift 3では、func stringArray(from nsData:NSData) ';-)を好きです。 – vadian

+0

@vadian:確かに!可能であれば、 'func stringArray(from data:Data)'となります。 - 私はOPが彼/彼女のコードでそれを直接テストできるように名前を保持しました。 –

+0

Swift 3での廃止された 'NS ...'ファンデーションクラスの誤用について話す必要はありません... – vadian