Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit on Get photo assets #11

Closed
firsname-markus opened this issue Feb 25, 2017 · 13 comments
Closed

Limit on Get photo assets #11

firsname-markus opened this issue Feb 25, 2017 · 13 comments
Assignees
Milestone

Comments

@firsname-markus
Copy link

When fecthing all photos, max 393 photos is returned. There are 500+ photos in a roll. I tried increase the interval and lower the limit but still no help.

Any ideas?

@domax domax added the iOS label Feb 26, 2017
@domax domax changed the title Limit on Get photo assets (iOs) Limit on Get photo assets Feb 26, 2017
@domax
Copy link
Owner

domax commented Feb 26, 2017

@firsname-markus : Did you use limit option for bundle-related fetching?
If you don't use it, then you'll have a problem with memory in your device. I strongly recommend to use limit for huge rolls.

@firsname-markus
Copy link
Author

firsname-markus commented Feb 26, 2017

@domax : Yep, i tried with different combos like --> limit: 10 interval:100, limit: 30 interval: 100, limit: 100 interval: 1000... No matter what i always get 393 photos.

I'm testing with iPhone 7 and i havent noticed any freezing or slowing no matter what combo of settings, but still only 393 photos..

@domax domax added the bug label Feb 27, 2017
@domax domax added this to the 1.0.8 milestone Feb 27, 2017
@domax domax self-assigned this Feb 27, 2017
@domax
Copy link
Owner

domax commented Feb 27, 2017

That shouldn't happen then. The only reason that may prevent fetching is that your 394th photo has some absent, wrong or corrupted attribute. Are you able to run your app in Xcode and catch in debugger what happens with 394th photo in your roll?

@domax
Copy link
Owner

domax commented Feb 27, 2017

I tested fetching roll with more than 2.5k photos on iPhone 6

@firsname-markus
Copy link
Author

firsname-markus commented Feb 27, 2017

@domax first of all, thanks for the support :)
Photo #393 seems to give me "Error in Success callbackId: Photos1574288256 : TypeError: undefined is not an object (evaluating 'photos[0].id') (console-via-logger.js, line 173)" and "TypeError: undefined is not an object (evaluating 'photos[0].id')"

Fecthing photo #393 for some reason returns an empty object..

EDIT: Actually #392 is the last working fetch, after that only empty object is returned. If i put offset to for example 410, still Photos are returning [] and fails on that. Weird because all the other apps in my phone shows all the photos just fine

@domax
Copy link
Owner

domax commented Feb 28, 2017

Could you please provide your snippet of code you use.

@firsname-markus
Copy link
Author

I have a clean PhoneGap project with only this inside deviceReady..

        Photos.photos({ "limit": 10, "interval": 100 },
            function(photos) {
                console.log(JSON.stringify(photos));
            },
            function(error) {
                console.log(JSON.stringify(error));
            }
        );

as I said earlier i have tried with different limit ( 1-100), interval (30-3000) and offset (395++). I have also tried to determine the album. Each will fetch without freezing, slacking or other problems until photo #392. It doesn't matter which photo is #392. #393 always returns []. IF offset is for example 395 it returns []

I'm totally out of ideas

@domax
Copy link
Owner

domax commented Mar 3, 2017

OK, got it.

First of all - interval doesn't affect the content of fetching data - it's just a background thread's pause between bundles. A default of 30ms is enough as a rule.

Photos.photos() method returns you bundles. If you don't specify limit option, you'll get only one callback with a bundle. In case you specify limit option, you may get several callbacks, where each of them will have a bundle - even empty one.
That allows you to detect the fact that fetching process is finished (see example 2 for details). So, empty last bundle is a normal.

