chore(ios): add Share Extension execution trace diagnostics (temporary)
Add a lightweight, temporary trace logger to diagnose where the iOS Share Extension stops executing during a failed cold-start share. - ShareViewController: add appendTrace() helper that writes ISO8601- prefixed lines to share-extension-trace.log in the App Group container, ignoring failures (diagnostics only) - Add trace entries across the share flow: viewDidLoad, processAndOpenApp, processSharedImage, image attachment/load, storeImageData, setSharedPhotoReadyFlag, openMainApp, completeRequest - SharedImageUtility: add getShareExtensionTrace() (read-only) and clearShareExtensionTrace() (deletes the trace file) - SharedImagePlugin: expose getShareExtensionTrace() and clearShareExtensionTrace() to JS - definitions.ts / SharedImagePlugin.web.ts: add ShareExtensionTrace type, method signatures, and web stubs Share behavior is unchanged and Android is untouched. All additions are marked with "TEMPORARY SHARE TARGET DIAGNOSTICS".
This commit is contained in:
@@ -25,7 +25,11 @@ public class SharedImagePlugin: CAPPlugin, CAPBridgedPlugin {
|
|||||||
return [
|
return [
|
||||||
CAPPluginMethod(#selector(getSharedImage(_:)), returnType: .promise),
|
CAPPluginMethod(#selector(getSharedImage(_:)), returnType: .promise),
|
||||||
CAPPluginMethod(#selector(hasSharedImage(_:)), returnType: .promise),
|
CAPPluginMethod(#selector(hasSharedImage(_:)), returnType: .promise),
|
||||||
CAPPluginMethod(#selector(getShareExtensionDiagnostics(_:)), returnType: .promise)
|
CAPPluginMethod(#selector(getShareExtensionDiagnostics(_:)), returnType: .promise),
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
CAPPluginMethod(#selector(getShareExtensionTrace(_:)), returnType: .promise),
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
CAPPluginMethod(#selector(clearShareExtensionTrace(_:)), returnType: .promise)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,5 +74,24 @@ public class SharedImagePlugin: CAPPlugin, CAPBridgedPlugin {
|
|||||||
@objc public func getShareExtensionDiagnostics(_ call: CAPPluginCall) {
|
@objc public func getShareExtensionDiagnostics(_ call: CAPPluginCall) {
|
||||||
call.resolve(SharedImageUtility.getShareExtensionDiagnostics())
|
call.resolve(SharedImageUtility.getShareExtensionDiagnostics())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
/**
|
||||||
|
* Return the raw Share Extension execution trace log from the App Group container
|
||||||
|
*/
|
||||||
|
@objc public func getShareExtensionTrace(_ call: CAPPluginCall) {
|
||||||
|
call.resolve([
|
||||||
|
"trace": SharedImageUtility.getShareExtensionTrace()
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
/**
|
||||||
|
* Delete the Share Extension execution trace log if present
|
||||||
|
*/
|
||||||
|
@objc public func clearShareExtensionTrace(_ call: CAPPluginCall) {
|
||||||
|
SharedImageUtility.clearShareExtensionTrace()
|
||||||
|
call.resolve()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ public class SharedImageUtility {
|
|||||||
private static let sharedPhotoShareIdKey = "sharedPhotoShareId"
|
private static let sharedPhotoShareIdKey = "sharedPhotoShareId"
|
||||||
private static let shareExtensionLastStartKey = "shareExtensionLastStart"
|
private static let shareExtensionLastStartKey = "shareExtensionLastStart"
|
||||||
private static let sharedPhotoReadyKey = "sharedPhotoReady"
|
private static let sharedPhotoReadyKey = "sharedPhotoReady"
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
private static let shareExtensionTraceFileName = "share-extension-trace.log"
|
||||||
|
|
||||||
/// Get the App Group container URL for accessing shared files
|
/// Get the App Group container URL for accessing shared files
|
||||||
private static var appGroupContainerURL: URL? {
|
private static var appGroupContainerURL: URL? {
|
||||||
@@ -145,6 +147,33 @@ public class SharedImageUtility {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
/**
|
||||||
|
* Read the Share Extension trace file from the App Group container.
|
||||||
|
* Read-only: does not modify or delete the trace file.
|
||||||
|
*
|
||||||
|
* @returns the full trace contents, or an empty string if no trace exists
|
||||||
|
*/
|
||||||
|
static func getShareExtensionTrace() -> String {
|
||||||
|
guard let containerURL = appGroupContainerURL else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
let fileURL = containerURL.appendingPathComponent(shareExtensionTraceFileName)
|
||||||
|
return (try? String(contentsOf: fileURL, encoding: .utf8)) ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
/**
|
||||||
|
* Delete the Share Extension trace file from the App Group container if present.
|
||||||
|
*/
|
||||||
|
static func clearShareExtensionTrace() {
|
||||||
|
guard let containerURL = appGroupContainerURL else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let fileURL = containerURL.appendingPathComponent(shareExtensionTraceFileName)
|
||||||
|
try? FileManager.default.removeItem(at: fileURL)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if shared photo ready flag is set
|
* Check if shared photo ready flag is set
|
||||||
* This flag is set by the Share Extension when image is ready
|
* This flag is set by the Share Extension when image is ready
|
||||||
|
|||||||
@@ -17,12 +17,36 @@ class ShareViewController: UIViewController {
|
|||||||
private let shareExtensionLastStartKey = "shareExtensionLastStart"
|
private let shareExtensionLastStartKey = "shareExtensionLastStart"
|
||||||
private let sharedImageFileName = "shared-image"
|
private let sharedImageFileName = "shared-image"
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
private let shareExtensionTraceFileName = "share-extension-trace.log"
|
||||||
|
|
||||||
/// Get the App Group container URL for storing shared files
|
/// Get the App Group container URL for storing shared files
|
||||||
private var appGroupContainerURL: URL? {
|
private var appGroupContainerURL: URL? {
|
||||||
return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier)
|
return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
/// Append a single timestamped line to the Share Extension trace file in the
|
||||||
|
/// App Group container. Each line is prefixed with an ISO8601 timestamp.
|
||||||
|
/// Logging failures are intentionally ignored (diagnostics only).
|
||||||
|
private func appendTrace(_ message: String) {
|
||||||
|
guard let containerURL = appGroupContainerURL else { return }
|
||||||
|
let fileURL = containerURL.appendingPathComponent(shareExtensionTraceFileName)
|
||||||
|
let timestamp = ISO8601DateFormatter().string(from: Date())
|
||||||
|
let line = "\(timestamp) \(message)\n"
|
||||||
|
guard let data = line.data(using: .utf8) else { return }
|
||||||
|
if let handle = try? FileHandle(forWritingTo: fileURL) {
|
||||||
|
defer { try? handle.close() }
|
||||||
|
_ = try? handle.seekToEnd()
|
||||||
|
try? handle.write(contentsOf: data)
|
||||||
|
} else {
|
||||||
|
try? data.write(to: fileURL, options: .atomic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("viewDidLoad START")
|
||||||
if let userDefaults = UserDefaults(suiteName: appGroupIdentifier) {
|
if let userDefaults = UserDefaults(suiteName: appGroupIdentifier) {
|
||||||
let timestamp = ISO8601DateFormatter().string(from: Date())
|
let timestamp = ISO8601DateFormatter().string(from: Date())
|
||||||
userDefaults.set(timestamp, forKey: shareExtensionLastStartKey)
|
userDefaults.set(timestamp, forKey: shareExtensionLastStartKey)
|
||||||
@@ -39,19 +63,29 @@ class ShareViewController: UIViewController {
|
|||||||
// Process image immediately without showing UI
|
// Process image immediately without showing UI
|
||||||
processAndOpenApp()
|
processAndOpenApp()
|
||||||
print("[ShareTarget] viewDidLoad completed")
|
print("[ShareTarget] viewDidLoad completed")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("viewDidLoad END")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func processAndOpenApp() {
|
private func processAndOpenApp() {
|
||||||
print("[ShareTarget] processAndOpenApp started")
|
print("[ShareTarget] processAndOpenApp started")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("processAndOpenApp START")
|
||||||
|
|
||||||
// extensionContext is automatically available on UIViewController when used as extension principal class
|
// extensionContext is automatically available on UIViewController when used as extension principal class
|
||||||
guard let context = extensionContext,
|
guard let context = extensionContext,
|
||||||
let inputItems = context.inputItems as? [NSExtensionItem] else {
|
let inputItems = context.inputItems as? [NSExtensionItem] else {
|
||||||
print("[ShareTarget] processAndOpenApp failed: missing extensionContext or inputItems")
|
print("[ShareTarget] processAndOpenApp failed: missing extensionContext or inputItems")
|
||||||
print("[ShareTarget] completeRequest starting")
|
print("[ShareTarget] completeRequest starting")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("completeRequest START")
|
||||||
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
|
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
|
||||||
print("[ShareTarget] completeRequest completed")
|
print("[ShareTarget] completeRequest completed")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("completeRequest END")
|
||||||
print("[ShareTarget] processAndOpenApp completed")
|
print("[ShareTarget] processAndOpenApp completed")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("processAndOpenApp END")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +98,8 @@ class ShareViewController: UIViewController {
|
|||||||
guard let self = self, let context = self.extensionContext else {
|
guard let self = self, let context = self.extensionContext else {
|
||||||
print("[ShareTarget] processAndOpenApp failed: self or extensionContext unavailable in completion")
|
print("[ShareTarget] processAndOpenApp failed: self or extensionContext unavailable in completion")
|
||||||
print("[ShareTarget] processAndOpenApp completed")
|
print("[ShareTarget] processAndOpenApp completed")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
self?.appendTrace("processAndOpenApp END")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,23 +114,35 @@ class ShareViewController: UIViewController {
|
|||||||
|
|
||||||
// Complete immediately - no UI shown
|
// Complete immediately - no UI shown
|
||||||
print("[ShareTarget] completeRequest starting")
|
print("[ShareTarget] completeRequest starting")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
self.appendTrace("completeRequest START")
|
||||||
context.completeRequest(returningItems: [], completionHandler: nil)
|
context.completeRequest(returningItems: [], completionHandler: nil)
|
||||||
print("[ShareTarget] completeRequest completed")
|
print("[ShareTarget] completeRequest completed")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
self.appendTrace("completeRequest END")
|
||||||
print("[ShareTarget] processAndOpenApp completed")
|
print("[ShareTarget] processAndOpenApp completed")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
self.appendTrace("processAndOpenApp END")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setSharedPhotoReadyFlag() {
|
private func setSharedPhotoReadyFlag() {
|
||||||
print("[ShareTarget] setSharedPhotoReadyFlag started")
|
print("[ShareTarget] setSharedPhotoReadyFlag started")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("setSharedPhotoReadyFlag START")
|
||||||
guard let userDefaults = UserDefaults(suiteName: appGroupIdentifier) else {
|
guard let userDefaults = UserDefaults(suiteName: appGroupIdentifier) else {
|
||||||
print("[ShareTarget] setSharedPhotoReadyFlag failed: UserDefaults unavailable for app group")
|
print("[ShareTarget] setSharedPhotoReadyFlag failed: UserDefaults unavailable for app group")
|
||||||
print("[ShareTarget] setSharedPhotoReadyFlag completed")
|
print("[ShareTarget] setSharedPhotoReadyFlag completed")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("setSharedPhotoReadyFlag FAILURE")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
userDefaults.set(true, forKey: "sharedPhotoReady")
|
userDefaults.set(true, forKey: "sharedPhotoReady")
|
||||||
userDefaults.synchronize()
|
userDefaults.synchronize()
|
||||||
print("[ShareTarget] setSharedPhotoReadyFlag success")
|
print("[ShareTarget] setSharedPhotoReadyFlag success")
|
||||||
print("[ShareTarget] setSharedPhotoReadyFlag completed")
|
print("[ShareTarget] setSharedPhotoReadyFlag completed")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("setSharedPhotoReadyFlag SUCCESS")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func processSharedImage(from items: [NSExtensionItem], completion: @escaping (Bool) -> Void) {
|
private func processSharedImage(from items: [NSExtensionItem], completion: @escaping (Bool) -> Void) {
|
||||||
@@ -102,6 +150,8 @@ class ShareViewController: UIViewController {
|
|||||||
count + (item.attachments?.count ?? 0)
|
count + (item.attachments?.count ?? 0)
|
||||||
}
|
}
|
||||||
print("[ShareTarget] processSharedImage started attachmentCount=\(attachmentCount)")
|
print("[ShareTarget] processSharedImage started attachmentCount=\(attachmentCount)")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("processSharedImage START")
|
||||||
|
|
||||||
// Find the first image attachment
|
// Find the first image attachment
|
||||||
for item in items {
|
for item in items {
|
||||||
@@ -120,6 +170,8 @@ class ShareViewController: UIViewController {
|
|||||||
let shareId = UUID().uuidString
|
let shareId = UUID().uuidString
|
||||||
print("[ShareTarget] processSharedImage found image attachment shareId=\(shareId) UTType=\(UTType.image.identifier)")
|
print("[ShareTarget] processSharedImage found image attachment shareId=\(shareId) UTType=\(UTType.image.identifier)")
|
||||||
print("[ShareTarget] share received shareId=\(shareId)")
|
print("[ShareTarget] share received shareId=\(shareId)")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("image attachment found shareId=\(shareId)")
|
||||||
|
|
||||||
// Try to load raw data first to preserve original format
|
// Try to load raw data first to preserve original format
|
||||||
// This preserves the original image format without conversion
|
// This preserves the original image format without conversion
|
||||||
@@ -134,6 +186,8 @@ class ShareViewController: UIViewController {
|
|||||||
if let error = error {
|
if let error = error {
|
||||||
print("[ShareTarget] processSharedImage failed: loadItem error shareId=\(shareId) error=\(error.localizedDescription)")
|
print("[ShareTarget] processSharedImage failed: loadItem error shareId=\(shareId) error=\(error.localizedDescription)")
|
||||||
print("[ShareTarget] processSharedImage completed shareId=\(shareId) success=false")
|
print("[ShareTarget] processSharedImage completed shareId=\(shareId) success=false")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
self.appendTrace("processSharedImage END success=false")
|
||||||
completion(false)
|
completion(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -177,19 +231,27 @@ class ShareViewController: UIViewController {
|
|||||||
guard let finalImageData = imageData else {
|
guard let finalImageData = imageData else {
|
||||||
print("[ShareTarget] processSharedImage failed: no image data shareId=\(shareId)")
|
print("[ShareTarget] processSharedImage failed: no image data shareId=\(shareId)")
|
||||||
print("[ShareTarget] processSharedImage completed shareId=\(shareId) success=false")
|
print("[ShareTarget] processSharedImage completed shareId=\(shareId) success=false")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
self.appendTrace("processSharedImage END success=false")
|
||||||
completion(false)
|
completion(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
print("[ShareTarget] image loaded bytes=\(finalImageData.count) filename=\(fileName) shareId=\(shareId)")
|
print("[ShareTarget] image loaded bytes=\(finalImageData.count) filename=\(fileName) shareId=\(shareId)")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
self.appendTrace("image loaded shareId=\(shareId) bytes=\(finalImageData.count)")
|
||||||
|
|
||||||
// Store image as file in App Group container
|
// Store image as file in App Group container
|
||||||
if self.storeImageData(finalImageData, fileName: fileName, shareId: shareId) {
|
if self.storeImageData(finalImageData, fileName: fileName, shareId: shareId) {
|
||||||
print("[ShareTarget] processSharedImage completed shareId=\(shareId) success=true")
|
print("[ShareTarget] processSharedImage completed shareId=\(shareId) success=true")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
self.appendTrace("processSharedImage END success=true")
|
||||||
completion(true)
|
completion(true)
|
||||||
} else {
|
} else {
|
||||||
print("[ShareTarget] processSharedImage failed: storeImageData returned false shareId=\(shareId)")
|
print("[ShareTarget] processSharedImage failed: storeImageData returned false shareId=\(shareId)")
|
||||||
print("[ShareTarget] processSharedImage completed shareId=\(shareId) success=false")
|
print("[ShareTarget] processSharedImage completed shareId=\(shareId) success=false")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
self.appendTrace("processSharedImage END success=false")
|
||||||
completion(false)
|
completion(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,6 +262,8 @@ class ShareViewController: UIViewController {
|
|||||||
// No image found
|
// No image found
|
||||||
print("[ShareTarget] processSharedImage failed: no image attachment found attachmentCount=\(attachmentCount)")
|
print("[ShareTarget] processSharedImage failed: no image attachment found attachmentCount=\(attachmentCount)")
|
||||||
print("[ShareTarget] processSharedImage completed success=false")
|
print("[ShareTarget] processSharedImage completed success=false")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("processSharedImage END success=false")
|
||||||
completion(false)
|
completion(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,10 +291,14 @@ class ShareViewController: UIViewController {
|
|||||||
/// Returns true if successful, false otherwise
|
/// Returns true if successful, false otherwise
|
||||||
private func storeImageData(_ imageData: Data, fileName: String, shareId: String) -> Bool {
|
private func storeImageData(_ imageData: Data, fileName: String, shareId: String) -> Bool {
|
||||||
print("[ShareTarget] storeImageData started shareId=\(shareId) bytes=\(imageData.count) filename=\(fileName)")
|
print("[ShareTarget] storeImageData started shareId=\(shareId) bytes=\(imageData.count) filename=\(fileName)")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("storeImageData START shareId=\(shareId)")
|
||||||
|
|
||||||
guard let containerURL = appGroupContainerURL else {
|
guard let containerURL = appGroupContainerURL else {
|
||||||
print("[ShareTarget] storeImageData failed: app group container unavailable shareId=\(shareId)")
|
print("[ShareTarget] storeImageData failed: app group container unavailable shareId=\(shareId)")
|
||||||
print("[ShareTarget] storeImageData completed shareId=\(shareId) success=false")
|
print("[ShareTarget] storeImageData completed shareId=\(shareId) success=false")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("storeImageData FAILURE shareId=\(shareId)")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,6 +321,8 @@ class ShareViewController: UIViewController {
|
|||||||
} catch {
|
} catch {
|
||||||
print("[ShareTarget] storeImageData failed: file write error shareId=\(shareId) error=\(error.localizedDescription)")
|
print("[ShareTarget] storeImageData failed: file write error shareId=\(shareId) error=\(error.localizedDescription)")
|
||||||
print("[ShareTarget] storeImageData completed shareId=\(shareId) success=false")
|
print("[ShareTarget] storeImageData completed shareId=\(shareId) success=false")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("storeImageData FAILURE shareId=\(shareId)")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
print("[ShareTarget] file stored shareId=\(shareId) originalFilename=\(originalFileName) storedFilename=\(storedFileName)")
|
print("[ShareTarget] file stored shareId=\(shareId) originalFilename=\(originalFileName) storedFilename=\(storedFileName)")
|
||||||
@@ -261,6 +331,8 @@ class ShareViewController: UIViewController {
|
|||||||
guard let userDefaults = UserDefaults(suiteName: appGroupIdentifier) else {
|
guard let userDefaults = UserDefaults(suiteName: appGroupIdentifier) else {
|
||||||
print("[ShareTarget] storeImageData failed: UserDefaults unavailable shareId=\(shareId)")
|
print("[ShareTarget] storeImageData failed: UserDefaults unavailable shareId=\(shareId)")
|
||||||
print("[ShareTarget] storeImageData completed shareId=\(shareId) success=false")
|
print("[ShareTarget] storeImageData completed shareId=\(shareId) success=false")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("storeImageData FAILURE shareId=\(shareId)")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,16 +348,22 @@ class ShareViewController: UIViewController {
|
|||||||
print("[ShareTarget] metadata stored shareId=\(shareId) originalFilename=\(originalFileName) storedFilename=\(storedFileName)")
|
print("[ShareTarget] metadata stored shareId=\(shareId) originalFilename=\(originalFileName) storedFilename=\(storedFileName)")
|
||||||
print("[ShareTarget] storeImageData success shareId=\(shareId)")
|
print("[ShareTarget] storeImageData success shareId=\(shareId)")
|
||||||
print("[ShareTarget] storeImageData completed shareId=\(shareId) success=true")
|
print("[ShareTarget] storeImageData completed shareId=\(shareId) success=true")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("storeImageData SUCCESS shareId=\(shareId)")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private func openMainApp() {
|
private func openMainApp() {
|
||||||
print("[ShareTarget] openMainApp starting")
|
print("[ShareTarget] openMainApp starting")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("openMainApp START")
|
||||||
|
|
||||||
// Open the main app with minimal URL - app will detect shared data on activation
|
// Open the main app with minimal URL - app will detect shared data on activation
|
||||||
guard let url = URL(string: "timesafari://") else {
|
guard let url = URL(string: "timesafari://") else {
|
||||||
print("[ShareTarget] openMainApp failed: could not create timesafari:// URL")
|
print("[ShareTarget] openMainApp failed: could not create timesafari:// URL")
|
||||||
print("[ShareTarget] openMainApp completed")
|
print("[ShareTarget] openMainApp completed")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("openMainApp FAILURE")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,6 +372,8 @@ class ShareViewController: UIViewController {
|
|||||||
if let application = responder as? UIApplication {
|
if let application = responder as? UIApplication {
|
||||||
application.open(url, options: [:], completionHandler: nil)
|
application.open(url, options: [:], completionHandler: nil)
|
||||||
print("[ShareTarget] openMainApp completed via UIApplication")
|
print("[ShareTarget] openMainApp completed via UIApplication")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("openMainApp SUCCESS")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
responder = responder?.next
|
responder = responder?.next
|
||||||
@@ -302,6 +382,8 @@ class ShareViewController: UIViewController {
|
|||||||
// Fallback: use extension context
|
// Fallback: use extension context
|
||||||
extensionContext?.open(url, completionHandler: nil)
|
extensionContext?.open(url, completionHandler: nil)
|
||||||
print("[ShareTarget] openMainApp completed via extensionContext fallback")
|
print("[ShareTarget] openMainApp completed via extensionContext fallback")
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
appendTrace("openMainApp SUCCESS")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import type {
|
|||||||
SharedImagePlugin,
|
SharedImagePlugin,
|
||||||
SharedImageResult,
|
SharedImageResult,
|
||||||
ShareExtensionDiagnostics,
|
ShareExtensionDiagnostics,
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
ShareExtensionTrace,
|
||||||
} from "./definitions";
|
} from "./definitions";
|
||||||
|
|
||||||
export class SharedImagePluginWeb
|
export class SharedImagePluginWeb
|
||||||
@@ -33,4 +35,14 @@ export class SharedImagePluginWeb
|
|||||||
pendingShareExists: false,
|
pendingShareExists: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
async getShareExtensionTrace(): Promise<ShareExtensionTrace> {
|
||||||
|
return { trace: "" };
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
async clearShareExtensionTrace(): Promise<void> {
|
||||||
|
// Web platform doesn't support native sharing - no-op
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ export interface ShareExtensionDiagnostics {
|
|||||||
pendingShareExists: boolean;
|
pendingShareExists: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
export interface ShareExtensionTrace {
|
||||||
|
trace: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SharedImagePlugin {
|
export interface SharedImagePlugin {
|
||||||
/**
|
/**
|
||||||
* Get shared image data from native layer
|
* Get shared image data from native layer
|
||||||
@@ -34,4 +39,16 @@ export interface SharedImagePlugin {
|
|||||||
* Diagnostic snapshot of Share Extension startup and pending share state (iOS)
|
* Diagnostic snapshot of Share Extension startup and pending share state (iOS)
|
||||||
*/
|
*/
|
||||||
getShareExtensionDiagnostics(): Promise<ShareExtensionDiagnostics>;
|
getShareExtensionDiagnostics(): Promise<ShareExtensionDiagnostics>;
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
/**
|
||||||
|
* Read the raw Share Extension execution trace log (iOS)
|
||||||
|
*/
|
||||||
|
getShareExtensionTrace(): Promise<ShareExtensionTrace>;
|
||||||
|
|
||||||
|
// TEMPORARY SHARE TARGET DIAGNOSTICS
|
||||||
|
/**
|
||||||
|
* Delete the Share Extension execution trace log if present (iOS)
|
||||||
|
*/
|
||||||
|
clearShareExtensionTrace(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user