2015-05-05 10 views
5

Uso il framework Photos (ovvero PhotoKit). Nella mia app ho bisogno di raccogliere momenti (che sono di tipo PHAssetCollection). PHAssetCollection ha una proprietà di CLLocation *approximateLocation.Filtro PHAssetCollections nel raggio di CLLocationCoordinate2d

Tuttavia non riesco a far funzionare il NSPredicate quando recupero Moments da PhotoKit.

-(void)getMomentsNearCoordinate:(CLLocationCoordinate2D)coordinate completionBlock:(PKAssetManagerArrayBlock)completionBlock{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     PHFetchOptions *options = [[PHFetchOptions alloc] init]; 
     options.predicate = [NSPredicate predicateWithFormat:@"approximateLocation.coordinate.latitude < 37.0"]; 

     self.moments = [PHAssetCollection fetchMomentsWithOptions:options]; 

     // Convert PHCollection into NSArray 
     NSMutableArray *momentsArray = [[NSMutableArray alloc]initWithCapacity:self.moments.count]; 
     [self.moments enumerateObjectsUsingBlock:^(PHAssetCollection *moment, NSUInteger idx, BOOL *stop) { 
      [momentsArray addObject:moment]; 
     }]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      completionBlock([NSArray arrayWithArray:momentsArray]); 
     }); 
    }); 
} 

Il debugger si arresterà su

self.moments = [PHAssetCollection fetchMomentsWithOptions:options]; 

con l'errore:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported predicate in fetch options: approximateLocation.coordinate.latitude < 37'

Questo sembra strano dato che posso usare NSPredicate per filtrare per startDate o endDate.

In ogni caso, dopo ho pensato che mi piacerebbe provare il NSPredicate con il blocco:

-(void)getMomentsNearCoordinate:(CLLocationCoordinate2D)coordinate completionBlock:(PKAssetManagerArrayBlock)completionBlock{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     PHFetchOptions *options = [[PHFetchOptions alloc] init]; 
     options.predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { 
      // Logic goes here 
      return YES; 
     }]; 

     self.moments = [PHAssetCollection fetchMomentsWithOptions:options]; 

     // Convert PHCollection into NSArray 
     NSMutableArray *momentsArray = [[NSMutableArray alloc]initWithCapacity:self.moments.count]; 
     [self.moments enumerateObjectsUsingBlock:^(PHAssetCollection *moment, NSUInteger idx, BOOL *stop) { 
      [momentsArray addObject:moment]; 
     }]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      completionBlock([NSArray arrayWithArray:momentsArray]); 
     }); 
    }); 
} 

Anche in questo caso il debugger si interrompe al

self.moments = [PHAssetCollection fetchMomentsWithOptions:options]; 

con un messaggio di errore diverso:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported predicate in fetch options: BLOCKPREDICATE(0x27d338)'

Alla fine ho ricordato di aver letto in CloudKit documentation che hanno aggiunto un nuovo supporto per il file tering per distanza. Tuttavia questo è per CKQuery, non NSPredicate. Ho deciso di provarlo comunque. Io uso il mio coordinata per fare un CLLocation quindi chiamare:

-(void)getMomentsNearLocation:(CLLocation*)location completionBlock:(PKAssetManagerArrayBlock)completionBlock{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     PHFetchOptions *options = [[PHFetchOptions alloc] init]; 
     options.predicate = [NSPredicate predicateWithFormat:@"distanceToLocation:fromLocation:(%K,%@) < %f", 
          location, 
          2.0]; 

     self.moments = [PHAssetCollection fetchMomentsWithOptions:options]; 

     // Convert PHCollection into NSArray 
     NSMutableArray *momentsArray = [[NSMutableArray alloc]initWithCapacity:self.moments.count]; 
     [self.moments enumerateObjectsUsingBlock:^(PHAssetCollection *moment, NSUInteger idx, BOOL *stop) { 
      [momentsArray addObject:moment]; 
     }]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      completionBlock([NSArray arrayWithArray:momentsArray]); 
     }); 
    }); 
} 

avete indovinato. Errore:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CLLocation rangeOfString:]: unrecognized selector sent to instance 0x19e3e350' 

Nel frattempo mi limiterò a scorrere l'elenco dei PHAssetCollections e calcolare manualmente se è vicino alla CLLocation. Questo sarà molto meno efficiente.

+0

Hai mai funzionato? –

+0

No. Non ho incasinato il codice molto dal post originale. Si prega di postare se si ottiene che funziona. Forse funziona su iOS 10? – VaporwareWolf

risposta

0

Se si guarda alla tabella 1 della documentazione PHFetchOptions, vedrete che è possibile utilizzare solo i seguenti tasti per il filtraggio dei predicati di PHAssetCollections:

SELF 
localIdentifier 
localizedTitle (or title) 
startDate 
endDate 
estimatedAssetCount 

se si desidera filtrare un PHCollection (al contrario di un PHAssetCollection), allora si sono limitati alle seguenti chiavi:

SELF 
localIdentifier 
localizedTitle (or title) 
startDate 
endDate 

Niente di simile "approximateLocation" è una chiave di supporto. Ma aspetta! IlTitolo localizzato è generalmente un nome di luogo. Non l'ho visto altrimenti. Quindi, potresti essere in grado di ottenere risorse tramite raccolte temporali di filtro dei predicati

Problemi correlati