It's a second question - why it is empty. That may happen in following cases:

  1. Amount of all available photos is multiple of specified limit value - e.g. limit == 10 but all available photos is 100: 100 % 10 == 0 (looks like it's not your case).
  2. There are filtered out images from your last bundle: a native implementation of Photos.photos() method contains several very simple filters to get only "valid" images:
    • asset should be only PHAssetMediaTypeImage;
    • it's name must match to following case insensitive regular expression: ^(.+)\.([a-z]{3,4})$;
    • uppercased name extension must be one of: "JPG", "JPEG", "PNG", "GIF", "TIF" or "TIFF";

2nd I believe is your case.

So far you have no any errors during fetching, I suppose you have only 393 available photos in your roll. To make sure try to use the following snippet:

Photos.photos(console.log, console.error);

This will try to get all available photos on your "Camera Roll" "smart" album at once and drop it all into webview log. Please notice that calling photos() method w/o collections argument gets photos only from one specific collection/album - "Camera Roll".

You may try to:

  1. Get all the collections;
  2. Then request photos from all of these collections.

Smth like that:

Photos.collections({"collectionMode": "ALBUMS"},
    function(albums) {
        var ids = [];
        albums.forEach(function(album){ids.push(album.id)});
        console.log(ids);
        Photos.photos(ids, {limit:100}, console.log, console.error);
    }, console.error);

Since it's iOS, you may try "MOMENTS" and "SMART" collectionModes as well.

@firsname-markus
Copy link
Author

Photos.photos(console.log, console.error);

--> returns 389 photos

Photos.collections({"collectionMode": "ALBUMS"},
    function(albums) {
        Photos.photos(albums, console.log, console.error);
    }, console.error);

--> returns 389 photos

Photos.collections({"collectionMode": "SMART"},
    function(albums) {
        Photos.photos(albums, console.log, console.error);
    }, console.error);

--> returns 389 photos

Photos.collections({"collectionMode": "MOMENTS"},
    function(albums) {
        Photos.photos(albums, console.log, console.error);
    }, console.error);

--> returns 389 photos

I have 569 photos in roll, all of them are either JPG, GIF or PNG

domax added a commit that referenced this issue Mar 4, 2017
There is a bug in assetResourcesForAsset - it doesn't work properly for all the images.
Moreover, it obtains resource for very long time - too long for just a file name.
Implementation was replaced with getting file name from asset properties directly - quite hacky however.
@domax
Copy link
Owner

domax commented Mar 4, 2017

Well, looks like I found where bug was - see comment for commit above.
@firsname-markus please check it (npm package 1.0.8 is published as well).
Just in case, I added code that gathers all skipped photos (iOS only) - they're logged with prefix skipped asset in Xcode output - I'll remove this code in future releases.

@domax domax closed this as completed Mar 13, 2017
@orgotech-robin
Copy link

Hey, I also got this issue.

I got 3,3k images but can only find 2,8k of them. My xCode output is filled with the skipped assets. Where I can see the ID of the images but I can't seem to find them in my js response.

Image counter:

Photos.photos({ "limit": 10, "interval": 100 },
        function(photos) {
            imgCounter = imgCounter + 10;
            console.log(imgCounter);
        },
        function(error) {
            console.log(error);
        }
    );

What should I do to get the ID:s of the skipped assets?

@orgotech-robin
Copy link

Do you still develop this plugin for Cordvoa? @domax

@domax
Copy link
Owner

domax commented Dec 15, 2018

@orgotech-robin

What should I do to get the ID:s of the skipped assets?

Assets are skipped in 3 cases:

  1. if asset has no file name (line 190 in CDVPhotos.m)
  2. if name of asset doesn't match the regexp ^(.+)\.([a-z]{3,4})$ (line 196 in CDVPhotos.m)
  3. if file extension (2nd regexp group) isn't one of supported: jpg, jpeg, png, gif, tif, tiff (line 200 in CDVPhotos.m)

All these cases depend on (NSString*) getFilenameForAsset:(PHAsset*)asset method that extracts the filename - that's the most critical place here. I tried to use different ways to retrieve asset filename. The most correct way is to use requestContentEditingInputWithOptions method of asset, but it's asynchronous, that complicates everything alot (see commented lines 394-399 in CDVPhotos.m). So now is kinda hack is used - undocumented attribute "filename" of asset - maybe that's the root cause of asset skipping.

Do you still develop this plugin for Cordvoa?

Now I have neither time nor motivation for that. Feel free to take support of this plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants