Reputation: 2636
I am receiving a base64String from webservice response in NSData, how to convert that base64String to String in swift?
//Code
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as! NSDictionary // Response JSON from webservice
var base64String : String = ""
base64String = jsonResult["Base64String"] as! String // Retrieve base64String as string from json response
println("Base64String Alone: \(base64String)")
// Code to decode that base64String
let decodedData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions(rawValue: 0))
println("Decoded: \(decodedData)")
let decodedString = NSString(data: decodedData!, encoding: NSUTF8StringEncoding)
println(decodedString) // Prints nil
Encode and decode of base64String works well for the files containing only text, if a file contains some table formats/images both encoding and decoding gives an invalid base64String. How to convert a file into base64String encode and decode whatever the contents of file ? File formats are doc, docx, pdf, txt
Advance thanks for any help !
Upvotes: 58
Views: 75603
Reputation: 9148
Try this:
let base64Encoded = "YW55IGNhcm5hbCBwbGVhc3VyZS4="
var decodedString = ""
if let decodedData = Data(base64Encoded: base64Encoded) {
decodedString = String(data: decodedData, encoding: .utf8)!
}
if !decodedString.isEmpty {
print(decodedString)
} else {
print("Oops, invalid input format!")
}
Make sure your base 64 encoded string is valid.
In most base64
decoding implementations like Java
, the padding-character is not needed, but Data(base64Encoded:)
returns nil
if it's missing.
Swift 5 solution; use String.fromBase64(_:)
instead, after implementing like:
extension Data {
/// Same as ``Data(base64Encoded:)``, but adds padding automatically
/// (if missing, instead of returning `nil`).
public static func fromBase64(_ encoded: String) -> Data? {
// Prefixes padding-character(s) (if needed).
var encoded = encoded;
let remainder = encoded.count % 4
if remainder > 0 {
encoded = encoded.padding(
toLength: encoded.count + 4 - remainder,
withPad: "=", startingAt: 0);
}
// Finally, decode.
return Data(base64Encoded: encoded);
}
}
extension String {
public static func fromBase64(_ encoded: String) -> String? {
if let data = Data.fromBase64(encoded) {
return String(data: data, encoding: .utf8)
}
return nil;
}
}
As mentioned on editor's profile, above edit's code allows Apache 2.0 license as well, without attribution need.
Upvotes: 147
Reputation: 2809
You can encrypt/decrypt base64 strings using this extension:
public extension String {
var base64Decoded: String? {
guard let decodedData = Data(base64Encoded: self) else { return nil }
return String(data: decodedData, encoding: .utf8)
}
var base64Encoded: String? {
let plainData = data(using: .utf8)
return plainData?.base64EncodedString()
}
}
To Encode:
"Hello World!".base64Encoded
Result is an Optional string: "SGVsbG8gV29ybGQh"
To Decode:
"SGVsbG8gV29ybGQh".base64Decoded
Result is an Optional string: "Hello World!"
Upvotes: 8
Reputation: 2177
The above answers are core, but i had an error like
fatal error, found nil while unwrapping an optional value
The solution is adding options
extension String {
//: ### Base64 encoding a string
func base64Encoded() -> String? {
if let data = self.data(using: .utf8) {
return data.base64EncodedString()
}
return nil
}
//: ### Base64 decoding a string
func base64Decoded() -> String? {
if let data = Data(base64Encoded: self, options: .ignoreUnknownCharacters) {
return String(data: data, encoding: .utf8)
}
return nil
}
}
and use it safely
var str = "HelloWorld"
if let base64Str = str.base64Encoded() {
print("Base64 encoded string: \"\(base64Str)\"")
if let trs = base64Str.base64Decoded() {
print("Base64 decoded string: \"\(trs)\"")
}
}
Upvotes: 5
Reputation: 549
i've made an update to Ashok Kumar S answer to add filler character when string size is not divisible by 4, raising an exception and returning nil
extension String {
func base64Encoded() -> String? {
return data(using: .utf8)?.base64EncodedString()
}
func base64Decoded() -> String? {
var st = self;
if (self.count % 4 <= 2){
st += String(repeating: "=", count: (self.count % 4))
}
guard let data = Data(base64Encoded: st) else { return nil }
return String(data: data, encoding: .utf8)
}
Upvotes: 15
Reputation: 5655
Swift extension is handy.
extension String {
func base64Encoded() -> String? {
return data(using: .utf8)?.base64EncodedString()
}
func base64Decoded() -> String? {
guard let data = Data(base64Encoded: self) else { return nil }
return String(data: data, encoding: .utf8)
}
}
"heroes".base64Encoded() // It will return: aGVyb2Vz
"aGVyb2Vz".base64Decoded() // It will return: heroes
Upvotes: 38