Eliminate the iOS startup race between asynchronous SharedImage plugin
registration and the first shared-image check. Previously the initial
check fired on a fixed 1000ms timer that only assumed the native plugin
(registered by AppDelegate with retries from T+500ms) was ready, so a
slow registration could make the first getSharedImage() call throw and
miss a cold-start share.
Replace the fixed delay with waitForSharedImagePluginReady(), which
probes the plugin via a read-only hasSharedImage() call and retries
within a bounded budget (10 attempts, 300ms apart) until the plugin
actually responds. The initial check runs only once readiness is
confirmed, with a best-effort fallback if the budget is exhausted.
Scope is limited to the initial startup check on iOS. appStateChange,
appUrlOpen/handleDeepLink, router navigation, share processing, Android
behavior, and all native Swift code are unchanged. Temporary
share-target diagnostics are preserved and extended with startup
readiness logging.
Document the change as a Phase 2A section in
doc/share-target-ios-audit.md.
Stop deleting App Group metadata and image files in getSharedImageData()
so retrieval is read-only while preserving the existing plugin API shape.
Document removed deletion paths in the iOS share target audit.
Store shared images as <shareId>.<ext> in the App Group container while
keeping the original filename in metadata, preventing on-disk collisions
without changing retrieval, deletion, or JS consumer behavior.
Generate a UUID per incoming share in the Share Extension, persist it
as sharedPhotoShareId in App Group metadata, and add [ShareTarget] logs
for receive/store/retrieve events without changing retrieval or deletion.
Document the Share Extension → App Group → main app flow, including
read/write/delete points, startup detection hooks, timing behavior,
and race conditions to support share-target reliability work.