diff --git a/Samples/MobileBuyIntegration/MobileBuyIntegration/AppConfiguration.swift b/Samples/MobileBuyIntegration/MobileBuyIntegration/AppConfiguration.swift index 9ea2cd29..fd890a77 100644 --- a/Samples/MobileBuyIntegration/MobileBuyIntegration/AppConfiguration.swift +++ b/Samples/MobileBuyIntegration/MobileBuyIntegration/AppConfiguration.swift @@ -24,13 +24,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SO import Foundation import ShopifyCheckoutSheetKit -public struct AppConfiguration { +public final class AppConfiguration: ObservableObject { public var storefrontDomain: String = Bundle.main.infoDictionary?["StorefrontDomain"] as? String ?? "" - public var universalLinks = UniversalLinks() + @Published public var universalLinks = UniversalLinks() /// Prefill buyer information - public var useVaultedState: Bool = false + @Published public var useVaultedState: Bool = false /// Logger to retain Web Pixel events internal let webPixelsLogger = FileLogger("analytics.txt") @@ -43,6 +43,21 @@ public var appConfiguration = AppConfiguration() { } public struct UniversalLinks { - public var handleCheckoutInApp: Bool = true - public var handleAllURLsInApp: Bool = true + public var checkout: Bool = true + public var cart: Bool = true + public var products: Bool = true + + public var handleAllURLsInApp: Bool = true { + didSet { + if handleAllURLsInApp { + enableAllURLs() + } + } + } + + private mutating func enableAllURLs() { + checkout = true + products = true + cart = true + } } diff --git a/Samples/MobileBuyIntegration/MobileBuyIntegration/Localizable.xcstrings b/Samples/MobileBuyIntegration/MobileBuyIntegration/Localizable.xcstrings index acfc92f0..85ff5146 100644 --- a/Samples/MobileBuyIntegration/MobileBuyIntegration/Localizable.xcstrings +++ b/Samples/MobileBuyIntegration/MobileBuyIntegration/Localizable.xcstrings @@ -7,7 +7,7 @@ "App version" : { }, - "By default, the app will only handle Checkout URLs (non-thank you page) and route everything else to Safari. This setting will route all Universal Links to the app." : { + "By default, the app will only handle the selections above and route everything else to Safari. Enabling the \"Handle all Universal Links\" setting will route all Universal Links to this app." : { }, "Clear" : { @@ -24,9 +24,15 @@ }, "Handle all Universal Links" : { + }, + "Handle Cart URLs" : { + }, "Handle Checkout URLs" : { + }, + "Handle Product URLs" : { + }, "Logs" : { diff --git a/Samples/MobileBuyIntegration/MobileBuyIntegration/SceneDelegate.swift b/Samples/MobileBuyIntegration/MobileBuyIntegration/SceneDelegate.swift index d5553a8f..75d7cf12 100644 --- a/Samples/MobileBuyIntegration/MobileBuyIntegration/SceneDelegate.swift +++ b/Samples/MobileBuyIntegration/MobileBuyIntegration/SceneDelegate.swift @@ -59,7 +59,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { ] if #available(iOS 15.0, *) { - let settingsController = UIHostingController(rootView: SettingsView()) + let settingsController = UIHostingController(rootView: SettingsView(appConfiguration: appConfiguration)) settingsController.tabBarItem.image = UIImage(systemName: "gearshape.2") settingsController.tabBarItem.title = "Settings" @@ -80,8 +80,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { } func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { - guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, - let incomingURL = userActivity.webpageURL else { + guard + userActivity.activityType == NSUserActivityTypeBrowsingWeb, + let incomingURL = userActivity.webpageURL, + + /// Ensure URL host matches our Storefront domain + let host = incomingURL.host, host == appConfiguration.storefrontDomain + else { return } @@ -89,28 +94,32 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { } func handleUniversalLink(url: URL) { - // The URL host must match the StorefrontDomain defined in our env - guard let host = url.host, host == appConfiguration.storefrontDomain else { return } - let storefrontUrl = StorefrontURL(from: url) switch true { - case appConfiguration.universalLinks.handleCheckoutInApp && storefrontUrl.isCheckout() && !storefrontUrl.isThankYouPage(): - if let vc = cartController { - ShopifyCheckoutSheetKit.present(checkout: url, from: vc, delegate: vc) - } - case appConfiguration.universalLinks.handleAllURLsInApp: - if storefrontUrl.isCart() { - navigateToCart() - } else if let slug = storefrontUrl.getProductSlug() { + /// Checkout URLs + case appConfiguration.universalLinks.checkout && storefrontUrl.isCheckout() && !storefrontUrl.isThankYouPage(): + presentCheckout(url) + /// Cart URLs + case appConfiguration.universalLinks.cart && storefrontUrl.isCart(): + navigateToCart() + /// Product URLs + case appConfiguration.universalLinks.products: + if let slug = storefrontUrl.getProductSlug() { navigateToProduct(with: slug) } + /// Open everything else in Safari default: - // Open all other links in Safari UIApplication.shared.open(url) } } + private func presentCheckout(_ url: URL) { + if let viewController = cartController { + ShopifyCheckoutSheetKit.present(checkout: url, from: viewController, delegate: viewController) + } + } + private func getRootViewController() -> UINavigationController? { return window?.rootViewController as? UINavigationController } @@ -128,7 +137,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { } } - func navigateToProduct(with handle: String) { if let pdp = self.productController { pdp.getProductByHandle(handle) diff --git a/Samples/MobileBuyIntegration/MobileBuyIntegration/SettingsViewController.swift b/Samples/MobileBuyIntegration/MobileBuyIntegration/SettingsViewController.swift index 2ae37ac2..ec90226d 100644 --- a/Samples/MobileBuyIntegration/MobileBuyIntegration/SettingsViewController.swift +++ b/Samples/MobileBuyIntegration/MobileBuyIntegration/SettingsViewController.swift @@ -27,10 +27,9 @@ import ShopifyCheckoutSheetKit @available(iOS 15.0, *) struct SettingsView: View { + @ObservedObject var appConfiguration: AppConfiguration + @State private var preloadingEnabled = ShopifyCheckoutSheetKit.configuration.preloading.enabled - @State private var useVaultedState = appConfiguration.useVaultedState - @State private var handleCheckoutInApp = appConfiguration.universalLinks.handleCheckoutInApp - @State private var handleAllURLsInApp = appConfiguration.universalLinks.handleAllURLsInApp @State private var logs: [String?] = LogReader.shared.readLogs() ?? [] @State private var selectedColorScheme = ShopifyCheckoutSheetKit.configuration.colorScheme @State private var colorScheme: ColorScheme = .light @@ -43,23 +42,16 @@ struct SettingsView: View { .onChange(of: preloadingEnabled) { newValue in ShopifyCheckoutSheetKit.configuration.preloading.enabled = newValue } - Toggle("Prefill buyer information", isOn: $useVaultedState) - .onChange(of: useVaultedState) { newValue in - appConfiguration.useVaultedState = newValue - } + Toggle("Prefill buyer information", isOn: $appConfiguration.useVaultedState) } Section(header: Text("Universal Links")) { - Toggle("Handle Checkout URLs", isOn: $handleCheckoutInApp) - .onChange(of: handleCheckoutInApp) { newValue in - appConfiguration.universalLinks.handleCheckoutInApp = newValue - } - Toggle("Handle all Universal Links", isOn: $handleAllURLsInApp) - .onChange(of: handleAllURLsInApp) { newValue in - appConfiguration.universalLinks.handleAllURLsInApp = newValue - } + Toggle("Handle Checkout URLs", isOn: $appConfiguration.universalLinks.checkout) + Toggle("Handle Cart URLs", isOn: $appConfiguration.universalLinks.cart) + Toggle("Handle Product URLs", isOn: $appConfiguration.universalLinks.products) + Toggle("Handle all Universal Links", isOn: $appConfiguration.universalLinks.handleAllURLsInApp) - Text("By default, the app will only handle Checkout URLs (non-thank you page) and route everything else to Safari. This setting will route all Universal Links to the app.") + Text("By default, the app will only handle the selections above and route everything else to Safari. Enabling the \"Handle all Universal Links\" setting will route all Universal Links to this app.") .font(.caption) } @@ -187,7 +179,7 @@ extension Configuration.ColorScheme { #Preview { if #available(iOS 15.0, *) { - SettingsView() + SettingsView(appConfiguration: appConfiguration) } else { Text("Not supported in < iOS 15") } diff --git a/Sources/ShopifyCheckoutSheetKit/CheckoutBridge.swift b/Sources/ShopifyCheckoutSheetKit/CheckoutBridge.swift index 8e9c90e1..37818613 100644 --- a/Sources/ShopifyCheckoutSheetKit/CheckoutBridge.swift +++ b/Sources/ShopifyCheckoutSheetKit/CheckoutBridge.swift @@ -36,7 +36,7 @@ protocol CheckoutBridgeProtocol { enum CheckoutBridge: CheckoutBridgeProtocol { static let schemaVersion = "8.1" static let messageHandler = "mobileCheckoutSdk" - internal static let userAgent = "ShopifyCheckoutSDK/\(ShopifyCheckoutSheetKit.version)" + internal static let userAgent = "ShopifyLocalDev ShopifyCheckoutSDK/\(ShopifyCheckoutSheetKit.version)" static var applicationName: String { let theme = ShopifyCheckoutSheetKit.configuration.colorScheme.rawValue