Include the existing native sharedPhotoShareId in the SharedImage getSharedImage() result so the web layer can identify the current share. Add shareId to the native result dictionary and plugin response (NSNull on the no-image branch), and add shareId: string to the TypeScript SharedImageResult interface. This surfaces a value that was already produced natively (previously used only for logging) so application code can later pass it to markProcessed(). No behavior changes beyond exposing the value; Android untouched. Updates doc/share-target-ios-audit.md accordingly.
3.8 KiB
iOS Share Target Audit
Date: 2026-06-30 Platform: iOS only (Android unchanged) Status: Phase 1D complete — explicit share completion API added (not yet called)
Purpose
This document tracks the native iOS share-target lifecycle and the Capacitor API surface exposed to the web/TypeScript layer. It is updated as each phase lands.
Lifecycle Overview
- The Share Extension (
ShareViewController.swift) receives an image, writes it to the App Group container, records metadata in App GroupUserDefaults, assigns ashareId(UUID), sets thesharedPhotoReadyflag, and opens the main app viatimesafari://. - The main app reads the shared image through the
SharedImageCapacitor plugin. - The application layer processes the image, then (in a future phase) signals
explicit completion via
markProcessed(shareId).
App Group Storage Keys
Stored in UserDefaults(suiteName: "group.app.trentlarson.timesafari.share"):
| Key | Set by | Meaning |
|---|---|---|
sharedPhotoFileName |
Share Extension | Original display filename |
sharedPhotoFilePath |
Share Extension | On-disk filename in App Group container |
sharedPhotoShareId |
Share Extension | Current pending share identifier (UUID) |
sharedPhotoReady |
Share Extension | Flag indicating a share is ready |
sharedPhotoProcessedShareId |
Main app (markProcessed) |
Last shareId explicitly marked processed (Phase 1D) |
Capacitor API (SharedImage plugin)
The plugin is registered as SharedImage and is implemented in:
- Native iOS:
ios/App/App/SharedImagePlugin.swift(delegates toios/App/App/SharedImageUtility.swift) - Web stub:
src/plugins/SharedImagePlugin.web.ts - TypeScript definitions:
src/plugins/definitions.ts
getSharedImage(): Promise<SharedImageResult | null>
Returns the shared image as { base64, fileName, shareId }, or null if none
exists. shareId is the native sharedPhotoShareId (UUID assigned by the
Share Extension); pass it to markProcessed() to signal explicit completion.
Read-only: native metadata and the file are left intact after retrieval
(Phase 1C).
Note: On iOS the "no shared image" case resolves an object with
base64,fileName, andshareIdset tonull; on webgetSharedImage()resolvesnulldirectly.
hasSharedImage(): Promise<{ hasImage: boolean }>
Returns whether a shared image file currently exists, without reading it.
markProcessed(options: { shareId: string }): Promise<{ success: boolean }> — Phase 1D
Explicit completion signal from the application layer for a given share.
- Input:
shareId— the identifier reported bygetSharedImage(). Must be a non-empty string; otherwise the call rejects. - Behavior (iOS): Records
shareIdin App GroupUserDefaultsundersharedPhotoProcessedShareIdand resolves with{ success: true }. - Does NOT delete files: The stored image file and share metadata are intentionally left intact. File cleanup is deferred to a later phase.
- Web: No-op; resolves with
{ success: false }. - Logging: Emits
[ShareTarget] shareId=<id> marked processedon success.
Note (Phase 1D):
markProcessedis implemented and exposed to TypeScript but is not yet called from application code. Wiring it into the processing flow is a later phase.
Native Logging Reference
Relevant [ShareTarget] log lines emitted on iOS:
[ShareTarget] shareId=<id> retrieved[ShareTarget] shareId=<id> left intact after retrieval[ShareTarget] shareId=<id> marked processed(Phase 1D)
Out of Scope
- Android: no changes. The Android plugin
(
android/app/src/main/java/app/timesafari/sharedimage/SharedImagePlugin.java) does not implementmarkProcessed. - File deletion / cleanup of processed shares.
- Calling
markProcessedfrom application code.