Photos フレームワーク (aka PhotoKit
) を使用しています。私のアプリでは、モーメント (タイプはPHAssetCollection
) を収集する必要があります。PHAssetCollection
のプロパティがありCLLocation *approximateLocation
ます。
ただしNSPredicate
、PhotoKit から Moments を取得すると、 が動作しません。
-(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]);
});
});
}
デバッガーが停止します
self.moments = [PHAssetCollection fetchMomentsWithOptions:options];
エラーで:
*** キャッチされない例外 'NSInvalidArgumentException' が原因でアプリを終了します。理由: 'フェッチ オプションでサポートされていない述語:approximationLocation.coordinate.latitude < 37'
またはNSPredicate
でフィルタリングするために使用できるため、これは奇妙に思えます。startDate
endDate
NSPredicate
とにかく、次にwith ブロックを試してみようと思いました:
-(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]);
});
});
}
再びデバッガは次の場所で停止します
self.moments = [PHAssetCollection fetchMomentsWithOptions:options];
別のエラー メッセージ:
*** キャッチされない例外 'NSInvalidArgumentException' が原因でアプリを終了します。理由: 'フェッチ オプションでサポートされていない述語: BLOCKPREDICATE(0x27d338)'
最後に、距離によるフィルタリングの新しいサポートが追加されたことをCloudKit のドキュメントで読んだことを思い出しました。ただし、これは のためのものCKQuery
であり、 ではありませんNSPredicate
。とにかくやってみることにしました。座標を使用してCLLocation
then 呼び出しを行います。
-(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]);
});
});
}
当たってるよ。エラー:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CLLocation rangeOfString:]: unrecognized selector sent to instance 0x19e3e350'
それまでの間、 のリストを繰り返し処理し、PHAssetCollections
の近くにあるかどうかを手動で計算しCLLocation
ます。これははるかに効率が悪いでしょう。