Dov*_*Dov 17 macos cocoa objective-c osx-lion appstore-sandbox
我正在沙盒化我的应用程序,并尝试允许导入/导出多个文件,使用XML文件来引用它们.为了允许我的应用程序(或其他沙盒应用程序)访问XML中列出的文件,我还包括一个序列化的安全范围书签.我正在按照本答案中的描述对其进行序列化,我的单元测试(不是沙箱)会毫无问题地写入和读取XML数据.当我的应用程序解析书签时,NSURL返回的内容为nil,NSError引用也是如此.既然我不相信应该是这样的话,为什么会这样呢?我可以通过提示用户选择带有a的文件/目录来解决它NSOpenPanel,但我仍然希望让书签按原样运行.
在测试项目中转载
要在家中重现,请在Xcode中创建一个新的Cocoa应用程序,并对项目中的文件使用以下Gist:https://gist.github.com/2582589(使用正确的下一个视图循环更新)
然后,按照Apple的说明对项目进行代码签名.您通过依次单击按钮重现问题(我以rdar:// 11369377提交给Apple ).您选择磁盘上的任何文件(在应用程序的容器外),然后选择要导出的XML,然后导入相同的XML.
希望你们能够帮助我弄清楚我做错了什么.要么我做错了什么,框架错误地保持自己,或者我做得对,它完全被打破了.我尽量不责怪框架,所以它是什么?还是有其他可能吗?
示例代码
将XML导出到docURL:
// After the user picks an XML (docURL) destination with NSSavePanel
[targetURL startAccessingSecurityScopedResource];
NSData *bookmark = [targetURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:nil
relativeToURL:docURL
error:&error];
[targetURL stopAccessingSecurityScopedResource];
Run Code Online (Sandbox Code Playgroud)
从docURL以下位置导入XML :
// After the user selected the XML (docURL) from an NSOpenPanel
NSURL *result = [NSURL URLByResolvingBookmarkData:bookmarkData
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:docURL
bookmarkDataIsStale:nil
error:&error];
Run Code Online (Sandbox Code Playgroud)
我试着围绕这个调用[docURL ..AccessingSecurityScopedResource],这没有什么区别(正如预期的那样,因为docURL在Open Panel中被选中后已经在范围内了)
另外,我在我的app.entitlements文件中指定以下内容:
com.apple.security.files.user-selected.read-write
com.apple.security.files.bookmarks.app-scope
com.apple.security.files.bookmarks.collection-scope
Run Code Online (Sandbox Code Playgroud)
如上所述,第二步(解析书签)完成,但保留两者error和result零.由于我一直在实施沙盒,我所犯的大多数错误都导致了NSError返回,这有助于我解决这个问题.但现在没有错误,也没有解决任何URL.
其他故障排除步骤
我尝试将XML文件放入我的应用程序的沙箱中,这没有什么区别,因此访问XML文件不是问题
该应用程序使用ARC,但成功的单元测试也是如此.我尝试使用alloc/init而不是autoreleased类方法(以防万一)
我在创建书签后立即粘贴了URL解析代码,它运行正常,产生了一个安全范围的URL
我po在最初创建的书签(序列化之前)上做了一个,然后在反序列化后的书签上,它们匹配100%.序列化不是问题
我更换了分辨率调用CFURLCreateByResolvingBookmarkData(..),没有任何变化.如果它是一个bug,它会出现在Core Foundation API以及Cocoa层中
指定值bookmarkDataIsStale:无效
如果我指定0的options:,然后我做得到一个有效的NSURL,但它没有安全范围,因此后续调用来读取文件仍旧失败
换句话说,反序列化的书签看起来确实有效.如果书签数据已损坏,我怀疑NSURL能否对它做任何事情
NSURL.h 没有任何有用的评论来指出我做错了什么
是否有其他人在沙盒应用程序中使用安全范围的文档书签成功?如果是这样,你做的与我不同的是什么?
OS版本请求
有权访问Mountain Lion测试版的人是否可以验证我的示例项目是否显示相同(缺少)错误?如果这是在Lion之后修复的错误,我不会担心它.我还没有进入开发者计划,所以没有访问权限.我不确定回答这个问题是否违反了NDA,但我希望不会.
在您的Gist代码中,更改AppDelegate.m中的以下行(第61行):
[xmlTextFileData writeToURL:savePanel.URL atomically:YES];
Run Code Online (Sandbox Code Playgroud)
至
[xmlTextFileData writeToURL:savePanel.URL atomically:NO];
Run Code Online (Sandbox Code Playgroud)
您的代码将工作.
造成这种情况的原因可能与调用[anURL bookmarkDataWithOptions]之前需要包含文档范围书签的现有(但空)文件的原因相同:创建NSData实例时,ScopedBookmarkAgent会添加一些内容(如该文件的标签,可能是扩展文件属性.
如果您以原子方式将数据(即书签URL)写入该文件,实际上它们不是直接写入文件,而是首先写入在写入操作成功时重命名的临时文件.似乎已经添加到包含书签的(空的,但是现有的)文件的标记在写入临时文件然后重命名它(从而可能删除原始的空文件)的过程中丢失了.
顺便说一句:在将相应的URL传递给包含文档范围书签的xml文件之前,不必创建应用程序范围的书签.
另外:com.apple.security.files.bookmarks.collection-scope已重命名为10.7.4中的com.apple.security.files.bookmarks.document-scope.
| 归档时间: |
|
| 查看次数: |
4423 次 |
| 最近记录: |