我可以为内存NSData创建一个指向的NSURL吗?

34

NSURL的文档指出:

NSURL对象表示一个URL,可以潜在地包含远程服务器上资源的位置、本地磁盘上文件的路径,甚至是任意编码数据的一部分

我有一块内存中的数据,想把它交给一个需要通过NSURL加载资源的库。当然,我可以先将这个NSData写入临时文件,然后从那里创建一个file://NSURL,但我更希望将URL直接指向我已经存在于内存中的缓冲区。

上面引用的文档似乎表明这是可能的,但我找不到如何实现的任何提示。我错过了什么吗?


也许这意味着你可以给它一个数据URI?http://en.wikipedia.org/wiki/Data_URI_scheme - nobody
1
所以基本上你想让[NSData dataWithContentsOfURL:myURLHere]返回已经存在于RAM中的数据,而不是从文件中读取它? - Abhi Beckert
NSData 的文档提到了 data:// 作为一种支持的 URL 协议,但我找不到关于它如何工作的任何文档。很可能它只是数据的十六进制字符串。 - Abhi Beckert
2个回答

34

NSURL 支持 data:// URL 方案 (RFC 2397)。
该方案允许您构建如下形式的 URL:

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

一个可工作的Cocoa示例如下:

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];

由于base64编码的性质,使用数据URL传递大型二进制块可能会有些低效。

您还可以实现自定义 NSURLProtocol 处理您的数据。 苹果有一些示例代码,使用自定义协议传递图像对象:https://developer.apple.com/library/mac/samplecode/SpecialPictureProtocol/Introduction/Intro.html#//apple_ref/doc/uid/DTS10003816


1
另一个例子:[NSString stringWithContentsOfURL:[NSURL URLWithString:@"data:text/plain;base64,aGVsbG8gd29ybGQ="] encoding:NSUTF8StringEncoding error:NULL]; 可以给你 @"hello world"。它并不太低效,只比 ASCII 多了 4 个字节。 - Abhi Beckert
1
感谢。data: 协议对于较小的缓冲区绝对是有效的(如果有人感兴趣,我在这里编写了一个微型协议:https://github.com/bzotto/NSURL-DataAdditions)。自定义 NSURLProtocol 的方式可能是这里最好的答案,因为第一个选项在内存方面会极其浪费(并需要大量编码)用于任何非平凡操作。 - Ben Zotto
我尝试使用这个逻辑创建一个包含MP4视频数据的NSURL,并使用AVFoundation播放它。使用这种方法无法加载电影文件,也许使用NSURLProtocol会更成功。 - MoDJ

6
你所缺少的是NSURLProtocol类。需要大约三十多行代码,任何正确处理URL的代码都可以访问你的内存数据。阅读文档不难,并且有示例代码可用。
不幸的是,有些API只接受文件URL作为参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接