feat(imagepicker): use PHPickerViewController on iOS, add onProgress - #681
sitefinitysteve wants to merge 9 commits into
Conversation
Replace the QBImagePickerController pod with the system photo picker
(iOS 14+). The public API is unchanged: create(), authorize(), present()
and the ImagePickerSelection shape all behave as before, and cancel still
rejects with Error('Canceled').
- No CocoaPods dependency any more; the picker runs out of process.
- authorize() is now optional. With library access, picks resolve to
their PHAsset as before; without it, the picker's file copy is used.
- Ordered multi-select honours maximumNumberOfSelection.
- The iOS-only UI options (prompt, column counts, etc.) are marked
deprecated since the system picker owns its own UI.
iOS copies now run on a global dispatch queue and Android uses the async File.copy(), so large videos no longer block the UI while the picker resolves. Android also drops the two duplicated inline handlers in favour of a shared toSelection() helper. Public API is unchanged.
iOS streams per-item download progress (iCloud items via PhotoKit and item-provider NSProgress); Android has nothing to report so it emits a single 100% per item. Demo shows a progress bar while items resolve.
…ving; demo: fix first-tap no-op, no cap, single scroll, clear button
Adds a 19 second screen recording from an iPhone 15 Pro Max to packages/imagepicker/images and links it from the README demo section. Why a video in the repo: the PHPicker change is easiest to judge by watching it. The recording was taken with the app's photo access set to None, so it shows the part that is hard to reproduce on a simulator: the system picker still opens, iOS shows its "Private Access to Photos" banner, the selected items come back as file copies, and the demo's progress rows update as each item loads. Reviewers can check the behaviour without setting up a device. The file is 8.4 MB, which is why it lives next to the other plugin media (compare packages/animated-circle/images) rather than being embedded in the README.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ScreenRecording_09-11-2026.13-56-49_1.movHere's what it looks like, the progress streaming is faked, they're local images, but... it's working. Much nicer picker and gives access to the phones collections where the previous one didn't (not to mention removing a cocoapod) |
What
Replaces the QBImagePickerController CocoaPod on iOS with the system
PHPickerViewController, and adds an optionalonProgresscallback on both platforms.Why
PHPickerViewControllerships with iOS 14+, so the plugin no longer has a CocoaPods dependency at all.iOS behaviour
authorize()still requests library access. When granted, picks resolve to theirPHAssetas before.authorize()was never called,present()still opens the picker. Items outside the app's access fall back to a copy handed over by the picker's item provider, stored in the temp folder and exposed throughpath/asset. A single selection can mix both. This is documented in the README.present()waits for the app to be active and presents on the main thread; the picker is dismissed before the promise resolves.minimumNumberOfSelection,showsNumberOfSelectedAssets,prompt,numberOfColumnsInPortraitandnumberOfColumnsInLandscapeare accepted but ignored, since the system picker owns its UI. They are marked@deprecatedin the typings and README.nativescript.platforms.iosbumped to~9.0.0.Android
onProgressemits a singlefraction: 1per item once it is ready (there is no download progress to report).copyToAppFoldernow usesFile.copy()off the main thread instead of a synchronous read/write.Demo app
The demo page was reworked to show the progress ticks, render multiple picks in one scrolling list, and add a Clear button. It presents the picker regardless of the permission result so the no-access path can be exercised.
One thing to be clear about: the progress bar in the demo (and in the recording) is paced. Items already on the device resolve in a few milliseconds, so the bar would jump straight to 100% and there would be nothing to see. The demo queues every
onProgresstick it receives and holds each one on screen for about 600 ms before showing the next. The values it displays are exactly what the plugin reported, only the timing is slowed for the eye. The plugin side is not faked:onProgressis a real stream fromPHPickerViewController's item provider (or PhotoKit when the app has library access), and an iCloud item on a real device produces several ticks with increasing fractions as the download runs. An app that subscribes to it can drive a progress bar directly without the demo's pacing.Recording
packages/imagepicker/images/imagepicker-ios-phpicker.movis a 19 second recording from an iPhone 15 Pro Max with photo access set to None: the picker opens, iOS shows the "Private Access to Photos" banner, and the picks come back as file copies with progress rows. If you would rather not carry the binary in the repo, say so and I will drop that commit and attach the clip here instead.Tested