diff --git a/ios/Capacitor/Capacitor/CAPBridgeProtocol.swift b/ios/Capacitor/Capacitor/CAPBridgeProtocol.swift index 37680bd56..6bef8c1e6 100644 --- a/ios/Capacitor/Capacitor/CAPBridgeProtocol.swift +++ b/ios/Capacitor/Capacitor/CAPBridgeProtocol.swift @@ -2,7 +2,7 @@ import Foundation import WebKit @objc public protocol CAPBridgeProtocol: NSObjectProtocol { - // MARK: Environment Properties + // MARK: - Environment Properties var viewController: UIViewController? { get } var config: InstanceConfiguration { get } var webView: WKWebView? { get } @@ -34,16 +34,16 @@ import WebKit @available(iOS 12.0, *) @available(*, deprecated, renamed: "userInterfaceStyle") func getUserInterfaceStyle() -> UIUserInterfaceStyle - + @available(*, deprecated, message: "Moved - equivalent is found on config.localURL") func getLocalUrl() -> String - // MARK: Call Management + // MARK: - Call Management func getSavedCall(_ callbackId: String) -> CAPPluginCall? func releaseCall(_ call: CAPPluginCall) func releaseCall(callbackId: String) - // MARK: JavaScript Handling + // MARK: - JavaScript Handling func evalWithPlugin(_ plugin: CAPPlugin, js: String) func eval(js: String) @@ -56,7 +56,11 @@ import WebKit func triggerDocumentJSEvent(eventName: String) func triggerDocumentJSEvent(eventName: String, data: String) - // MARK: View Presentation + // MARK: - Paths, Files, Assets + func localURL(fromWebURL webURL: URL?) -> URL? + func portablePath(fromLocalURL localURL: URL?) -> URL? + + // MARK: - View Presentation func showAlertWith(title: String, message: String, buttonTitle: String) func presentVC(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?) func dismissVC(animated flag: Bool, completion: (() -> Void)?) diff --git a/ios/Capacitor/Capacitor/CAPFile.swift b/ios/Capacitor/Capacitor/CAPFile.swift index c753ff67a..f3ab8a32f 100644 --- a/ios/Capacitor/Capacitor/CAPFile.swift +++ b/ios/Capacitor/Capacitor/CAPFile.swift @@ -1,32 +1,9 @@ -public class CAPFile { - var url: URL - - public init(url: URL) { - self.url = url - } -} - /** * CAPFileManager helps map file schemes to physical files, whether they are on * disk, in a bundle, or in another location. */ @objc public class CAPFileManager: NSObject { - static func get(path: String) -> CAPFile? { - let handlers: [String: CAPFileResolver.Type] = [ - "res://": CAPFileResolverResource.self, - "file://": CAPFileResolverFile.self, - "base64:": CAPFileResolverNotImplemented.self - ] - - for (handlerPrefix, handler) in handlers { - if path.hasPrefix(handlerPrefix) { - return handler.resolve(path: path) - } - } - - return nil - } - + @available(*, deprecated, message: "Use portablePath(fromLocalURL:) on the Bridge") public static func getPortablePath(host: String, uri: URL?) -> String? { if let uri = uri { let uriWithoutFile = uri.absoluteString.replacingOccurrences(of: "file://", with: "") @@ -35,40 +12,3 @@ public class CAPFile { return nil } } - -private protocol CAPFileResolver { - static func resolve(path: String) -> CAPFile? -} - -private class CAPFileResolverFile: CAPFileResolver { - static func resolve(path: String) -> CAPFile? { - let manager = FileManager.default - let absPath = path.replacingOccurrences(of: "file:///", with: "") - if !manager.fileExists(atPath: absPath) { - return nil - } - return CAPFile(url: URL(fileURLWithPath: absPath)) - } - -} - -private class CAPFileResolverResource: CAPFileResolver { - static func resolve(path: String) -> CAPFile? { - let manager = FileManager.default - let bundle = Bundle.main - let resourcePath = bundle.resourcePath - - var absPath = path.replacingOccurrences(of: "res://", with: "") - absPath = resourcePath! + "/" + absPath - if !manager.fileExists(atPath: absPath) { - return nil - } - return CAPFile(url: URL(fileURLWithPath: absPath)) - } -} - -private class CAPFileResolverNotImplemented: CAPFileResolver { - static func resolve(path: String) -> CAPFile? { - return nil - } -} diff --git a/ios/Capacitor/Capacitor/CapacitorBridge.swift b/ios/Capacitor/Capacitor/CapacitorBridge.swift index b92691326..8d6390632 100644 --- a/ios/Capacitor/Capacitor/CapacitorBridge.swift +++ b/ios/Capacitor/Capacitor/CapacitorBridge.swift @@ -135,11 +135,11 @@ internal class CapacitorBridge: NSObject, CAPBridgeProtocol { public func getUserInterfaceStyle() -> UIUserInterfaceStyle { return userInterfaceStyle } - + public func getLocalUrl() -> String { return config.localURL.absoluteString } - + @nonobjc public func setStatusBarAnimation(_ animation: UIStatusBarAnimation) { statusBarAnimation = animation } @@ -537,6 +537,47 @@ internal class CapacitorBridge: NSObject, CAPBridgeProtocol { } } + // MARK: - CAPBridgeProtocol: Paths, Files, Assets + + /** + * Translate a URL from the web view into a file URL for native iOS. + * + * The web view may be handling several different types of URLs: + * - res:// (shortcut scheme to web assets) + * - file:// (fully qualified URL to file on the local device) + * - base64:// (to be implemented) + * - [web view scheme]:// (already converted once to load in the web view, to be implemented) + */ + public func localURL(fromWebURL webURL: URL?) -> URL? { + guard let inputURL = webURL else { + return nil + } + + let url: URL + + switch inputURL.scheme { + case "res": + url = config.appLocation.appendingPathComponent(inputURL.path) + case "file": + url = inputURL + default: + return nil + } + + return url + } + + /** + * Translate a file URL for native iOS into a URL to load in the web view. + */ + public func portablePath(fromLocalURL localURL: URL?) -> URL? { + guard let inputURL = localURL else { + return nil + } + + return self.config.localURL.appendingPathComponent(CapacitorBridge.fileStartIdentifier).appendingPathComponent(inputURL.path) + } + // MARK: - CAPBridgeProtocol: View Presentation @objc public func showAlertWith(title: String, message: String, buttonTitle: String) {