refactor: remove unused ShareImage plugin code, simplify to temp file approach
Remove unused Capacitor plugin implementation and simplify shared image handling to use only the temp file approach, which is already working reliably for both iOS and Android. Changes: - Delete ios/App/App/ShareImagePlugin.swift (unused, never registered) - Delete ios/App/App/ShareImageBridge.swift (only used by plugin) - Remove ~80 lines of plugin fallback code from src/main.capacitor.ts - Simplify error handling to single code path - Add documentation comment explaining temp file approach and future plugin implementation possibility Benefits: - ~154 lines of code removed - Single, consistent code path for both platforms - Easier to maintain and debug - No functional changes - temp file approach already working The temp file approach uses Capacitor's Filesystem plugin to read shared image data written by native code (AppDelegate on iOS, MainActivity on Android). This is simpler and more reliable than the plugin approach, which required registration and bridge setup. Future improvement: Consider implementing Capacitor plugins for direct native-to-JS communication if lower latency becomes a priority, though the current approach performs well in production.
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; };
|
||||
97EF2DC6FD76C3643D680B8D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90DCAFB4D8948F7A50C13800 /* Pods_App.framework */; };
|
||||
C86585DF2ED456DE00824752 /* TimeSafariShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C86585D52ED456DE00824752 /* TimeSafariShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
C86585E82ED45A3E00824752 /* ShareImageBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86585E72ED45A3D00824752 /* ShareImageBridge.swift */; };
|
||||
C8D7E2CC2ED46A3B00DD738D /* ShareImagePlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D7E2CB2ED46A3B00DD738D /* ShareImagePlugin.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -57,8 +55,6 @@
|
||||
90DCAFB4D8948F7A50C13800 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C86585D52ED456DE00824752 /* TimeSafariShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = TimeSafariShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C86585E52ED4577F00824752 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = "<group>"; };
|
||||
C86585E72ED45A3D00824752 /* ShareImageBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareImageBridge.swift; sourceTree = "<group>"; };
|
||||
C8D7E2CB2ED46A3B00DD738D /* ShareImagePlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareImagePlugin.swift; sourceTree = "<group>"; };
|
||||
E2E9297D5D02C549106C77F9 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = "<group>"; };
|
||||
EAEC6436E595F7CD3A1C9E96 /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -127,8 +123,6 @@
|
||||
504EC3061FED79650016851F /* App */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C8D7E2CB2ED46A3B00DD738D /* ShareImagePlugin.swift */,
|
||||
C86585E72ED45A3D00824752 /* ShareImageBridge.swift */,
|
||||
C86585E52ED4577F00824752 /* App.entitlements */,
|
||||
50379B222058CBB4000EE86E /* capacitor.config.json */,
|
||||
504EC3071FED79650016851F /* AppDelegate.swift */,
|
||||
@@ -345,8 +339,6 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C8D7E2CC2ED46A3B00DD738D /* ShareImagePlugin.swift in Sources */,
|
||||
C86585E82ED45A3E00824752 /* ShareImageBridge.swift in Sources */,
|
||||
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
* Share Image Bridge
|
||||
*
|
||||
* Provides a bridge between JavaScript and native iOS code to access
|
||||
* shared images stored in App Group UserDefaults by the Share Extension.
|
||||
*
|
||||
* This bridge allows the JavaScript layer to read shared image data
|
||||
* that was stored by the Share Extension.
|
||||
*
|
||||
* Note: This class doesn't need Capacitor - it's a simple Swift utility
|
||||
* that reads from App Group UserDefaults. The JavaScript bridge will be
|
||||
* implemented separately.
|
||||
*/
|
||||
@objc(ShareImageBridge)
|
||||
public class ShareImageBridge: NSObject {
|
||||
|
||||
private static let appGroupIdentifier = "group.app.timesafari"
|
||||
private static let sharedPhotoBase64Key = "sharedPhotoBase64"
|
||||
private static let sharedPhotoFileNameKey = "sharedPhotoFileName"
|
||||
|
||||
/**
|
||||
* Get shared image data from App Group UserDefaults
|
||||
* Called from JavaScript via Capacitor bridge
|
||||
*
|
||||
* @returns Dictionary with "base64" and "fileName" keys, or nil if no shared image
|
||||
*/
|
||||
@objc public static func getSharedImageData() -> [String: String]? {
|
||||
guard let userDefaults = UserDefaults(suiteName: appGroupIdentifier) else {
|
||||
print("ShareImageBridge: Failed to access App Group UserDefaults")
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let base64 = userDefaults.string(forKey: sharedPhotoBase64Key),
|
||||
let fileName = userDefaults.string(forKey: sharedPhotoFileNameKey) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clear the shared data after reading
|
||||
userDefaults.removeObject(forKey: sharedPhotoBase64Key)
|
||||
userDefaults.removeObject(forKey: sharedPhotoFileNameKey)
|
||||
userDefaults.synchronize()
|
||||
|
||||
return ["base64": base64, "fileName": fileName]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import Foundation
|
||||
import Capacitor
|
||||
|
||||
/**
|
||||
* Share Image Plugin
|
||||
*
|
||||
* Capacitor plugin that exposes ShareImageBridge functionality to JavaScript.
|
||||
* Allows JavaScript to retrieve shared images from App Group UserDefaults.
|
||||
*/
|
||||
@objc(ShareImagePlugin)
|
||||
public class ShareImagePlugin: CAPPlugin {
|
||||
|
||||
@objc func getSharedImageData(_ call: CAPPluginCall) {
|
||||
guard let sharedData = ShareImageBridge.getSharedImageData() else {
|
||||
call.resolve(["success": false, "data": NSNull()])
|
||||
return
|
||||
}
|
||||
|
||||
call.resolve([
|
||||
"success": true,
|
||||
"data": [
|
||||
"base64": sharedData["base64"] ?? "",
|
||||
"fileName": sharedData["fileName"] ?? ""
|
||||
]
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,18 +192,17 @@ async function checkAndStoreNativeSharedImage(): Promise<{
|
||||
`[Main] Checking for ${platform} shared image from native layer`,
|
||||
);
|
||||
|
||||
// Use Capacitor's native bridge to call the ShareImagePlugin
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const capacitor = (window as any).Capacitor;
|
||||
|
||||
if (!capacitor || !capacitor.Plugins) {
|
||||
logger.debug("[Main] Capacitor plugins not available");
|
||||
isProcessingSharedImage = false;
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
// WORKAROUND: Since the plugin isn't being auto-discovered, use a temp file bridge
|
||||
// Native layer (AppDelegate on iOS, MainActivity on Android) writes the shared image data to a temp file, and we read it here
|
||||
// TEMP FILE APPROACH:
|
||||
// Native layer (AppDelegate on iOS, MainActivity on Android) writes the shared image data
|
||||
// to a temp file, and we read it here using Capacitor's Filesystem plugin.
|
||||
//
|
||||
// This approach is simple, reliable, and works consistently across both platforms.
|
||||
// The temp file is deleted immediately after reading to prevent re-processing.
|
||||
//
|
||||
// FUTURE IMPROVEMENT: Consider implementing Capacitor plugins for iOS and Android
|
||||
// to provide a more direct native-to-JS bridge. This would eliminate the need for
|
||||
// file I/O and polling, providing lower latency and a more "native" integration.
|
||||
// However, the current temp file approach is production-ready and performs well.
|
||||
const tempFilePath = "timesafari_shared_photo.json";
|
||||
|
||||
// Use platform-specific directory:
|
||||
@@ -250,96 +249,20 @@ async function checkAndStoreNativeSharedImage(): Promise<{
|
||||
}
|
||||
}
|
||||
} catch (fileError: unknown) {
|
||||
// File exists but can't be read - log and continue to plugin method
|
||||
logger.debug(
|
||||
"[Main] Temp file exists but couldn't be read, trying plugin method",
|
||||
logger.error(
|
||||
"[Main] Temp file exists but couldn't be read:",
|
||||
fileError,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
logger.debug(
|
||||
"[Main] Temp file not found after polling (this is normal if plugin works)",
|
||||
);
|
||||
}
|
||||
|
||||
// NOTE: Plugin registration issue - ShareImage plugin is not being auto-discovered
|
||||
// This is a known issue that needs to be resolved. For now, we use the temp file workaround above.
|
||||
|
||||
// Try multiple methods to call the plugin (fallback if temp file method fails)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const plugins = (capacitor as any).Plugins;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const shareImagePlugin = (plugins as any)?.ShareImage;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let result: any = null;
|
||||
|
||||
if (
|
||||
shareImagePlugin &&
|
||||
typeof shareImagePlugin.getSharedImageData === "function"
|
||||
) {
|
||||
logger.debug("[Main] Using direct plugin method");
|
||||
try {
|
||||
result = await shareImagePlugin.getSharedImageData();
|
||||
} catch (pluginError) {
|
||||
logger.error("[Main] Plugin call failed:", pluginError);
|
||||
isProcessingSharedImage = false;
|
||||
return { success: false };
|
||||
}
|
||||
} else {
|
||||
// Method 2: Use Capacitor's execute method
|
||||
logger.debug(
|
||||
"[Main] Plugin not found directly, trying Capacitor.execute",
|
||||
);
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const bridge = (capacitor as any).getBridge?.();
|
||||
if (bridge) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
result = await bridge.execute({
|
||||
pluginId: "ShareImage",
|
||||
methodName: "getSharedImageData",
|
||||
options: {},
|
||||
});
|
||||
} else {
|
||||
// Method 3: Try execute on Plugins object
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((plugins as any)?.execute) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
result = await (plugins as any).execute(
|
||||
"ShareImage",
|
||||
"getSharedImageData",
|
||||
{},
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (executeError) {
|
||||
logger.error("[Main] Execute method failed:", executeError);
|
||||
isProcessingSharedImage = false;
|
||||
return { success: false };
|
||||
}
|
||||
logger.debug("[Main] Temp file not found after polling");
|
||||
}
|
||||
|
||||
if (!result || !result.success || !result.data) {
|
||||
logger.debug("[Main] No shared image data found in result");
|
||||
isProcessingSharedImage = false;
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
const { base64, fileName } = result.data;
|
||||
|
||||
if (!base64) {
|
||||
logger.debug("[Main] Shared image data missing base64");
|
||||
isProcessingSharedImage = false;
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
logger.info("[Main] Native shared image found, storing in temp DB");
|
||||
|
||||
// Store in temp database using extracted method
|
||||
await storeSharedImageInTempDB(base64, fileName);
|
||||
|
||||
// No shared image found
|
||||
isProcessingSharedImage = false;
|
||||
return { success: true, fileName: fileName || "shared-image.jpg" };
|
||||
return { success: false };
|
||||
} catch (error) {
|
||||
logger.error("[Main] Error checking for native shared image:", error);
|
||||
isProcessingSharedImage = false;
|
||||
|
||||
Reference in New Issue
Block a user