The problem is here:
let base64Decoded: NSString = NSString(data: nsdata, encoding: NSUTF8StringEncoding)!
You convert the decoded data to a string. This fails for
[128] because that does not represent a valid UTF-8 sequence.
Here is a version that avoids the intermediate string:
func base64ToByteArray(base64String: String) -> [UInt8] {
let nsdata: NSData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions(rawValue: 0))!
// Create array of the required size ...
var bytes = [UInt8](count: nsdata.length, repeatedValue: 0)
// ... and fill it with the data
nsdata.getBytes(&bytes)
return bytes
}
Remarks:
options: NSDataBase64DecodingOptions(rawValue: 0) can be simplified
to options: nil.
- There are some unnecessary type annotations and conversions in your code.
- Your function crashes if
baseString is not a valid Base64 string.
You could change it to return an optional.
Then it would look like this:
func byteArrayToBase64(bytes: [UInt8]) -> String {
let nsdata = NSData(bytes: bytes, length: bytes.count)
let base64Encoded = nsdata.base64EncodedStringWithOptions(nil);
return base64Encoded;
}
func base64ToByteArray(base64String: String) -> [UInt8]? {
if let nsdata = NSData(base64EncodedString: base64String, options: nil) {
var bytes = [UInt8](count: nsdata.length, repeatedValue: 0)
nsdata.getBytes(&bytes)
return bytes
}
return nil // Invalid input
}
Example usage:
let testString = byteArrayToBase64([127, 128, 0, 130]);
println(testString) // Output: f4AAgg==
if let result = base64ToByteArray(testString) {
println(result) // Output: [127, 128, 0, 130]
} else {
println("failed")
}
Update for Swift 2 / Xcode 7:
func byteArrayToBase64(bytes: [UInt8]) -> String {
let nsdata = NSData(bytes: bytes, length: bytes.count)
let base64Encoded = nsdata.base64EncodedStringWithOptions([]);
return base64Encoded;
}
func base64ToByteArray(base64String: String) -> [UInt8]? {
if let nsdata = NSData(base64EncodedString: base64String, options: []) {
var bytes = [UInt8](count: nsdata.length, repeatedValue: 0)
nsdata.getBytes(&bytes, length: bytes.count)
return bytes
}
return nil // Invalid input
}
let testString = byteArrayToBase64([127, 128, 0, 130]);
print(testString) // Output: f4AAgg==
if let result = base64ToByteArray(testString) {
print(result) // Output: [127, 128, 0, 130]
} else {
print("failed")
}
Update for Swift 3 and later:
func byteArrayToBase64(bytes: [UInt8]) -> String {
let data = Data(bytes)
let base64Encoded = data.base64EncodedString()
return base64Encoded;
}
func base64ToByteArray(base64String: String) -> [UInt8]? {
guard let data = Data(base64Encoded: base64String) else {
return nil
}
return Array(data)
}
let testString = byteArrayToBase64(bytes: [127, 128, 0, 130]);
print(testString) // Output: f4AAgg==
if let result = base64ToByteArray(base64String: testString) {
print(result) // Output: [127, 128, 0, 130]
} else {
print("failed")
}