2015-04-15 14 views
20

Ho riscontrato problemi durante la conversione di UInt8 Byte array in string in swift. Ho cercato di trovare una soluzione sempliceCome convertire l'array di byte UInt8 in stringa in Swift

String.stringWithBytes(buff, encoding: NSUTF8StringEncoding) 

ma sta mostrando errore String.type non ha uno stringWithBytes membri. Qualcuno mi può suggerire una soluzione?

questo è il mio codice in cui sto ricevendo un NSData e convertito in array di byte e quindi devo convertire quell'array di byte in stringa.

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) 
+0

http://stackoverflow.com/a/24465772/986169 Questo potrebbe aiutare a – giorashc

+0

Oppure provate http : //stackoverflow.com/questions/25554986/how-to-convert-string-to-unsafepointeruint8-and-length – emrys57

risposta

34

Aggiornamento per Swift 3/Xcode 8:

if let string = String(data: data, encoding: .utf8) { 
    print(string) 
} else { 
    print("not a valid UTF-8 sequence") 
} 

Aggiornamento per Swift 2/Xcode 7:

if let str = String(data: data, encoding: NSUTF8StringEncoding) { 
    print(str) 
} else { 
    print("not a valid UTF-8 sequence") 
} 

risposta precedente:

String non ha un metodo stringWithBytes(). NSString ha un metodo

NSString(bytes: , length: , encoding:) 

che si potrebbe usare, ma è possibile creare la stringa direttamente da NSData, senza la necessità di un UInt8 matrice:

if let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String { 
    println(str) 
} else { 
    println("not a valid UTF-8 sequence") 
} 
0

"MSString (byte: lunghezza: , codifica:) "non sembra funzionare a partire dal 26 luglio 2015

Convertire i valori di byte in ASCII sembra problematico, se hai colpito un muro puoi farlo nel modo più difficile come segue (e be mi manca qualcosa con swift ma non ho trovato nessuna soluzione entro il mio tempo.) Questo sarà fatto con due funzioni. La prima funzione accetta un UInt8 e lo converte in una rappresentazione "\ u {}", che viene quindi restituita dalla funzione. Secondo, viene impostata un'altra funzione che accetta un array UInt8 come parametro, quindi emette una stringa.

Passaggio 1. Funzione di conversione ogni byte a "\ 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}" 

// .. Aggiungi per tutti i caratteri che si prevede ... non dimenticate di base 16 ..

case 0x09: characterToReturn = "\u{09}" 
case 0x0A: characterToReturn = "\u{0A}" 

default: characterToReturn = "\u{0}" 

/* .. e tutta la strada fino a 0xff */

case 0xFE: characterToReturn = "\u{FE}" 
case 0xFF: characterToReturn = "\u{FF}" 



    } 

return characterToReturn

}

Passo # 2 ...Accanto una funzione che prende in una matrice uint8 come parametro restituisce una stringa ...

func UInt8ArrayToString(#UInt8Array: [UInt8]) -> String {

var returnString : String = "" for eachUInt8Byte in UInt8Array {

returnString += convertToCharacter(UInt8Bits: eachUInt8Byte)

}

return returnString }

Questo dovrebbe funzionare in un parco giochi Swift Fare una matrice

var myArray: [Uint8] = [0x30, 0x3A, 0x4B]

// quindi applicare le funzioni sopra

println (UInt8ArrayToString (UInt8Array: myArray))

+0

Potresti chiarire la tua dichiarazione * "" NSString (bytes:, length:, encoding:) "non appare lavorare ... "*? - L'ho ricontrollato con Xcode 7 beta 5 e non ho riscontrato problemi. –

+0

Anche io sto avendo un problema. Stiamo facendo xor di due UInt8 e quello che sembra accadere è che il risultato xor sta restituendo un UInt8 corretto, ma il NSString (byte, ...) non riesce a convertire la stringa. Se utilizzo Playground e regola le stringhe che restituiscono un risultato prima dell'avvio di base16, la NSString (byte, ...) funziona. – Josh

4

Questa soluzione funziona.

NSString(bytes: data!, length: data!.count, encoding: NSUTF8StringEncoding) 
1

Non molto elegante o 'Swifty', ma questo è semplice e funziona:

let i: UInt8 = 65 
let s = String(format: "%c", i) // A 

ho sprecato ore alla ricerca di un modo semplice per fare questo, prima che improvvisamente ho pensato di 'printf' dai miei giorni di scripting per Unix!

6

questo ha funzionato per me:

String(bytes: bytes, encoding: NSUTF8StringEncoding) 
3

Martin R in https://stackoverflow.com/a/29644387/2214832 risposto Sunil Kumar sul suo problema, ma non sul tema domanda. Il problema si verifica ancora se si dispone già dell'array di byte UInt8 e occorre presentarlo come stringa.

Ecco la mia soluzione:

extension String { 
    init(_ bytes: [UInt8]) { 
     self.init() 
     for b in bytes { 
      self.append(UnicodeScalar(b)) 
     } 
    } 
} 

Utilizzando questa estensione è possibile String ora init con Uint8 array di byte così:

func testStringUInt8Extension() { 
    var cs : [UInt8] = [] 
    for char : UInt8 in 0..<255 { 
     cs.append(char) 
    } 
    print("0..255 string looks like \(String(cs)))") 
} 

Questo non è la soluzione ideale, perché in pratica si avrebbe bisogno di decodificare qualcosa come il testo codificato UTF-8. Ma per i dati ASCII funziona come previsto.

7

Swifty soluzione rappresentazione

array.reduce("", combine: { $0 + String(format: "%c", $1)}) 

Hex:

array.reduce("", combine: { $0 + String(format: "%02x", $1)}) 
+3

Swift 3: '' 'array.reduce (" ", {$ 0 + Stringa (formato:"% c ", $ 1)})' '' –

+0

Uso errato se 'riduci' IMO. Andrei con 'array.map {String (formato:"% c ", $ 0)} .joined()' –

0

esempio completo per Swift 2 & 3:

import Foundation 

let bytes : [UInt8] = [72, 73] 
let nsdata = NSData(bytes: bytes as [UInt8], length: 2) 
let str = String(data: nsdata, encoding: NSUTF8StringEncoding)! // 'HI' 
3

Swift 3

il seguente mi stava dando un errore a causa di "NSUTF8StringEncoding":

String(data: nsdata, encoding: NSUTF8StringEncoding)! 

questo ha lavorato per me in rapida 3:

let xmlStr:String = String(bytes: data!, encoding: String.Encoding.utf8)! 
1

Ecco il codice più generalizzato per estrarre stringhe da un array di byte dove le stringhe sono state codificate in 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)! 
    } 
} 

Questo è un estratto da una classe più ampia (vedi anche https://stackoverflow.com/a/41547936/253938) che uso per elaborare i dati serializzati.

0

È necessario convertire l'array Int8 in Data, quindi convertire in String.

Questa è la mia soluzione:

var buffer = [Int8](repeating: 0, count: 100) 
    let data = Data(bytes: buffer as [Int8], count: buffer.count); 
    return String(data: data, encoding: .utf8) 
0

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") 
Problemi correlati