Files
crowd-funder-for-time-pwa/ios/App/App/SharedImageUtility.swift
Jose Olarte III c6d5876da3 refactor(ios): remove orphaned Share Extension diagnostics API
Remove the getShareExtensionDiagnostics() API now that the share-target
investigation is complete and it has no remaining callers.

- Drop getShareExtensionDiagnostics from the plugin definition, web stub,
  Swift plugin method + registration, and SharedImageUtility implementation
- Remove the ShareExtensionDiagnostics TypeScript interface and its now-dead
  import in the web stub
- Remove the diagnostics-only [ShareTarget] log line and the now-unused
  shareExtensionLastStartKey constant in SharedImageUtility

getSharedImage/hasSharedImage, SharedPhotoReady logic, ShareViewController,
AppDelegate, and Android are unchanged. TypeScript type-check passes.
2026-06-29 18:12:35 +08:00

128 lines
4.8 KiB
Swift

//
// SharedImageUtility.swift
// App
//
// Shared utility for accessing shared image data from App Group container
// Images are stored as files in the App Group container to avoid UserDefaults size limits
// Used by both AppDelegate and SharedImagePlugin
//
import Foundation
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
private static var appGroupContainerURL: URL? {
return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier)
}
private static func logShareDiagnostic(method: String, userDefaults: UserDefaults?) {
let shareId = userDefaults?.string(forKey: sharedPhotoShareIdKey)
let filePath = userDefaults?.string(forKey: sharedPhotoFilePathKey)
let metadataExists = filePath != nil
let fileExists: Bool
if let filePath = filePath, let containerURL = appGroupContainerURL {
let fileURL = containerURL.appendingPathComponent(filePath)
fileExists = FileManager.default.fileExists(atPath: fileURL.path)
} else {
fileExists = false
}
let shareIdLog = shareId ?? "nil"
let filePathLog = filePath ?? "nil"
print("[ShareTarget] \(method) shareId=\(shareIdLog) sharedPhotoFilePath=\(filePathLog) metadataExists=\(metadataExists) fileExists=\(fileExists)")
}
/**
* Get shared image data from App Group container file
* All images are stored as files for consistency and to avoid UserDefaults size limits
* Read-only: metadata and file are left intact after retrieval (Phase 1C)
*
* @returns Dictionary with "base64" and "fileName" keys, or nil if no shared image
*/
static func getSharedImageData() -> [String: String]? {
let userDefaults = UserDefaults(suiteName: appGroupIdentifier)
logShareDiagnostic(method: "getSharedImageData", userDefaults: userDefaults)
guard let userDefaults = userDefaults else {
return nil
}
// Get file path and filename from UserDefaults
guard let filePath = userDefaults.string(forKey: sharedPhotoFilePathKey),
let containerURL = appGroupContainerURL else {
return nil
}
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
}
let resolvedShareId = shareId ?? "unknown"
print("[ShareTarget] shareId=\(resolvedShareId) retrieved")
print("[ShareTarget] shareId=\(resolvedShareId) left intact after retrieval")
// Convert file data to base64 for JavaScript consumption
let base64String = imageData.base64EncodedString()
return ["base64": base64String, "fileName": fileName]
}
/**
* Check if shared image exists without reading it
*
* @returns true if shared image file exists, false otherwise
*/
static func hasSharedImage() -> Bool {
let userDefaults = UserDefaults(suiteName: appGroupIdentifier)
logShareDiagnostic(method: "hasSharedImage", userDefaults: userDefaults)
guard let userDefaults = userDefaults,
let filePath = userDefaults.string(forKey: sharedPhotoFilePathKey),
let containerURL = appGroupContainerURL else {
return false
}
let fileURL = containerURL.appendingPathComponent(filePath)
return FileManager.default.fileExists(atPath: fileURL.path)
}
/**
* Check if shared photo ready flag is set
* This flag is set by the Share Extension when image is ready
*
* @returns true if flag is set, false otherwise
*/
static func isSharedPhotoReady() -> Bool {
guard let userDefaults = UserDefaults(suiteName: appGroupIdentifier) else {
return false
}
return userDefaults.bool(forKey: sharedPhotoReadyKey)
}
/**
* Clear the shared photo ready flag
* Called after processing the shared image
*/
static func clearSharedPhotoReadyFlag() {
guard let userDefaults = UserDefaults(suiteName: appGroupIdentifier) else {
return
}
userDefaults.removeObject(forKey: sharedPhotoReadyKey)
userDefaults.synchronize()
}
}