2016-04-01 37 views
6

Sto cercando di decodificare una stringa base64 a un'immagine in rapida utilizzando il seguente codice:veloci rendimenti decodifica base64 nil

let decodedData=NSData(base64EncodedString: encodedImageData, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) 

Purtroppo, la variabile decodedData risulta avere un valore pari a zero

Debugging attraverso il codice, ho verificato che la variabile encodedImageData non è nil ed è i dati di immagine codificati corretti (verificati utilizzando un convertitore di base64 online per immagini). Quale potrebbe essere la ragione dietro il mio problema?

Nota: Sono ancora nuovo per Swift e XCode

Grazie

+0

Hai provato con le opzioni di base? 'let decodedData = NSData (base64EncodedString: encodedImageData, opzioni: NSDataBase64EncodingOptions())' – Moritz

risposta

18

Questo metodo richiede imbottitura con “=”, la lunghezza della stringa deve essere multiplo di 4.

In alcune implementazioni di base64 il carattere di riempimento non è necessario per la decodifica, poiché è possibile calcolare il numero di byte mancanti. Ma nell'attuazione della Fundation è obbligatorio.

Aggiornato: Come notato sui commenti, è una buona idea quella di verificare prima se la lunghezza della stringa è già un multiplo di 4. Se encoded64 ha la stringa base64 e non è una costante, si può fare qualcosa di simile:

Swift 2

let remainder = encoded64.characters.count % 4 
if remainder > 0 { 
    encoded64 = encoded64.stringByPaddingToLength(encoded64.characters.count + 4 - remainder, 
                withPad: "=", 
                startingAt: 0) 
} 

Swift 3

01.235.164,106 mila
let remainder = encoded64.characters.count % 4 
if remainder > 0 { 
    encoded64 = encoded64.padding(toLength: encoded64.characters.count + 4 - remainder, 
            withPad: "=", 
            startingAt: 0) 
} 

Versione aggiornata una riga:

oppure è possibile utilizzare questa versione di una riga che restituisce la stessa stringa, quando la sua lunghezza è già un multiplo di 4:

encoded64.padding(toLength: ((encoded64.characters.count+3)/4)*4, 
        withPad: "=", 
        startingAt: 0) 
+0

per le stringhe hanno già una lunghezza di più di 4, il codice aggiunge quattro '=' non necessari! – Mbt925

+0

@ Mbt925 Qui sto spiegando all'OP perché la decodifica in base64 potrebbe non riuscire. Naturalmente, non è una cattiva idea controllare prima se la lunghezza della stringa è già un multiplo di 4. Colgo l'occasione per aggiornare a swift 3. – jlasierra

+0

Ho finito per usare: 'encoded64 = encoded64.padding (toLength: encoded64.characters .count + (4 - resto)% 4, withPad: "=", startingAt: 0) 'senza' if'. – Mbt925

5

Quando il numero di caratteri è divisibile per 4, è necessario evitare il riempimento.

private func base64PaddingWithEqual(encoded64: String) -> String { 
    let remainder = encoded64.characters.count % 4 
    if remainder == 0 { 
    return encoded64 
    } else { 
    // padding with equal 
    let newLength = encoded64.characters.count + (4 - remainder) 
    return encoded64.stringByPaddingToLength(newLength, withString: "=", startingAtIndex: 0) 
    } 
} 
0

Un'altra versione di una sola riga:

let length = encoded64.characters.count 
encoded64 = encoded64.padding(toLength: length + (4 - length % 4) % 4, withPad: "=", startingAt: 0) 
1

(Swift 3) Sono stato in questa situazione, cercando di ottenere i dati utilizzando Base64 ritorna stringa codificata NIL con me quando ho usato questa linea

let imageData = Data(base64Encoded: strBase64, options: .ignoreUnknownCharacters) 

provato imbottitura la corda e non ha funzionato troppo

Questo è ciò che ha funzionato con me

func imageForBase64String(_ strBase64: String) -> UIImage? { 

    do{ 
     let imageData = try Data(contentsOf: URL(string: strBase64)!) 
     let image = UIImage(data: imageData) 
     return image! 
    } 
    catch{ 
     return nil 
    } 
}