diff --git a/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/JSTestWebViewModel.swift b/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/JSTestWebViewModel.swift index 6c5596bb..d745b2a7 100644 --- a/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/JSTestWebViewModel.swift +++ b/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/JSTestWebViewModel.swift @@ -23,7 +23,7 @@ class JSTestWebViewModel: KlaviyoWebViewModeling { private static func initializeLoadScripts() -> [String: WKUserScript] { var scripts: [String: WKUserScript] = [:] - if let toggleHandlerScript = try? FileIO.getFileContents(path: "toggleHandler", type: "js") { + if let toggleHandlerScript = try? ResourceLoader.getResourceContents(path: "toggleHandler", type: "js") { let script = WKUserScript(source: toggleHandlerScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true) scripts["toggleMessageHandler"] = script } diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewController.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewController.swift index 8bdafb74..70fad2e8 100644 --- a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewController.swift +++ b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewController.swift @@ -169,14 +169,14 @@ func createKlaviyoWebPreview(viewModel: KlaviyoWebViewModeling) -> UIViewControl @available(iOS 17.0, *) #Preview("Klaviyo Form") { - let indexHtmlFileUrl = Bundle.module.url(forResource: "klaviyo", withExtension: "html")! + let indexHtmlFileUrl = try! ResourceLoader.getResourceUrl(path: "klaviyo", type: "html") let viewModel = KlaviyoWebViewModel(url: indexHtmlFileUrl) return createKlaviyoWebPreview(viewModel: viewModel) } @available(iOS 17.0, *) #Preview("JS Test Page") { - let indexHtmlFileUrl = Bundle.module.url(forResource: "jstest", withExtension: "html")! + let indexHtmlFileUrl = try! ResourceLoader.getResourceUrl(path: "jstest", type: "html") let viewModel = JSTestWebViewModel(url: indexHtmlFileUrl) return KlaviyoWebViewController(viewModel: viewModel) } diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModel.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModel.swift index 25b59f63..4dfd15ca 100644 --- a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModel.swift +++ b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModel.swift @@ -37,7 +37,7 @@ class KlaviyoWebViewModel: KlaviyoWebViewModeling { private static func initializeLoadScripts() -> [String: WKUserScript] { var scripts: [String: WKUserScript] = [:] - if let closeHandlerScript = try? FileIO.getFileContents(path: "closeHandler", type: "js") { + if let closeHandlerScript = try? ResourceLoader.getResourceContents(path: "closeHandler", type: "js") { let script = WKUserScript(source: closeHandlerScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true) scripts["closeHandler"] = script } diff --git a/Sources/KlaviyoUI/Utilities/FileIO.swift b/Sources/KlaviyoUI/Utilities/FileIO.swift deleted file mode 100644 index 387339f4..00000000 --- a/Sources/KlaviyoUI/Utilities/FileIO.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// FileIO.swift -// KlaviyoSwiftUIWebView -// -// Created by Andrew Balmer on 9/27/24. -// - -import Foundation - -enum FileIOError: Error { - case notFound -} - -enum FileIO { - static func getFileUrl(path: String, type: String) throws -> URL { - guard let fileUrl = Bundle.module.url(forResource: path, withExtension: type) else { - throw FileIOError.notFound - } - - return fileUrl - } - - static func getFileContents(path: String, type: String) throws -> String { - guard let path = Bundle.module.path(forResource: path, ofType: type) else { - throw FileIOError.notFound - } - - do { - let contents = try String(contentsOfFile: path, encoding: String.Encoding.utf8) - return contents - } catch { - throw error - } - } -} diff --git a/Sources/KlaviyoUI/Utilities/ResourceLoader.swift b/Sources/KlaviyoUI/Utilities/ResourceLoader.swift new file mode 100644 index 00000000..8ac05778 --- /dev/null +++ b/Sources/KlaviyoUI/Utilities/ResourceLoader.swift @@ -0,0 +1,64 @@ +// +// ResourceLoader.swift +// KlaviyoSwiftUIWebView +// +// Created by Andrew Balmer on 9/27/24. +// + +#if DEBUG +import Foundation + +enum ResourceLoaderError: Error { + case resourceNotFound +} + +enum ResourceLoader { + static func getResourceUrl(path: String, type: String) throws -> URL { + let bundle = resourceBundle() + + guard let resourceUrl = bundle?.url(forResource: path, withExtension: type) else { + throw ResourceLoaderError.resourceNotFound + } + + return resourceUrl + } + + static func getResourceContents(path: String, type: String) throws -> String { + let bundle = resourceBundle() + + guard let resourcePath = bundle?.path(forResource: path, ofType: type) else { + throw ResourceLoaderError.resourceNotFound + } + + do { + let contents = try String(contentsOfFile: resourcePath, encoding: .utf8) + return contents + } catch { + throw error + } + } + + // Determines the appropriate bundle based on the build system + private static func resourceBundle() -> Bundle? { + #if SWIFT_PACKAGE + return Bundle.module + #else + return Bundle(for: BundleLocator.self).resourceBundle(named: "KlaviyoUIResources") + #endif + } +} + +// Helper class for locating the resource bundle (CocoaPods) +private class BundleLocator {} + +extension Bundle { + fileprivate func resourceBundle(named name: String) -> Bundle? { + guard let bundleUrl = url(forResource: name, withExtension: "bundle"), + let bundle = Bundle(url: bundleUrl) else { + return nil + } + + return bundle + } +} +#endif