Objective c 如何正确实现QLEVIEWPANEL数据源,同时牢记安全范围的URL?

Objective c 如何正确实现QLEVIEWPANEL数据源,同时牢记安全范围的URL?,objective-c,cocoa,sandbox,quicklook,security-scoped-bookmarks,Objective C,Cocoa,Sandbox,Quicklook,Security Scoped Bookmarks,在Cocoa中,当人们试图将快速预览面板和安全范围的URL结合起来时,会出现一个选择不当、不可组合的抽象的问题 我有一个具体的例子: 假设我们正在尝试显示MediaLibrary中某些对象的预览(MediaLibrary.framework允许应用程序通过方便的API浏览iPhoto、Aperture…和照片库) 最简单、最直接的方法是调整“MLMediaObject”类(表示特定的照片或视频项目)以实现“QLPreviewItem”协议(可传递到QLPreviewPanel): MLMedia

在Cocoa中,当人们试图将快速预览面板和安全范围的URL结合起来时,会出现一个选择不当、不可组合的抽象的问题

我有一个具体的例子:

假设我们正在尝试显示MediaLibrary中某些对象的预览(MediaLibrary.framework允许应用程序通过方便的API浏览iPhoto、Aperture…和照片库)

最简单、最直接的方法是调整“MLMediaObject”类(表示特定的照片或视频项目)以实现“QLPreviewItem”协议(可传递到QLPreviewPanel):

MLMediaObject+PreviewItem.h

#import <MediaLibrary/MLMediaObject.h>

#import <Quartz/Quartz.h>

@interface MLMediaObject (PreviewItem) <QLPreviewItem>

@end
简单。现在想象一下以下QLEVIEWPANEL数据源实现:

AlbumViewController.m

#import "MLMediaObject+PreviewItem.h"

@implementation MLMediaObject (PreviewItem)

- (NSURL*) previewItemURL
{
  return self.URL;
}

- (NSString*) previewItemTitle
{
  return self.name;
}

@end
- (NSInteger) numberOfPreviewItemsInPreviewPanel: (QLPreviewPanel*) panel
{
  // 'currentAlbum' property contains the currently-represented MLMediaGroup object.
  return self.currentAlbum.count;
}

- (id<QLPreviewItem>) previewPanel: (QLPreviewPanel*) panel previewItemAtIndex: (NSInteger) index
{
  return self.currentAlbum[index];
}
-(NSInteger)PreviewWitemsinPreviewPanel:(QLPreviewPanel*)面板的PreviewWitemsinPreviewPanel编号
{
//“currentAlbum”属性包含当前表示的MLMediaGroup对象。
返回self.currentAlbum.count;
}
-(id)previewPanel:(QLPreviewPanel*)面板PreviewWiteMatIndex:(NSInteger)索引
{
返回self.currentAlbum[索引];
}
到目前为止还不错。但是,如果我们仔细研究苹果公司稀疏且通常具有误导性的文档,我们可能会发现以下重要细节:

URL
媒体对象的位置。(只读)
此属性作为安全范围的URL提供。为了访问此URL引用的文件,调用方必须在使用URL访问该文件之前调用
startAccessingSecurityScopedResource
,然后在使用URL访问该文件之后调用
stoppaccessingsecurityscopedresource

因此,很明显,对资源的访问必须用
startAccessingSecurityScopedResource
/
stopAccessingSecurityScopedResource
调用对括起来

问题是,考虑到当前的
QLPreviewPanelDataSource
协议定义,我应该把这些调用放在哪里?
访问资源是QLPreviewPanel的责任,而不是我的代码,但不幸的是,我几乎不会相信苹果会更新QL以在沙箱环境中运行

startAccessingSecurityScopedResource
调用返回
NO
,说明访问失败时,我如何处理这些情况?

似乎当您尝试
在已被访问的URL上启动访问安全性ScopedResource
时,您会在返回时收到失败标志。就像,一切都正常,但是你会得到一个错误标志。似乎这些开始/停止。。。呼叫必须精确配对,甚至禁止平衡嵌套那么,当您在返回时获得
NO
时,如何区分这两种可能性:已被访问的安全范围URL和未能“解析”的安全范围URL?

这是一个经过实验验证的事实,即您的应用程序只能访问有限数量的安全范围的URL(您可以获取约1500个URL,然后它将自动停止工作)。那么,在我将安全范围的URL传递给QLPreviewPanel之后,我应该如何正确地放弃对它们的访问呢?何时是这样做的适当时机?在我看来,它似乎是QLVeviewPanel类的私有实现细节,我无法对其内部工作进行任何假设。

您可以使用:

- (void)beginPreviewPanelControl:(QLPreviewPanel *)panel {
    [bookmarkURL startAccessingSecurityScopedResource];
    //... Your code

}


不幸的是,它没有解决我在帖子中提到的任何问题。
- (void)endPreviewPanelControl:(QLPreviewPanel *)panel {
    //... Your Code
    [bookmarkURL stopAccessingSecurityScopedResource];
}