feat(ios): add share ID tracking for share target (Phase 1A)

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.
This commit is contained in:
Jose Olarte III
2026-06-23 19:13:44 +08:00
parent 08a55202f5
commit 35a6a6bfb3
3 changed files with 79 additions and 9 deletions

View File

@@ -13,6 +13,7 @@ public class SharedImageUtility {
private static let appGroupIdentifier = "group.app.timesafari.share"
private static let sharedPhotoFileNameKey = "sharedPhotoFileName"
private static let sharedPhotoFilePathKey = "sharedPhotoFilePath"
private static let sharedPhotoShareIdKey = "sharedPhotoShareId"
private static let sharedPhotoReadyKey = "sharedPhotoReady"
/// Get the App Group container URL for accessing shared files
@@ -39,13 +40,18 @@ public class SharedImageUtility {
}
let fileName = userDefaults.string(forKey: sharedPhotoFileNameKey) ?? "shared-image.jpg"
let shareId = userDefaults.string(forKey: sharedPhotoShareIdKey)
let fileURL = containerURL.appendingPathComponent(filePath)
// Read image data from file
guard let imageData = try? Data(contentsOf: fileURL) else {
return nil
}
if let shareId = shareId {
print("[ShareTarget] share retrieved shareId=\(shareId)")
}
// Convert file data to base64 for JavaScript consumption
let base64String = imageData.base64EncodedString()

View File

@@ -13,6 +13,7 @@ class ShareViewController: UIViewController {
private let appGroupIdentifier = "group.app.timesafari.share"
private let sharedPhotoFileNameKey = "sharedPhotoFileName"
private let sharedPhotoFilePathKey = "sharedPhotoFilePath"
private let sharedPhotoShareIdKey = "sharedPhotoShareId"
private let sharedImageFileName = "shared-image"
/// Get the App Group container URL for storing shared files
@@ -76,6 +77,9 @@ class ShareViewController: UIViewController {
continue
}
let shareId = UUID().uuidString
print("[ShareTarget] share received shareId=\(shareId)")
// Try to load raw data first to preserve original format
// This preserves the original image format without conversion
attachment.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { [weak self] (data, error) in
@@ -124,7 +128,7 @@ class ShareViewController: UIViewController {
}
// Store image as file in App Group container
if self.storeImageData(finalImageData, fileName: fileName) {
if self.storeImageData(finalImageData, fileName: fileName, shareId: shareId) {
completion(true)
} else {
completion(false)
@@ -149,7 +153,7 @@ class ShareViewController: UIViewController {
/// Store image data as a file in the App Group container
/// All images are stored as files regardless of size for consistency and simplicity
/// Returns true if successful, false otherwise
private func storeImageData(_ imageData: Data, fileName: String) -> Bool {
private func storeImageData(_ imageData: Data, fileName: String, shareId: String) -> Bool {
guard let containerURL = appGroupContainerURL else {
return false
}
@@ -168,20 +172,23 @@ class ShareViewController: UIViewController {
} catch {
return false
}
print("[ShareTarget] file stored shareId=\(shareId)")
// Store file path and filename in UserDefaults (small data, safe to store)
guard let userDefaults = UserDefaults(suiteName: appGroupIdentifier) else {
return false
}
// Store relative path and filename
// Store relative path, filename, and share identifier
userDefaults.set(actualFileName, forKey: sharedPhotoFilePathKey)
userDefaults.set(fileName, forKey: sharedPhotoFileNameKey)
userDefaults.set(shareId, forKey: sharedPhotoShareIdKey)
// Clean up any old base64 data that might exist
userDefaults.removeObject(forKey: "sharedPhotoBase64")
userDefaults.synchronize()
print("[ShareTarget] metadata stored shareId=\(shareId)")
return true
}