Программный доступ к библиотеке фотографий в Mac OS X: PhotoKit / Photos Framework для Mac
В Objective-C есть Photos Framework, также известный как PhotoKit, который позволяет разработчикам iOS получать доступ к библиотеке фотографий на iPhone и iPad и получать изображения / видео вместе с их метаданными.
Как разработчики Mac будут выполнять аналогичную задачу? Кажется, PhotoKit доступен только в iOS 8.0. Есть ли эквивалент Photos Framework для Mac OS X?
2 ответа
Media Library Framework - это то, что нужно.
Использование:
@import MediaLibrary;
- (void) awakeFromNib
{
NSDictionary *options = @{
MLMediaLoadSourceTypesKey: @(MLMediaSourceTypeImage),
MLMediaLoadIncludeSourcesKey: @[MLMediaSourcePhotosIdentifier]
};
MLMediaLibrary *mediaLibrary = [[MLMediaLibrary alloc] initWithOptions:options];
self.mediaLibrary = mediaLibrary;
[mediaLibrary addObserver:self
forKeyPath:@"mediaSources"
options:0
context:(__bridge void *)@"mediaLibraryLoaded"];
[mediaLibrary mediaSources]; // returns nil and starts asynchronous loading
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if (context == (__bridge void *)@"mediaLibraryLoaded") {
// Media Library is loaded now, we can access mediaSources
MLMediaSource *mediaSource = [self.mediaLibrary.mediaSources objectForKey:@"com.apple.Photos"];
}
}
Концепция библиотеки заключается в том, что вы должны запросить ее для чтения атрибута объекта, который возвращает пустую ссылку. Затем вы подписываетесь на этот атрибут с помощью наблюдателя значения ключа и ожидаете его загрузки. Затем вы можете получить следующего ребенка по тому же принципу и так далее...
Основываясь на ответе Пьера F, я расширяю код для отображения URL-адресов для всех фотографий:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSDictionary *options = @{
MLMediaLoadSourceTypesKey: @(MLMediaSourceTypeImage),
MLMediaLoadIncludeSourcesKey: @[MLMediaSourcePhotosIdentifier]
};
self.mediaLibrary = [[MLMediaLibrary alloc] initWithOptions:options];
[self.mediaLibrary addObserver:self
forKeyPath:@"mediaSources"
options:0
context:(__bridge void *)@"mediaLibraryLoaded"];
[self.mediaLibrary.mediaSources objectForKey:MLMediaSourcePhotosIdentifier];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
MLMediaSource *mediaSource = [self.mediaLibrary.mediaSources objectForKey:MLMediaSourcePhotosIdentifier];
if (context == (__bridge void *)@"mediaLibraryLoaded")
{
[mediaSource addObserver:self
forKeyPath:@"rootMediaGroup"
options:0
context:(__bridge void *)@"rootMediaGroupLoaded"];
[mediaSource rootMediaGroup];
}
else if (context == (__bridge void *)@"rootMediaGroupLoaded")
{
MLMediaGroup *albums = [mediaSource mediaGroupForIdentifier:@"TopLevelAlbums"];
for (MLMediaGroup *album in albums.childGroups)
{
NSString *albumIdentifier = [album.attributes objectForKey:@"identifier"];
if ([albumIdentifier isEqualTo:@"allPhotosAlbum"])
{
self.allPhotosAlbum = album;
[album addObserver:self
forKeyPath:@"mediaObjects"
options:0
context:@"mediaObjects"];
[album mediaObjects];
break;
}
}
}
else if (context == (__bridge void *)@"mediaObjects")
{
NSArray * mediaObjects = self.allPhotosAlbum.mediaObjects;
for(MLMediaObject * mediaObject in mediaObjects)
{
NSURL * url = mediaObject.URL;
NSLog(url.path);
}
}
}
Хотя это не официально документированный API, w0lfschild опубликовал заголовки фреймворка Apple PhotoKit для macOS. API выглядит очень похоже на iOS, так что, возможно, вы сможете понять это, используя только документы iOS. И в дополнение к MediaLibrary Framework вы также можете вносить изменения в библиотеку.