Как правильно реализовать источник данных QLPreviewPanel с учетом URL-адресов с ограничением безопасности?

Существует проблема с плохо подобранными, несоставными абстракциями в Какао, которые возникают, когда кто-то пытается объединить панель предварительного просмотра Quick Look и URL-адреса в области безопасности.

У меня есть конкретный пример:

Представьте, что мы пытаемся показать предварительный просмотр некоторых объектов из MediaLibrary (MediaLibrary.framework позволяет приложениям просматривать библиотеки iPhoto, Aperture ... и Photos через удобный API).

Самый простой и понятный способ сделать это - адаптировать класс MLMediaObject (который представляет конкретный фото или видео элемент) для реализации протокола QLPreviewItem (который можно передать в QLPreviewPanel):

MLMediaObject + PreviewItem.h

#import <MediaLibrary/MLMediaObject.h>

#import <Quartz/Quartz.h>

@interface MLMediaObject (PreviewItem) <QLPreviewItem>

@end

MLMediaObject + PreviewItem.m

#import "MLMediaObject+PreviewItem.h"

@implementation MLMediaObject (PreviewItem)

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

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

@end

Простой. Теперь представьте следующую реализацию источника данных QLPreviewPanel:

AlbumViewController.m

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

Все идет нормально. Но если мы посмотрим на немногочисленную и обычно вводящую в заблуждение документацию Apple, мы можем обнаружить следующие важные детали:

URL
Расположение медиа-объекта. (только для чтения)
Это свойство предоставляется как URL с ограничением безопасности. Чтобы получить доступ к файлу, на который ссылается этот URL-адрес, вызывающий должен вызвать startAccessingSecurityScopedResource до и stopAccessingSecurityScopedResource после использования URL-адреса для доступа к файлу.

Итак, очевидно, что доступ к ресурсу должен быть ограничен парой вызовов _6 _ / _ 7_.

Вопрос в том, где мне разместить эти вызовы с учетом текущего QLPreviewPanelDataSource определения протокола? Это зависит от QLPreviewPanel, чтобы получить доступ к ресурсу, а не к моему коду, но, к сожалению, я вряд ли когда-нибудь поверю, что Apple обновила QL для работы в среде «песочницы».

Как действовать в случаях, когда startAccessingSecurityScopedResource вызов возвращает NO, сообщая об отсутствии доступа?

Похоже, когда вы пытаетесь startAccessingSecurityScopedResource использовать URL-адрес, к которому уже осуществляется доступ, вы получаете флаг ошибки при возврате. Мол, все ок, но выдает ошибку. Похоже, что эти вызовы start / stop ... должны быть точно спарены, и даже сбалансированное вложение запрещено. Итак, как отличить две возможности, когда вы получаете NO при возврате: URL-адрес с областью безопасности, к которому уже осуществляется доступ, и URL-адрес с областью безопасности, который не удалось "разрешить"?

Экспериментально подтвержденный факт, что ваше приложение может получить доступ только к ограниченному количеству URL-адресов с ограниченным уровнем безопасности (вы можете взять около 1500 URL-адресов, прежде чем оно автоматически перестанет работать). Итак, как мне правильно отказаться от доступа к URL-адресам в области безопасности после того, как я передал их в QLPreviewPanel? Когда наступит подходящий момент? Мне кажется, что это частная деталь реализации класса QLPreviewPanel, и я не могу делать никаких предположений относительно его внутренней работы.


person Konstantin Pavlikhin    schedule 12.05.2015    source источник


Ответы (1)


Ты можешь использовать:

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

}

и

- (void)endPreviewPanelControl:(QLPreviewPanel *)panel {
    //... Your Code
    [bookmarkURL stopAccessingSecurityScopedResource];
}
person Sinisa Drpa    schedule 10.09.2015
comment
К сожалению, это не решило ни одну из проблем, изложенных в моем сообщении. - person Konstantin Pavlikhin; 19.02.2016