2015-05-05 29 views
5

Używam frameworku Zdjęcia (aka PhotoKit). W mojej aplikacji muszę zbierać momenty (które są typu PHAssetCollection). PHAssetCollection ma właściwość CLLocation *approximateLocation.Filtruj PHAssetKolekcje w promieniu CLLocationCoordinate2d

Jednak nie mogę uzyskać NSPredicate do pracy po odzyskaniu momentów z 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]); 
     }); 
    }); 
} 

Debuger zatrzyma na

self.moments = [PHAssetCollection fetchMomentsWithOptions:options]; 

z błędem:

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

To wydaje się dziwne, ponieważ mogę używać NSPredicate filtrować przez startDate lub endDate.

Zresztą obok pomyślałem, że spróbować NSPredicate z bloku:

-(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]); 
     }); 
    }); 
} 

Ponownie debugger zatrzymuje się

self.moments = [PHAssetCollection fetchMomentsWithOptions:options]; 

z innym komunikatem o błędzie:

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

W końcu przypomniałem sobie, że przeczytałem w CloudKit documentation, że dodali nowe wsparcie dla fil tering według odległości. Jednak jest to dla CKQuery, a nie NSPredicate. Postanowiłem jakoś spróbować. Używam koordynować zrobić CLLocation następnie zadzwonić:

-(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]); 
     }); 
    }); 
} 

Zgadłeś. Błąd:

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

W tym czasie ja po prostu iterację listy PHAssetCollections i ręcznie obliczyć, czy to w pobliżu CLLocation. Będzie to znacznie mniej wydajne.

+0

Czy zdarzyło Ci się, że to działa? –

+0

Nie. Nie zawarłem zbyt wiele kodu od czasu pierwotnego wpisu. Opublikuj ponownie, jeśli działa. Może działa na iOS 10? – VaporwareWolf

Odpowiedz

0

Jeśli spojrzeć na tablicy 1 dokumentacji PHFetchOptions, widać, że można używać tylko następujących klawiszy do filtrowania orzecznikiem PHAssetCollections:

SELF 
localIdentifier 
localizedTitle (or title) 
startDate 
endDate 
estimatedAssetCount 

jeśli chcesz filtrować PHCollection (w przeciwieństwie do PHAssetCollection), wtedy są ograniczone do następujących klawiszy:

SELF 
localIdentifier 
localizedTitle (or title) 
startDate 
endDate 

Nic przypominający „approximateLocation” jest kluczowym wsparciem. Ale czekaj! ZlokalizowanyTytuł to zazwyczaj nazwa miejsca. Nie widziałem tego inaczej. Tak więc możesz być w stanie zdobyć zasoby według momentu zbioru filtrów

Powiązane problemy