I am a bit at a loss about the MLMediaLibrary API.
Maybe, I haven't quite understood it yet, maybe something else is wrong.

I am writing a screen saver that accesses Photos' albums and the images 
referenced by them.
(Code excerpts follow at the end of this email.)

I create an array of the top level albums at startup time of the screensaver , 
using the KVO.
At runtime, I occasionally extract the images referenced by one of those albums.
Most of the time it works fine, except sometimes, my KVO never gets invoked, at 
which point my screensaver hangs,
because I had to stop the animation during that phase.

I have not found a pattern as to when this happens.
(it is not a deterministic album, nor a deterministic n-th time.)

Any suggestions, hints, insights, and pointers will be highly appreciated.

Best regards, 

The code snippets.  (variables ending with underscore are instance variables.)

This is what I do at startup time (in -initwithFrame:isPreview:)

   albums_ = [[NSMutableArray alloc] init];
   NSDictionary *options = @{
   mediaLibrary_ = [[MLMediaLibrary alloc] initWithOptions: options];
   [mediaLibrary_ addObserver: self
                       forKeyPath: @"mediaSources"
                          options: 0
                          context: (__bridge void *) @"mediaLibraryLoaded"];
   [mediaLibrary_.mediaSources objectForKey: MLMediaSourcePhotosIdentifier ];  
// starts asynchronous loading

During runtime, this gets executed occasionally:

   album_ = albums_[album_id];
   [album_ addObserver: self
            forKeyPath: @"mediaObjects"
               options: 0
               context: @"mediaObjects"];
   [album_ mediaObjects];

I have checked using log message that addObserver: does actually get executed.

And this is my key value observer:

- (void) observeValueForKeyPath: (NSString *) keyPath   ofObject: (id) object
                        change: (NSDictionary *) change context: (void *) 
   MLMediaSource * mediaSource = [mediaLibrary_.mediaSources objectForKey: 
   if ( context == (__bridge void *) @"mediaLibraryLoaded" )
       [mediaSource addObserver: self
                     forKeyPath: @"rootMediaGroup"
                        options: 0
                        context: (__bridge void *) @"rootMediaGroupLoaded"];
       [mediaSource rootMediaGroup];                                           
// start next phase: load groups
   else if ( context == (__bridge void *) @"rootMediaGroupLoaded" )
       MLMediaGroup *albums = [mediaSource mediaGroupForIdentifier: 
       for ( MLMediaGroup * album in albums.childGroups )
           NSString * albumName = [album.attributes objectForKey: @"name"];
           [self logMessage: [NSString stringWithFormat: @"album name = %@", 
albumName] asError: NO];
           if ( albumName )
               [albums_ addObject: album ];
   else if ( context == (__bridge void *) @"mediaObjects" )
       NSArray * mediaObjects = album_.mediaObjects;       
       for ( MLMediaObject * mediaObject in mediaObjects )
           if ( mediaObject.mediaType != MLMediaTypeImage )
               // we still get movies as mediaObjects, which might be contained 
in a Photos album

           NSURL * url  = mediaObject.URL;
           [photoPaths_ addObject: url.path];

Again, I checked with a log message that the KVO never gets invoked in the case 
when the screen saver hangs
(i.e., I am positive the hanging is not caused by an infinite loop or similar 
in the KVO.)


Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to arch...@mail-archive.com

Reply via email to