6

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でフィルタリングするために使用できるため、これは奇妙に思えます。startDateendDate

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。とにかくやってみることにしました。座標を使用してCLLocationthen 呼び出しを行います。

-(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ます。これははるかに効率が悪いでしょう。

4

1 に答える 1