Saya menghadapi masalah saat mengubah UInt8
Byte array ke string dengan cepat. Aku telah mencari dan menemukan sebuah solusi sederhana
String.stringWithBytes(buff, encoding: NSUTF8StringEncoding)
tapi itu menunjukkan kesalahan String.jenis
tidak memiliki anggota stringWithBytes
. Siapa pun dapat menyarankan saya solusi ?
ini kode saya di mana saya mendapatkan sebuahNSData
dan diubah menjadi byte array dan kemudian saya harus mengubah byte array ke string.
let count = data.length / sizeof(UInt8)
var array = [UInt8](count: count, repeatedValue: 0)
data.getBytes(&array, length:count * sizeof(UInt8))
String.stringWithBytes(buff, encoding: NSUTF8StringEncoding)
Update Swift 3/Xcode 8:
String dari bytes: [UInt8]
:
if let string = String(bytes: bytes, encoding: .utf8) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}
String dari data: Data
:
let data: Data = ...
if let string = String(data: data, encoding: .utf8) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}
Update Swift 2/Xcode 7:
String dari bytes: [UInt8]
:
if let string = String(bytes: bytes, encoding: NSUTF8StringEncoding) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}
String dari data: NSData
:
let data: NSData = ...
if let str = String(data: data, encoding: NSUTF8StringEncoding) {
print(str)
} else {
print("not a valid UTF-8 sequence")
}
Jawaban sebelumnya:
String
tidak memiliki stringWithBytes()
metode.
NSString
memiliki
NSString(bytes: , length: , encoding: )
metode yang dapat anda gunakan, tetapi anda dapat membuat string langsung dari NSData
, tanpa perlu sebuah UInt8
array:
if let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String {
println(str)
} else {
println("not a valid UTF-8 sequence")
}
Bagi siapa saja yang tidak bisa mengubah array dari byte ke String, coba ini
String(data: Data(decrypted), encoding: .utf8)
Ini adalah contoh string ekstensi. Saya menggunakannya untuk AES
extension String {
func decryptAES(key: String, iv: String) -> String {
do {
let encrypted = self
let key = Array(key.utf8)
let iv = Array(iv.utf8)
let aes = try AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding)
let decrypted = try aes.decrypt(Array(hex: encrypted))
return String(data: Data(decrypted), encoding: .utf8) ?? ""
} catch {
return "Error: \(error)"
}
}
}
Martin R di https://stackoverflow.com/a/29644387/2214832 menjawab Sunil Kumar pada masalahnya tetapi tidak pada topik pertanyaan. Masalah masih muncul jika anda sudah memiliki UInt8 byte array dan perlu untuk hadir sebagai string.
Berikut ini adalah solusi saya:
extension String {
init(_ bytes: [UInt8]) {
self.init()
for b in bytes {
self.append(UnicodeScalar(b))
}
}
}
Dengan ekstensi ini, anda sekarang dapat init String dengan UInt8 byte array seperti itu:
func testStringUInt8Extension() {
var cs : [UInt8] = []
for char : UInt8 in 0..<255 {
cs.append(char)
}
print("0..255 string looks like \(String(cs)))")
}
Ini bukan solusi yang ideal karena praktis anda akan perlu untuk men-decode sesuatu seperti UTF-8 teks. Tapi untuk data ASCII ini bekerja seperti yang diharapkan.
Swift 3
berikut ini adalah memberikan saya sebuah kesalahan karena "NSUTF8StringEncoding":
String(data: nsdata, encoding: NSUTF8StringEncoding)!
ini bekerja untuk saya di swift 3:
let xmlStr:String = String(bytes: data!, encoding: String.Encoding.utf8)!
Sangat tidak elegan atau 'Swifty', tapi ini lebih sederhana dan bekerja:
let i: UInt8 = 65
let s = String(format: "%c", i) // A
Aku menghabiskan berjam-jam mencari cara mudah untuk melakukan hal ini, sebelum saya tiba-tiba berpikir 'printf' dari Unix scripting hari!
Berikut adalah beberapa yang lebih umum kode untuk mengekstrak string dari byte array dimana string yang telah dikodekan dalam UTF-8.
/// Class which encapsulates a Swift byte array (an Array object with elements of type UInt8) and an
/// index into the array.
open class ByteArrayAndIndex {
private var _byteArray : [UInt8]
private var _arrayIndex = 0
public init(_ byteArray : [UInt8]) {
_byteArray = byteArray;
}
/// Method to get a UTF-8 encoded string preceded by a 1-byte length.
public func getShortString() -> String {
return getTextData(getUInt8AsInt())
}
/// Method to get a UTF-8 encoded string preceded by a 2-byte length.
public func getMediumString() -> String {
return getTextData(getUInt16AsInt())
}
/// Method to get a UTF-8 encoded string preceded by a 4-byte length. By convention a length of
/// -1 is used to signal a String? value of nil.
public func getLongString() -> String? {
let encodedLength = getInt32()
if encodedLength == -1 {
return nil
}
return getTextData(Int(encodedLength))
}
/// Method to get a single byte from the byte array, returning it as an Int.
public func getUInt8AsInt() -> Int {
return Int(getUInt8())
}
/// Method to get a single byte from the byte array.
public func getUInt8() -> UInt8 {
let returnValue = _byteArray[_arrayIndex]
_arrayIndex += 1
return returnValue
}
/// Method to get a UInt16 from two bytes in the byte array (little-endian), returning it as Int.
public func getUInt16AsInt() -> Int {
return Int(getUInt16())
}
/// Method to get a UInt16 from two bytes in the byte array (little-endian).
public func getUInt16() -> UInt16 {
let returnValue = UInt16(_byteArray[_arrayIndex]) |
UInt16(_byteArray[_arrayIndex + 1]) << 8
_arrayIndex += 2
return returnValue
}
/// Method to get an Int32 from four bytes in the byte array (little-endian).
public func getInt32() -> Int32 {
return Int32(bitPattern: getUInt32())
}
/// Method to get a UInt32 from four bytes in the byte array (little-endian).
public func getUInt32() -> UInt32 {
let returnValue = UInt32(_byteArray[_arrayIndex]) |
UInt32(_byteArray[_arrayIndex + 1]) << 8 |
UInt32(_byteArray[_arrayIndex + 2]) << 16 |
UInt32(_byteArray[_arrayIndex + 3]) << 24
_arrayIndex += 4
return returnValue
}
// Method to decode UTF-8 encoded text data in the byte array.
private func getTextData(_ numberBytes : Int) -> String {
if numberBytes == 0 {
return "" // Tiny optimization?
}
let startIndex = _arrayIndex
_arrayIndex += numberBytes
return String(bytes: _byteArray[startIndex ..< _arrayIndex], encoding: String.Encoding.utf8)!
}
}
Ini adalah ekstrak dari kelas yang lebih besar (lihat juga https://stackoverflow.com/a/41547936/253938 ) yang saya gunakan untuk proses serial data.
"MSString(bytes: , panjang: , encoding: )" tidak muncul untuk bekerja pada juli 26, 2015
Mengubah nilai byte ASCII tampaknya bermasalah, jika anda menabrak dinding, anda dapat melakukannya dengan cara yang keras sebagai berikut (dan mungkin aku kehilangan sesuatu dengan cepat tapi aku tidak't menemukan solusi dalam rentang waktu.) Hal ini akan dilakukan dengan dua fungsi. Fungsi pertama yang menerima UInt8 dan mengubah bahwa untuk "\u{}" representasi, yang kemudian dikembalikan oleh fungsi. Kedua, fungsi lain adalah set up yang diperlukan dalam UInt8 array sebagai parameter, maka output string.
Langkah #1. Fungsi yang mengkonversi setiap byte untuk "\u{someNumber"
func convertToCharacters(#UInt8Bits : UInt8) -> String {
var characterToReturn : String
switch UInt8Bits{
case 0x00: characterToReturn = "\u{0}"
case 0x01: characterToReturn = "\u{1}"
case 0x02: characterToReturn = "\u{2}"
case 0x03: characterToReturn = "\u{3}"
case 0x04: characterToReturn = "\u{4}"
//.. Add untuk banyak karakter yang anda mengantisipasi...don't melupakan basis 16..
case 0x09: characterToReturn = "\u{09}"
case 0x0A: characterToReturn = "\u{0A}"
default: characterToReturn = "\u{0}"
/.. dan semua jalan sampai ke 0xff /
case 0xFE: characterToReturn = "\u{FE}"
case 0xFF: characterToReturn = "\u{FF}"
}
kembali characterToReturn
}
Langkah #2 ...Selanjutnya fungsi yang diperlukan dalam UInt8 array sebagai parameter kemudian mengembalikan string...
func UInt8ArrayToString(#UInt8Array: [UInt8]) -> String {
var returnString : String = ""
untuk eachUInt8Byte di UInt8Array {
returnString += convertToCharacter(UInt8Bits: eachUInt8Byte)
}
kembali returnString
}
Ini harus bekerja secara Cepat Bermain anak Membuat sebuah array
var myArray : [UInt8] = [0x30, 0x3A, 0x4B]
//Kemudian menerapkan fungsi-fungsi di atas
println(UInt8ArrayToString(UInt8Array: myArray))
Anda perlu mengkonversi Int8 array untuk Data pertama, kemudian dikonversi ke String.
Ini adalah solusi saya:
var buffer = [Int8](repeating: 0, count: 100)
let data = Data(bytes: buffer as [Int8], count: buffer.count);
return String( data: data, encoding: .utf8)
Swift 4 / Ubuntu 16.04
let serverAns = [UInt8](repeating: 0x50, count: 100)
let readBytes = 8
let truncatedServerAns = serverAns[0..<readBytes]
let tsaData = Data(bytes: truncatedServerAns)
let serverIdStr = String(data: tsaData, encoding: .utf8)
print("serverIdStr=\(String( describing: serverIdStr))")
// Prints:
// serverIdStr=Optional("PPPPPPPP")