Sakthimuthiah
Sakthimuthiah

Reputation: 2636

How to convert a base64String to String in Swift?

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

Answers (5)

nRewik
nRewik

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.

WARNING (edit)

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

Sabrina
Sabrina

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!"

Source

Upvotes: 8

Blue_Alien
Blue_Alien

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

Tarciso Junior
Tarciso Junior

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

Ashok
Ashok

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

Related Questions