为了节省与我的iOS应用程序相关的服务器端带宽成本,我已经打包了一堆资产,否则这些资产可以在运行时下载到我的iOS应用程序包中。在编写应用程序的上下文中,如果我可以从一个用户可写目录(例如[App Dir]/Library/Application Support/My Custom Subfolder/
)访问文件而不必在运行时直接复制文件(例如,在启动时),那将是理想的选择。 ,首先运行,无论如何)。
虽然我已经能够使用.../My Custom Subfolder/
API NSFileManager
在createSymbolicLinkAtURL:withDestinationURL:error:
中成功创建包中文件的符号链接,但我会使用一些框架API来访问稍后的内容得到了充实,并返回了与符号链接有关的属性和数据,而不是基础文件。我可以通过利用其他一些框架API来缓解这些问题,但根据不正确的用法范围,它可能最终会有很多工作。
在模拟器上,我通过使用NSFileManager
API linkItemAtURL:toURL:error:
创建包内容的硬链接,成功解决了这个问题。硬链接适用于整个应用程序中使用的所有文件访问API,一切都很好。然而,在DEVICE上(在运行iOS 7.0的iPhone 5c和运行iOS 7.1的iPad上测试过),我会收到NSCocoaErrorDomain 513 error (Operation could not be completed. Operation not permitted.)
。我可以在.../My Custom Subfolder/
中创建一个测试文件并在同一个文件夹中创建一个硬链接就好了,但是如果我尝试硬连接到只读应用程序包中的任何内容,我会收到513错误。
有没有人知道是否有办法解决权限错误以完成我正在尝试做的事情?
答案 0 :(得分:4)
你根本无法绕过这个错误,我确信这一点。我没有找到任何正式的文档 - 但有几个教程解释了如何允许在越狱设备上使用符号链接。我没理由为什么iOS上的安全性与硬链接有所不同。在模拟器中,这是有效的,因为它在本地机器上的路径上运行(在〜/ Library / Application Support / iphone Simulator / iOSVersion / Applications / ...中)并具有本地安全性。作为一个反例,我不止一次地想到我在模拟器中工作的东西在设备上没有工作,反之亦然(例如当试图用SQLITE_WRITE在主捆绑中打开sqlite3 db时标志)。
我通过使用两个不同的文件位置解决了我的应用中的资源管理/版本控制问题。原始版本像往常一样在主包内。另一个位置是缓存目录或文档目录。然后我使用自定义资源处理程序返回提供的相对路径的完整路径。它的工作原理如下:
一些代码(使用缓存目录作为可更新目录,您可能想要更改它):
#define UpdateableCacheResourcePath(path) \
[[ResourceHandler sharedManager] updateableCacheResourcePath:path]
- (NSString*)updateableCacheResourcePath:(NSString *)path
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory , NSUserDomainMask, YES);
NSString *_libraryCacheStorageDir = [[paths objectAtIndex:0] copy];
NSString *updateablePath = [_libraryCacheStorageDir stringByAppendingPathComponent:path];
// Cache Dir
if ([_fileManager fileExistsAtPath:updateablePath]) {
return updateablePath;
}
// mainBundle
NSString *mainbundleResourcePath = [_mainBundlePath stringByAppendingPathComponent:path];
if ([_fileManager fileExistsAtPath:mainbundleResourcePath]) {
return mainbundleResourcePath;
}
NSLog(@"File not found: %@", path);
return nil;
}
在您的代码中,您将使用UpdateableCacheResourcePath(" some.file")而不是查看主包。它也适用于refrenced文件夹(拖放文件夹到xcode并选择创建引用而不是组)。然后,您可以引用父文件夹的相对路径(如advertisements / adbanner.png)。
唯一的缺点是,如果您有Web内容,则需要更新html网站引用的所有文件,原因显而易见(Web浏览器只能跟踪html文档所在文件夹的相对路径)。