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.
This commit is contained in:
@@ -24,7 +24,8 @@ public class SharedImagePlugin: CAPPlugin, CAPBridgedPlugin {
|
||||
public var pluginMethods: [CAPPluginMethod] {
|
||||
return [
|
||||
CAPPluginMethod(#selector(getSharedImage(_:)), returnType: .promise),
|
||||
CAPPluginMethod(#selector(hasSharedImage(_:)), returnType: .promise)
|
||||
CAPPluginMethod(#selector(hasSharedImage(_:)), returnType: .promise),
|
||||
CAPPluginMethod(#selector(markProcessed(_:)), returnType: .promise)
|
||||
]
|
||||
}
|
||||
|
||||
@@ -62,5 +63,22 @@ public class SharedImagePlugin: CAPPlugin, CAPBridgedPlugin {
|
||||
"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
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ public class SharedImageUtility {
|
||||
private static let sharedPhotoFilePathKey = "sharedPhotoFilePath"
|
||||
private static let sharedPhotoShareIdKey = "sharedPhotoShareId"
|
||||
private static let sharedPhotoReadyKey = "sharedPhotoReady"
|
||||
private static let sharedPhotoProcessedShareIdKey = "sharedPhotoProcessedShareId"
|
||||
|
||||
/// Get the App Group container URL for accessing shared files
|
||||
private static var appGroupContainerURL: URL? {
|
||||
@@ -78,6 +79,32 @@ public class SharedImageUtility {
|
||||
return ["base64": base64String, "fileName": fileName]
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a share as processed by the web/application layer (Phase 1D).
|
||||
*
|
||||
* Records the processed shareId in the App Group UserDefaults so that
|
||||
* later phases can decide whether retrieval/cleanup should be skipped.
|
||||
* This is an explicit completion signal: it does NOT delete the stored
|
||||
* image file or clear the share metadata. File cleanup is deferred to a
|
||||
* later phase.
|
||||
*
|
||||
* @param shareId The share identifier reported by getSharedImage()
|
||||
* @returns true if the processed marker was recorded, false otherwise
|
||||
*/
|
||||
@discardableResult
|
||||
static func markProcessed(shareId: String) -> Bool {
|
||||
guard let userDefaults = UserDefaults(suiteName: appGroupIdentifier) else {
|
||||
print("[ShareTarget] shareId=\(shareId) markProcessed failed: UserDefaults unavailable for app group")
|
||||
return false
|
||||
}
|
||||
|
||||
userDefaults.set(shareId, forKey: sharedPhotoProcessedShareIdKey)
|
||||
userDefaults.synchronize()
|
||||
|
||||
print("[ShareTarget] shareId=\(shareId) marked processed")
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if shared image exists without reading it
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user