flutter_photo_manager
flutter_photo_manager copied to clipboard
[How to use] Sort result like Camera Roll in iOS
Platforms
iOS
Description
Is there any way that can get sort result like iOS camera roll (Recent)?
My code
I tried createDate and modifiedDate. but result is not same with Camera roll.
CustomFilter.sql(
where:
'${CustomColumns.base.mediaType} = 2',
orderBy: [
OrderByItem(CustomColumns.base.createDate, false),
],
)
Can I get sort result like Camera Roll ? it is no issue before photo_manager 3.1.1
This issue is side effct when I want to upgrade photo_manager for 2.x to 3.2. https://github.com/fluttercandies/flutter_photo_manager/issues/1150
Because this behavior change, I need to add orderby for CustomFilter.sql
CustomFilter.sql(
where:
'${CustomColumns.base.mediaType} = 2 OR ${CustomColumns.darwin.mediaSubtypes} & 8 = 8',
orderBy: [
OrderByItem(CustomColumns.base.createDate, false),
],
)
in photo_manager 2.8. I just use FilterOptionGroup(), the result is what I want. (same with camera roll)
I face the same issue.
The result is still unexpected after adding the OrderByItem(CustomColumns.base.createDate, false). (So as OrderByItem(CustomColumns.base.modifiedDate, false))
Process ran to getAssetListPaged would get the results with wrong order.
(NSArray<PMAssetEntity *> *)getAssetListPaged:(NSString *)id type:(int)type page:(NSUInteger)page size:(NSUInteger)size filterOption:(NSObject<PMBaseFilter> *)filterOption {
NSMutableArray<PMAssetEntity *> *result = [NSMutableArray new];
PHFetchOptions *options = [PHFetchOptions new];
PHFetchResult<PHAssetCollection *> *fetchResult =
[PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[id]
options:options];
if (fetchResult && fetchResult.count == 0) {
return result;
}
PHAssetCollection *collection = fetchResult.firstObject;
PHFetchOptions *assetOptions = [self getAssetOptions:type filterOption:filterOption];
PHFetchResult<PHAsset *> *assetArray = [PHAsset fetchAssetsInAssetCollection:collection
options:assetOptions];
NSLog(@"assetOption: %@", assetOptions);
NSLog(@"assetArray: %lu", (unsigned long)[collection obtainAssetCount:assetOptions]);
if (assetArray.count == 0) {
return result;
}
NSUInteger startIndex = page * size;
NSUInteger endIndex = startIndex + size - 1;
NSUInteger count = assetArray.count;
if (endIndex >= count) {
endIndex = count - 1;
}
BOOL imageNeedTitle = filterOption.needTitle;
BOOL videoNeedTitle = filterOption.needTitle;
for (NSUInteger i = startIndex; i <= endIndex; i++) {
NSUInteger index = i;
if (assetOptions.sortDescriptors == nil) {
index = count - i - 1;
}
PHAsset *asset = assetArray[index];
BOOL needTitle = NO;
if ([asset isVideo]) {
needTitle = videoNeedTitle;
} else if ([asset isImage]) {
needTitle = imageNeedTitle;
}
PMAssetEntity *entity = [self convertPHAssetToAssetEntity:asset needTitle:needTitle];
[result addObject:entity];
[cacheContainer putAssetEntity:entity];
}
return result;
}
It seems that getAssetOptions will return different statement. Maybe the change causes the wrong order.
Use the none option. (The where is empty and the filter is empty).
To add a log for next patch: changes.patch git apply changes.patch
diff --git a/example/lib/page/custom_filter/path_list.dart b/example/lib/page/custom_filter/path_list.dart
index fc08122..8fd621e 100644
--- a/example/lib/page/custom_filter/path_list.dart
+++ b/example/lib/page/custom_filter/path_list.dart
@@ -59,6 +59,9 @@ class PathList extends StatelessWidget {
position: ToastPosition.bottom,
);
});
+ for (final asset in path.filterOption.toMap().entries) {
+ print('${asset.key}: ${asset.value}');
+ }
Navigator.push(
context,
MaterialPageRoute(
I get next log:
{where: , orderBy: [], needTitle: false, containsPathModified: false}
I use the example of the library:
https://github.com/user-attachments/assets/41735161-ed68-4ad0-a37b-2c64a707ba88
@CaiJingLong thanks your reply.
The problem is, aftrer photo_manager 3.2, it I want "Video + livePhoto"
I need to use where to filter content. (https://github.com/fluttercandies/flutter_photo_manager/issues/1150).
Is there anyway support this case? "Video + Live Photo", order is same with cameraRoll, (order is descend).
I can get this kind result in photo_manager 3.1, but not in 3.2. (My current solution is rollback to 3.1)
Thanks.
@CaiJingLong is it possiable ? I'm currently using photo_manager 3.1. I'm worried that one day I'll need to upgrade to flutter 3.2+, but I can't get the results I need. XD
I've tried Photo Manager 3.4.0, but I've noticed that photos and videos received through AirDrop appear in a different order compared to the Camera Roll. In the Camera Roll, newly received AirDrop media appears at the top. However, in the search results of Photo Manager 3.4.0, the media is sorted by creation time.
@CaiJingLong I want a video picker that include all video + livePhoto, and sort like "Recent in Camera Roll", Finally I found a combination that met my requirements
- set request tyoe to
RequestType.common(include all videos and photos) - set filteroption to
FilterOptionGroup(onlyLivePhotos: true);(filter non-live photo)
The result is what I want.
But, it have assert here https://github.com/fluttercandies/flutter_photo_manager/blob/9c8b7f9d9eaf6343638a755c7825bea1fb5bd0c5/lib/src/types/entity.dart#L224
assert(
type == RequestType.image || !filterOption.onlyLivePhotos,
'Filtering only Live Photos is only supported '
'when the request type contains image.',
);
Is it possiable change code to
assert(
type.containsImage() || !filterOption.onlyLivePhotos,
'Filtering only Live Photos is only supported '
'when the request type contains image.',
);
The assertion has been removed in v3.5.0.
In my opinion, the filter options group applies more conditions to the query. Simply set breakpoints in the native debugging can easily find out the core condition to produce the natural album order.
Having some time playing iOS Gallery. Here is the conclusion:
- The "Library" (All Photos Library) uses the creation date in descending order.
- ~The "Recents" album uses the modified date in descending order.~
In iOS 18, these two entries are combined and the sort options are provided.
So choose the fitting order according to your use case.
EDIT: The "Recents" album uses zero predicate queries and sorts the results in descending order.
You’re absolutely right. I ran into the same issue — when I fetched using the smartAlbumUserLibrary type and displayed the assets in reverse order in the collection view, it solved the problem.
During this process, I found that the sortDescriptors key "addedDate" actually provides the exact ordering based on the most recently added items. Unfortunately, Apple hasn’t made this key publicly available yet. It only works on iOS 26 beta builds.
So for now, choosing between creation date (Library) and modification date (Recents) sorting really depends on the use case.