PHFetchResult 自定义排序:按天排序的项目,最旧的照片优先

PHFetchResult custom sorting: items ordered by day, oldest photos first

我愿意按天排序我的结果,以便最旧的照片显示在最上面。

我目前正在使用 PHAsset fetchAssetsWithMediaType:

获取照片
@property PHFetchResult *photos;

self.photos = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];

理想情况下,我希望结果按天排序,最早的照片排在最前面。像这样:

[11 Dec]
Photo #20 with creation time 17:00
Photo #21 with creation time 18:30
Photo #22 with creation time 19:00
Photo #23 with creation time 20:40
Photo #24 with creation time 21:00
[10 Dec]
Photo #16 with creation time 10:30
Photo #17 with creation time 11:00
Photo #18 with creation time 12:20
Photo #19 with creation time 13:00
[9 Dec]
Photo #14 with creation time 16:30
Photo #15 with creation time 17:00

我看到我可以传递带有谓词和一些排序描述符 (https://developer.apple.com/reference/photos/phfetchoptions) 的 PHFetchOptions 对象,你能建议我如何指定它们吗(我相信我应该使用 creationDate 属性对它们进行排序)所以我会得到想要的订单吗?

你应该使用PHFetchOptions

    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
    fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:true]];
    PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];

PHFetchOptions 接受 sortDescriptors,但它会忽略自定义比较(我相信因为它只是执行 SQL 查询),如此处所写 (https://developer.apple.com/reference/photos/phfetchoptions/1624771-sortdescriptors):

Photos does not support sort descriptors created with the sortDescriptorWithKey:ascending:comparator: method.

答案是你应该将结果移动到一个新的 NSArray 中,然后在获取它们之后对其进行排序:

- (void)loadPhotos
{
    PHFetchResult *photosResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];

    self.photos = [@[] mutableCopy];
    for(PHAsset *asset in photosResult){
        [self.photos addObject:asset];
    }
    [self.photos sortUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"creationDate"
                                                                      ascending:YES
                                                                     comparator:^NSComparisonResult(NSDate *dateTime1, NSDate *dateTime2) {
                                                                         unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
                                                                         NSCalendar* calendar = [NSCalendar currentCalendar];

                                                                         NSDateComponents* components1 = [calendar components:flags fromDate:dateTime1];
                                                                         NSDate* date1 = [calendar dateFromComponents:components1];

                                                                         NSDateComponents* components2 = [calendar components:flags fromDate:dateTime2];
                                                                         NSDate* date2 = [calendar dateFromComponents:components2];

                                                                         NSComparisonResult comparedDates = [date1 compare:date2];
                                                                         if(comparedDates == NSOrderedSame)
                                                                         {
                                                                             return [dateTime2 compare:dateTime1];
                                                                         }
                                                                         return comparedDates;
                                                                     }
                                         ]]];

}

我没有用巨大的相机胶卷测试这个解决方案(这里的排序是在内存中完成的,它可能是一个性能瓶颈),但我希望这能有所帮助。