Can I create an NSURL that refers to in-memory NSData?

Ben Zotto picture Ben Zotto · May 14, 2014 · Viewed 7k times · Source

The docs for NSURL state that:

An NSURL object represents a URL that can potentially contain the location of a resource on a remote server, the path of a local file on disk, or even an arbitrary piece of encoded data.

I have a blob of in-memory data that I'd like to hand to a library that wants to load a resource via an NSURL. Sure, I can first write this NSData to a temp file and then create a file:// NSURL from that, but I'd prefer to have the URL point directly to the buffer that I already have present in memory.

The docs quoted above seem to suggest this is possible, but I can't find any hint of how to accomplish it. Am I missing something?

Answer

Thomas Zoechling picture Thomas Zoechling · May 14, 2014

NSURL supports the data:// URL-Scheme (RFC 2397).
This scheme allows you to build URLs in the form of

data://data:MIME-Type;base64,<data>

A working Cocoa example would be:

NSImage* img = [NSImage imageNamed:@"img"];
NSData* imgData = [img TIFFRepresentation];
NSString* dataFormatString = @"data:image/png;base64,%@";
NSString* dataString = [NSString stringWithFormat:dataFormatString, [imgData base64EncodedStringWithOptions:0]];
NSURL* dataURL = [NSURL URLWithString:dataString];

Passing around large binary blobs with data URLs might be a bit inefficient due to the nature of base64 encoding.

You could also implement a custom NSURLProtocol that specifically deals with your data. Apple has some sample code that uses a custom protocol to pass around image objects: https://developer.apple.com/library/mac/samplecode/SpecialPictureProtocol/Introduction/Intro.html#//apple_ref/doc/uid/DTS10003816