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.
Hai mai funzionato? –
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