Search code examples
swiftbase64

How can I encode/decode a string to Base64 in Swift?


I want to convert a string to Base64. I found answers in several places, but it does not work anymore in Swift. I am using Xcode 6.2. I believe the answer might be work in previous Xcode versions and not Xcode 6.2.

Could someone please guide me to do this in Xcode 6.2?

The answer I found was this, but it does not work in my version of Xcode:

var str = "iOS Developer Tips encoded in Base64"
println("Original: \(str)")

// UTF 8 str from original
// NSData! type returned (optional)
let utf8str = str.dataUsingEncoding(NSUTF8StringEncoding)

// Base64 encode UTF 8 string
// fromRaw(0) is equivalent to objc 'base64EncodedStringWithOptions:0'
// Notice the unwrapping given the NSData! optional
// NSString! returned (optional)
let base64Encoded = utf8str.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.fromRaw(0)!)
println("Encoded:  \(base64Encoded)")

// Base64 Decode (go back the other way)
// Notice the unwrapping given the NSString! optional
// NSData returned
let data = NSData(base64EncodedString: base64Encoded, options:   NSDataBase64DecodingOptions.fromRaw(0)!)

// Convert back to a string
let base64Decoded = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Decoded:  \(base64Decoded)")

ref: http://iosdevelopertips.com/swift-code/base64-encode-decode-swift.html


Solution

  • I don’t have 6.2 installed but I don’t think 6.3 is any different in this regard:

    dataUsingEncoding returns an optional, so you need to unwrap that.

    NSDataBase64EncodingOptions.fromRaw has been replaced with NSDataBase64EncodingOptions(rawValue:). Slightly surprisingly, this is not a failable initializer so you don’t need to unwrap it.

    But since NSData(base64EncodedString:) is a failable initializer, you need to unwrap that.

    Btw, all these changes were suggested by Xcode migrator (click the error message in the gutter and it has a “fix-it” suggestion).

    Final code, rewritten to avoid force-unwraps, looks like this:

    import Foundation
    
    let str = "iOS Developer Tips encoded in Base64"
    println("Original: \(str)")
    
    let utf8str = str.dataUsingEncoding(NSUTF8StringEncoding)
    
    if let base64Encoded = utf8str?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) 
    {
    
        println("Encoded:  \(base64Encoded)")
    
        if let base64Decoded = NSData(base64EncodedString: base64Encoded, options:   NSDataBase64DecodingOptions(rawValue: 0))
                              .map({ NSString(data: $0, encoding: NSUTF8StringEncoding) })
        {
            // Convert back to a string
            println("Decoded:  \(base64Decoded)")
        }
    }
    

    (if using Swift 1.2 you could use multiple if-lets instead of the map)

    Swift 5 Update:

    import Foundation
    
    let str = "iOS Developer Tips encoded in Base64"
    print("Original: \(str)")
    
    let utf8str = str.data(using: .utf8)
    
    if let base64Encoded = utf8str?.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0)) {
        print("Encoded: \(base64Encoded)")
    
        if let base64Decoded = Data(base64Encoded: base64Encoded, options: Data.Base64DecodingOptions(rawValue: 0))
        .map({ String(data: $0, encoding: .utf8) }) {
            // Convert back to a string
            print("Decoded: \(base64Decoded ?? "")")
        }
    }