Apple Photos: наблюдение изменений MLMediaGroup с использованием MediaLibrary на macOS - PullRequest
0 голосов
/ 02 ноября 2018

Мне нужно отобразить структуру альбома Apple Photos в моем приложении на macOS. Единственный способ сделать это - MediaLibrary Framework. Я могу без проблем пройти по древовидной структуре, используя класс MLMediaGroup. Но наблюдение за изменениями в нем вызывает у меня недоумение. Я ожидаю, что мне нужно будет подписаться на KVO-notificatios для каждой отдельной медиа-группы и наблюдать за изменениями в атрибутах.

Но в действительности, когда я создаю новый альбом / папку в Фото, я получаю уведомление о том, что rootMediaGroup изменилась, и адреса этой группы, а также всех дочерних групп также изменились. Это кажется странным, потому что теперь мне нужно перестроить всю иерархию альбомов. Это похоже на просмотр изменений каталога и получение непрозрачных уведомлений типа «что-то в файловой системе изменилось» без дополнительной информации каждый раз, когда пользователь изменяет каталог где-то глубоко внутри $ HOME.

Я использую target-c (на самом деле мне нужно интегрировать его с c ++), хотя быстрые примеры также могут дать мне подсказку. Ниже я приведу минимальный пример для иллюстрации вопроса.

PhotosObserver.h

#import <Foundation/Foundation.h>
#import <MediaLibrary/MediaLibrary.h>

@interface PhotosObserver: NSObject
{
    @private
    MLMediaLibrary *ml;
    MLMediaSource *src;
    MLMediaGroup *root;
}

@property(nonatomic, retain, nullable, readonly) MLMediaLibrary *ml;
@property(nonatomic, retain, nullable, readonly) MLMediaSource *src;
@property(nonatomic, retain, nullable, readonly) MLMediaGroup *root;

@end

PhotosObserver.m

#include "PhotosObserver.h"

static void* CTX_MEDIASOURCE         = &CTX_MEDIASOURCE;
static void* CTX_MEDIAGROUP          = &CTX_MEDIAGROUP;

static NSString* KPATH_SOURCES = @"mediaSources";
static NSString* KPATH_GROUPS  = @"rootMediaGroup";

@implementation PhotosObserver

@synthesize ml;
@synthesize src;
@synthesize root;

-(id)init {
    if(self = [super init]) {
        self->ml = [[MLMediaLibrary alloc] init];
        [self->ml addObserver: self forKeyPath:KPATH_SOURCES options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:CTX_MEDIASOURCE];
        [self->ml mediaSources];
    }
    return self;
}

-(void)dealloc {
    @try {
        [self.ml removeObserver:self forKeyPath:KPATH_SOURCES context:CTX_MEDIASOURCE];
        [self.src removeObserver:self forKeyPath:KPATH_GROUPS context:CTX_MEDIAGROUP];
    }
    @catch(NSException *) {}
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    if(CTX_MEDIASOURCE == context)
    {
        NSLog(@"Loaded mediaSources");
        self->src = [self->ml.mediaSources objectForKey:/*@"com.apple.Photos"*/MLMediaSourcePhotosIdentifier];
        assert(self->src);
        [self.src addObserver: self forKeyPath:KPATH_GROUPS options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:CTX_MEDIAGROUP];
        [self.src rootMediaGroup];
    }
    else if(CTX_MEDIAGROUP == context)
    {
        MLMediaGroup *old = self->root;
        if(!old)
            NSLog(@"Loaded rootMediaGroup");
        self->root = self.src.rootMediaGroup;
        if(old && old != self.root)
        {
            NSLog(@"Oops, root group has changed: %@ -> %@", old, self.root);
        }
    }
}


@end

Когда я запускаю программу и создаю папку / альбом или переименовываю альбом в Фото, я получаю уведомление об изменении корневой группы. Почему-то я не получаю уведомления в 100% случаев, но в любом случае довольно часто.

В: Почему rootMediaGroup изменяется вообще, поскольку пользователь не может изменить его в пользовательском интерфейсе Photos?

В: Как отслеживать изменения без необходимости повторного сканирования всей иерархии MLMediaGroup после каждой небольшой пользовательской модификации?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...