Files
crowd-funder-for-time-pwa/ios/App/App/SharedImagePlugin.swift
Jose Olarte III 981f8b77d0 feat(ios): add markProcessed share-completion API (Phase 1D)
Add a native iOS markProcessed(shareId) method to the SharedImage plugin
that records an explicit completion signal in App Group UserDefaults
(sharedPhotoProcessedShareId) and logs "[ShareTarget] shareId=<id> marked
processed". The API is exposed to TypeScript via the plugin definitions and
a web no-op stub.

Deliberately does not delete files or clear share metadata (cleanup is
deferred to a later phase), is not yet called from application code, and
does not touch Android. Documents the share-target lifecycle and plugin API
in doc/share-target-ios-audit.md.
2026-06-30 11:00:52 +08:00

85 lines
2.5 KiB
Swift

//
// SharedImagePlugin.swift
// App
//
// Capacitor plugin for accessing shared image data from Share Extension
//
import Foundation
import Capacitor
@objc(SharedImage)
public class SharedImagePlugin: CAPPlugin, CAPBridgedPlugin {
// MARK: - CAPBridgedPlugin Conformance
public var identifier: String {
return "SharedImage"
}
public var jsName: String {
return "SharedImage"
}
public var pluginMethods: [CAPPluginMethod] {
return [
CAPPluginMethod(#selector(getSharedImage(_:)), returnType: .promise),
CAPPluginMethod(#selector(hasSharedImage(_:)), returnType: .promise),
CAPPluginMethod(#selector(markProcessed(_:)), returnType: .promise)
]
}
// MARK: - Plugin Methods
/**
* Get shared image data from App Group UserDefaults
* Returns base64 string and fileName, or null if no image exists
* Read-only: native metadata and file are left intact after retrieval (Phase 1C)
*/
@objc public func getSharedImage(_ call: CAPPluginCall) {
guard let sharedData = SharedImageUtility.getSharedImageData() else {
// No shared image exists - return null (not an error)
call.resolve([
"base64": NSNull(),
"fileName": NSNull()
])
return
}
// Return the shared image data
call.resolve([
"base64": sharedData["base64"] ?? "",
"fileName": sharedData["fileName"] ?? ""
])
}
/**
* Check if shared image exists without reading it
* Useful for quick checks before calling getSharedImage()
*/
@objc public func hasSharedImage(_ call: CAPPluginCall) {
let hasImage = SharedImageUtility.hasSharedImage()
call.resolve([
"hasImage": hasImage
])
}
/**
* Mark a share as processed by the application layer (Phase 1D)
* Records an explicit completion signal for the given shareId.
* Does NOT delete the stored image file - file cleanup is deferred to a later phase.
*/
@objc public func markProcessed(_ call: CAPPluginCall) {
guard let shareId = call.getString("shareId"), !shareId.isEmpty else {
call.reject("markProcessed requires a non-empty 'shareId'")
return
}
let success = SharedImageUtility.markProcessed(shareId: shareId)
call.resolve([
"success": success
])
}
}