react-native-cameraroll: iOS: Sort order unexpected

When attempting to request all photos, photos are returned sorted by collection, instead of being a complete list. This makes it difficult to help users pick their most recent photos taken. Example:

RNCCameraRoll.getPhotos({
  first: 20,
  assetType: 'Photos',
  groupTypes: 'All',
})

Will return the 20 latest photos as expected, in the simulator. However, on a real device this may or may not return the most recent 20 photos, as it’ll sort the Collections by “end date” which will essentially show the album that was last modified, and show all photos from that album regardless of their date.

A javascript workaround is theoretically possible but it would require to fetch all photos (e.g. first: 9999..) and then sort by timestamp, which goes against the purpose of using cursors.

After tinkering with the source, it’s clear that the issue arises from first grabbing collections, then assets. Regardless of the sortDescriptor, everything will be grouped by collection:

    PHFetchResult<PHAssetCollection *> *const assetCollectionFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:collectionType subtype:collectionSubtype options:collectionFetchOptions];
    [assetCollectionFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull assetCollection, NSUInteger collectionIdx, BOOL * _Nonnull stopCollections) {
      // Enumerate assets within the collection
      PHFetchResult<PHAsset *> *const assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:assetFetchOptions];

Proposed solution: I propose that we add a condition that if groupTypes is "All", then we use fetchAssetsWithOptions instead of enumerating collections. No change required to sortDescriptor

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 5
  • Comments: 17 (6 by maintainers)

Commits related to this issue

Most upvoted comments

In case someone stumbles upon this issue, the current workaround I found was to massively over-fetch and sort manually in JS:

RNCCameraRoll.getPhotos({
  first: 2000,
  assetType: 'Photos',
  groupTypes: 'All',
}).then((response) => {
  response.edges.sort((a, b) => b.node.timestamp - a.node.timestamp);
  return response;
}).then((response) => {
  // normal image handling here
});

I’ll see if I can submit a PR today or tomorrow. Otherwise, anyone should feel free to implement this.

I have same problem. Is there any update?

I think it was fixed, merged, and resolved entirely unless there is a regression.

Coming from expo here

My .getPhotos() in production is working perfectly, but after upgrading SDK from 32 to 34, and React from 16.3.1 to 16.8.3 introduced this breaking change.

Had some issues with this as well. Seems like this is still broken when trying to get both videos and photos, at least that’s what I get. I does work as expected when setting assetType: 'photos'. However, I’m not sure what fails when loading the videos as well.

@ramon90 it does yes. That’s another bug I chose to omit from here. You’ll need to remove the duplicates as well. Run result through “uniqBy” (from lodash or similar) on the node image url