Base64 Encoding in Objective-C

Our first program will demonstrate base64 encoding and decoding. Here’s the full source code.

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // Here's the string we'll encode/decode.
        NSString *data = @"abc123!?$*&()'-=@~";
        
        // Objective-C provides built-in support for base64 encoding/decoding.
        // Here's how to encode using the standard encoder.
        NSData *nsData = [data dataUsingEncoding:NSUTF8StringEncoding];
        NSString *sEnc = [nsData base64EncodedStringWithOptions:0];
        NSLog(@"%@", sEnc);
        
        // Decoding may return an error, which you can check
        // if you don't already know the input to be well-formed.
        NSData *sDec = [[NSData alloc] initWithBase64EncodedString:sEnc options:0];
        NSString *sDecString = [[NSString alloc] initWithData:sDec encoding:NSUTF8StringEncoding];
        NSLog(@"%@", sDecString);
        NSLog(@"");
        
        // Objective-C doesn't have a built-in URL-compatible base64 format.
        // To achieve this, we need to replace characters after encoding.
        NSString *uEnc = [sEnc stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
        uEnc = [uEnc stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
        NSLog(@"%@", uEnc);
        
        // For decoding, we need to reverse the replacements before decoding.
        NSString *uEncForDecoding = [uEnc stringByReplacingOccurrencesOfString:@"-" withString:@"+"];
        uEncForDecoding = [uEncForDecoding stringByReplacingOccurrencesOfString:@"_" withString:@"/"];
        NSData *uDec = [[NSData alloc] initWithBase64EncodedString:uEncForDecoding options:0];
        NSString *uDecString = [[NSString alloc] initWithData:uDec encoding:NSUTF8StringEncoding];
        NSLog(@"%@", uDecString);
    }
    return 0;
}

To run the program, save the code in a file with a .m extension (e.g., base64_encoding.m) and use the following commands:

$ clang -framework Foundation base64_encoding.m -o base64_encoding
$ ./base64_encoding
YWJjMTIzIT8kKiYoKSctPUB+
abc123!?$*&()'-=@~

YWJjMTIzIT8kKiYoKSctPUB-
abc123!?$*&()'-=@~

The string encodes to slightly different values with the standard and URL-compatible base64 encoders (trailing + vs -) but they both decode to the original string as desired.

Note that Objective-C doesn’t have a built-in URL-compatible base64 encoder, so we manually replace the characters to achieve the same result. In practice, you might want to create a category on NSData or NSString to encapsulate this functionality for reuse.