diff --git a/.gitignore b/.gitignore index df954b2..f6e03a5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,16 +23,6 @@ playground.xcworkspace # Swift Package Manager # # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -<<<<<<< HEAD -Packages/ -Package.pins -Package.resolved -*.xcodeproj -# -# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata -# hence it is not needed unless you have added a package configuration file to your project -.swiftpm -======= # Packages/ # Package.pins # Package.resolved @@ -41,7 +31,6 @@ Package.resolved # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata # hence it is not needed unless you have added a package configuration file to your project # .swiftpm ->>>>>>> cd22661 (Update) .build/ diff --git a/BranchLinkSimulator.xcodeproj/project.pbxproj b/BranchLinkSimulator.xcodeproj/project.pbxproj index 2ff585c..5b5cbab 100644 --- a/BranchLinkSimulator.xcodeproj/project.pbxproj +++ b/BranchLinkSimulator.xcodeproj/project.pbxproj @@ -19,9 +19,8 @@ C16B97A02B75A0FA00FB0631 /* DeeplinkDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16B979F2B75A0FA00FB0631 /* DeeplinkDetailView.swift */; }; C16B97A22B75A18A00FB0631 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16B97A12B75A18A00FB0631 /* AppDelegate.swift */; }; C16B97B22B87BD8300FB0631 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C16B97B02B87BD8000FB0631 /* AdSupport.framework */; }; - E78DBA1F2E9786B1009FE663 /* BranchSDK.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = E78DBA1E2E9786B1009FE663 /* BranchSDK.xcframework */; }; - E78DBA202E9786B1009FE663 /* BranchSDK.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E78DBA1E2E9786B1009FE663 /* BranchSDK.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; E7EA36B22DD63A350094FCC9 /* SafariServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7EA36B12DD63A350094FCC9 /* SafariServices.framework */; }; + F1A2B3C4D5E6F7891ABCDEF1 /* BranchSDK in Frameworks */ = {isa = PBXBuildFile; productRef = F1A2B3C4D5E6F7890ABCDEF0 /* BranchSDK */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -31,7 +30,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - E78DBA202E9786B1009FE663 /* BranchSDK.xcframework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -54,7 +52,6 @@ C16B97A52B75A4F800FB0631 /* BranchLinkSimulator.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = BranchLinkSimulator.entitlements; sourceTree = ""; }; C16B97A62B75A5F700FB0631 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; C16B97B02B87BD8000FB0631 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; - E78DBA1E2E9786B1009FE663 /* BranchSDK.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = BranchSDK.xcframework; path = Frameworks/BranchSDK.xcframework; sourceTree = ""; }; E7EA36B12DD63A350094FCC9 /* SafariServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SafariServices.framework; path = System/Library/Frameworks/SafariServices.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -64,7 +61,7 @@ buildActionMask = 2147483647; files = ( E7EA36B22DD63A350094FCC9 /* SafariServices.framework in Frameworks */, - E78DBA1F2E9786B1009FE663 /* BranchSDK.xcframework in Frameworks */, + F1A2B3C4D5E6F7891ABCDEF1 /* BranchSDK in Frameworks */, C16B97B22B87BD8300FB0631 /* AdSupport.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -120,7 +117,6 @@ C16B97AF2B87BD8000FB0631 /* Frameworks */ = { isa = PBXGroup; children = ( - E78DBA1E2E9786B1009FE663 /* BranchSDK.xcframework */, E7EA36B12DD63A350094FCC9 /* SafariServices.framework */, C16B97B02B87BD8000FB0631 /* AdSupport.framework */, ); @@ -145,6 +141,7 @@ ); name = BranchLinkSimulator; packageProductDependencies = ( + F1A2B3C4D5E6F7890ABCDEF0 /* BranchSDK */, ); productName = BranchLinkSimulator; productReference = C16B978B2B759F9D00FB0631 /* BranchLinkSimulator.app */; @@ -175,6 +172,7 @@ ); mainGroup = C16B97822B759F9D00FB0631; packageReferences = ( + F1A2B3C4D5E6F7890ABCDEF2 /* XCLocalSwiftPackageReference "ios-branch-deep-linking-attribution" */, ); productRefGroup = C16B978C2B759F9D00FB0631 /* Products */; projectDirPath = ""; @@ -442,6 +440,20 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + F1A2B3C4D5E6F7890ABCDEF2 /* XCLocalSwiftPackageReference "ios-branch-deep-linking-attribution" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = "../ios-branch-deep-linking-attribution"; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + F1A2B3C4D5E6F7890ABCDEF0 /* BranchSDK */ = { + isa = XCSwiftPackageProductDependency; + productName = BranchSDK; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = C16B97832B759F9D00FB0631 /* Project object */; } diff --git a/BranchLinkSimulator/AppDelegate.swift b/BranchLinkSimulator/AppDelegate.swift index 8ffeb7e..85d0439 100644 --- a/BranchLinkSimulator/AppDelegate.swift +++ b/BranchLinkSimulator/AppDelegate.swift @@ -5,8 +5,8 @@ // Created by Nipun Singh on 2/8/24. // -import SwiftUI import BranchSDK +import SwiftUI struct AlertItem: Identifiable { var id: String { message } @@ -22,53 +22,141 @@ class DeepLinkViewModel: ObservableObject { class AppDelegate: UIResponder, UIApplicationDelegate { var deepLinkViewModel = DeepLinkViewModel() var store = RoundTripStore() - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { - + + /// Convenience logger (Objective-C singleton) + private var logger: BranchLogger { + BranchLogger.shared() + } + + func application(_: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { let config = loadConfigOrDefault() + + // Configure the SDK for API URL and Branch Key Branch.setAPIUrl(config.apiUrl) Branch.setBranchKey(config.branchKey) - - Branch.enableLogging(at: .verbose) { msg, logLevel, err, request, response in - self.store.processLog(request, response) - } + + // Enable verbose logging with advanced callback for console output and RoundTripStore + Branch.enableLogging(at: .verbose, withAdvancedCallback: { [weak self] message, logLevel, error, request, response in + // Log to console (os_log doesn't show verbose/debug in Xcode console) + let levelStr: String + switch logLevel { + case .verbose: levelStr = "VERBOSE" + case .debug: levelStr = "DEBUG" + case .warning: levelStr = "WARNING" + case .error: levelStr = "ERROR" + @unknown default: levelStr = "UNKNOWN" + } + var fullMessage = "[BranchSDK][\(levelStr)] \(message)" + if let error = error { + fullMessage += " Error: \(error.localizedDescription)" + } + NSLog("%@", fullMessage) + + // Process for RoundTripStore + self?.store.processLog(request, response) + }) // Retrieve or create the bls_session_id let blsSessionId: String if let savedId = UserDefaults.standard.string(forKey: "blsSessionId") { blsSessionId = savedId } else { - // Generate a new UUID if one does not exist blsSessionId = UUID().uuidString UserDefaults.standard.set(blsSessionId, forKey: "blsSessionId") } - + // Set the bls_session_id in Branch request metadata Branch.getInstance().setRequestMetadataKey("bls_session_id", value: blsSessionId) - Branch.getInstance().initSession(launchOptions: launchOptions) { (params, error) in - print(params as? [String: AnyObject] ?? {}) + // MARK: - Initialize with Branch SDK (Objective-C API) + + logger.logVerbose("Initializing Branch SDK...", error: nil) + + Branch.getInstance().initSession(launchOptions: launchOptions, andRegisterDeepLinkHandler: { [weak self] params, error in + guard let self = self else { return } + if let error = error { + self.logger.logError("Branch init error: \(error.localizedDescription)", error: error) var message = "Failed to initialize Branch SDK: \(error.localizedDescription)." if config.staging { - message += " Are you connected to VPN?" + message += " Are you connected to VPN?" + } + DispatchQueue.main.async { + self.deepLinkViewModel.errorItem = AlertItem(message: message) } - self.deepLinkViewModel.errorItem = AlertItem(message: message) + } else if let params = params { + self.logger.logVerbose("Branch SDK initialized successfully!", error: nil) + self.logger.logDebug("Params: \(params)", error: nil) + + // Handle deep link data if present + self.handleSessionParams(params) } - if let params = params as? [String: AnyObject] { - if let clickedBranchLink = params["+clicked_branch_link"] as? NSNumber, clickedBranchLink.boolValue == true { - DispatchQueue.main.async { - self.deepLinkViewModel.deepLinkData = params - self.deepLinkViewModel.deepLinkHandled = true - } - } else { - print("Didn't click Branch link") + }) + + return true + } + + // MARK: - Session Handling + + /// Handle successful session initialization + private func handleSessionParams(_ params: [AnyHashable: Any]) { + // Check if there's deep link data + let clickedBranchLink = params["+clicked_branch_link"] as? Bool ?? false + + if clickedBranchLink { + logger.logVerbose("Deep link detected!", error: nil) + logger.logDebug("Deep link params: \(params)", error: nil) + + // Convert params to the format expected by the UI + var displayParams: [String: AnyObject] = [:] + for (key, value) in params { + if let stringKey = key as? String { + displayParams[stringKey] = value as AnyObject } + } + DispatchQueue.main.async { + self.deepLinkViewModel.deepLinkData = displayParams + self.deepLinkViewModel.deepLinkHandled = true } + } else { + logger.logVerbose("No deep link data - organic session", error: nil) + } + } + + // MARK: - Universal Links + + func application( + _: UIApplication, + continue userActivity: NSUserActivity, + restorationHandler _: @escaping ([UIUserActivityRestoring]?) -> Void + ) -> Bool { + guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, + let url = userActivity.webpageURL + else { + return false } - + + logger.logVerbose("Received Universal Link: \(url)", error: nil) + + // Handle via Branch SDK + Branch.getInstance().handleDeepLink(url) + + return true + } + + // MARK: - URL Scheme Deep Links + + func application( + _: UIApplication, + open url: URL, + options _: [UIApplication.OpenURLOptionsKey: Any] = [:] + ) -> Bool { + logger.logVerbose("Received URL Scheme: \(url)", error: nil) + + // Handle via Branch SDK + Branch.getInstance().handleDeepLink(url) + return true } - } diff --git a/BranchLinkSimulator/BranchLinkSimulatorApp.swift b/BranchLinkSimulator/BranchLinkSimulatorApp.swift index cc68252..1b1d692 100644 --- a/BranchLinkSimulator/BranchLinkSimulatorApp.swift +++ b/BranchLinkSimulator/BranchLinkSimulatorApp.swift @@ -5,8 +5,8 @@ // Created by Nipun Singh on 2/8/24. // -import SwiftUI import BranchSDK +import SwiftUI @main struct BranchLinkSimulatorApp: App { @@ -17,9 +17,13 @@ struct BranchLinkSimulatorApp: App { HomeView() .environmentObject(appDelegate.deepLinkViewModel) .environmentObject(appDelegate.store) - .onOpenURL(perform: { url in + .onOpenURL { url in + // Use Branch SDK for URL handling + BranchLogger.shared().logVerbose("onOpenURL: \(url)", error: nil) + + // Handle the deep link - Branch SDK will call the init callback Branch.getInstance().handleDeepLink(url) - }) + } } } } diff --git a/BranchLinkSimulator/HomeView.swift b/BranchLinkSimulator/HomeView.swift index 9332602..ad129f0 100644 --- a/BranchLinkSimulator/HomeView.swift +++ b/BranchLinkSimulator/HomeView.swift @@ -1,14 +1,14 @@ // -// ContentView.swift +// HomeView.swift // BranchLinkSimulator // // Created by Nipun Singh on 2/8/24. // -import SwiftUI -import BranchSDK -import AppTrackingTransparency import AdSupport +import AppTrackingTransparency +import BranchSDK +import SwiftUI struct HomeView: View { @EnvironmentObject var deepLinkViewModel: DeepLinkViewModel @@ -22,130 +22,122 @@ struct HomeView: View { @State private var showingEventActionSheet = false @State private var selectedEventType: BranchStandardEvent = .purchase - - @State private var showingQRSheet = false + @State private var qrCodeImage: UIImage? = nil - + var body: some View { - NavigationView { - VStack { - if deepLinkViewModel.deepLinkHandled, let deepLinkData = deepLinkViewModel.deepLinkData { - NavigationLink(destination: DeeplinkDetailView(pageTitle: deepLinkData["page"] as? String ?? "Data", deepLinkParameters: deepLinkData), isActive: $deepLinkViewModel.deepLinkHandled) { - EmptyView() + NavigationStack { + List { + Section(header: Text("Deep Link Pages")) { + NavigationLink(destination: DeeplinkDetailView(pageTitle: "Tree", deepLinkParameters: [:])) { + Label("Go to Tree", systemImage: "tree.fill") } - } else { - List { - Section(header: Text("Deep Link Pages")) { - NavigationLink(destination: DeeplinkDetailView(pageTitle: "Tree", deepLinkParameters: [:])) { - Label("Go to Tree", systemImage: "tree.fill") - } - NavigationLink(destination: DeeplinkDetailView(pageTitle: "Twig", deepLinkParameters: [:])) { - Label("Go to Twig", systemImage: "line.diagonal") - } - NavigationLink(destination: DeeplinkDetailView(pageTitle: "Leaf", deepLinkParameters: [:])) { - Label("Go to Leaf", systemImage: "leaf.fill") - } - } - .headerProminence(.standard) - - Section(header: Text("Events")) { - Button(action: { self.showingEventActionSheet = true }) { - Label("Send Standard Event", systemImage: "paperplane.fill") - .labelStyle(.titleAndIcon) - .foregroundColor(.white) - .padding() - .frame(maxWidth: .infinity) - .background(Color.blue) - .cornerRadius(8) - } - .actionSheet(isPresented: $showingEventActionSheet) { - ActionSheet(title: Text("Choose Event Type"), message: nil, buttons: [ - .default(Text("Purchase"), action: { sendEventOfType(.purchase) }), - .default(Text("Add to Cart"), action: { sendEventOfType(.addToCart) }), - .default(Text("Login"), action: { sendEventOfType(.login) }), - .default(Text("Search"), action: { sendEventOfType(.search) }), - .default(Text("Share"), action: { sendEventOfType(.share) }), + NavigationLink(destination: DeeplinkDetailView(pageTitle: "Twig", deepLinkParameters: [:])) { + Label("Go to Twig", systemImage: "line.diagonal") + } + NavigationLink(destination: DeeplinkDetailView(pageTitle: "Leaf", deepLinkParameters: [:])) { + Label("Go to Leaf", systemImage: "leaf.fill") + } + } + .headerProminence(.standard) - .cancel() - ]) - } - Button(action: sendCustomEvent) { - Label("Send Custom Event", systemImage: "paperplane") - .labelStyle(.titleAndIcon) - .foregroundColor(.white) - .padding() - .frame(maxWidth: .infinity) - .background(Color.blue) - .cornerRadius(8) - } - Button(action: createURL) { - Label("Create Branch Link", systemImage: "link") - .labelStyle(.titleAndIcon) - .foregroundColor(.white) - .padding() - .frame(maxWidth: .infinity) - .background(Color.blue) - .cornerRadius(8) - } - Button(action: createQRCode) { - Label("Create Branch QR Code", systemImage: "qrcode") - .labelStyle(.titleAndIcon) - .foregroundColor(.white) - .padding() - .frame(maxWidth: .infinity) - .background(Color.blue) - .cornerRadius(8) - } - .sheet(isPresented: .constant(showingQRSheet), onDismiss: { - showingQRSheet = false - }) { - if let qrImage = qrCodeImage { - Image(uiImage: qrImage) - .interpolation(.none) - .resizable() - .scaledToFit() - } else { - Text("No QR Code Available") - } - } - } - .headerProminence(.standard) - .listRowSeparator(.hidden) - - - Section("API Settings") { - ApiSettingsView(store: store) + Section(header: Text("Events")) { + Button(action: { self.showingEventActionSheet = true }) { + Label("Send Standard Event", systemImage: "paperplane.fill") + .labelStyle(.titleAndIcon) + .foregroundColor(.white) + .padding() + .frame(maxWidth: .infinity) + .background(Color.blue) + .cornerRadius(8) + } + .actionSheet(isPresented: $showingEventActionSheet) { + ActionSheet(title: Text("Choose Event Type"), message: nil, buttons: [ + .default(Text("Purchase"), action: { sendEventOfType(.purchase) }), + .default(Text("Add to Cart"), action: { sendEventOfType(.addToCart) }), + .default(Text("Login"), action: { sendEventOfType(.login) }), + .default(Text("Search"), action: { sendEventOfType(.search) }), + .default(Text("Share"), action: { sendEventOfType(.share) }), + .cancel(), + ]) + } + Button(action: sendCustomEvent) { + Label("Send Custom Event", systemImage: "paperplane") + .labelStyle(.titleAndIcon) + .foregroundColor(.white) + .padding() + .frame(maxWidth: .infinity) + .background(Color.blue) + .cornerRadius(8) + } + Button(action: createURL) { + Label("Create Branch Link", systemImage: "link") + .labelStyle(.titleAndIcon) + .foregroundColor(.white) + .padding() + .frame(maxWidth: .infinity) + .background(Color.blue) + .cornerRadius(8) + } + Button(action: createQRCode) { + Label("Create Branch QR Code", systemImage: "qrcode") + .labelStyle(.titleAndIcon) + .foregroundColor(.white) + .padding() + .frame(maxWidth: .infinity) + .background(Color.blue) + .cornerRadius(8) + } + .sheet(isPresented: Binding( + get: { qrCodeImage != nil }, + set: { if !$0 { qrCodeImage = nil } } + )) { + if let qrImage = qrCodeImage { + Image(uiImage: qrImage) + .interpolation(.none) + .resizable() + .scaledToFit() } - - Section(header: Text("Event Settings"), footer: Text("Branch SDK v3.7.0").frame(maxWidth: .infinity)) { - VStack(alignment: .leading) { - Text("Customer Event Alias") - .font(.headline) - TextField("Eg. customAlias", text: $eventAlias) - .textFieldStyle(RoundedBorderTextFieldStyle()) - } - .padding(.vertical, 8) - - VStack(alignment: .leading) { - Text("Branch Link Simulator Session ID") - .font(.headline) - TextField("ID Goes Here", text: $sessionID) - .textFieldStyle(RoundedBorderTextFieldStyle()) - } - .padding(.vertical, 8) + } + } + .headerProminence(.standard) + .listRowSeparator(.hidden) - Button("Save Settings") { - saveSettings() - } - .foregroundColor(.blue) - - } - .headerProminence(.standard) + Section("API Settings") { + ApiSettingsView(store: store) + } + + Section(header: Text("Event Settings"), footer: Text("Branch SDK (Objective-C)").frame(maxWidth: .infinity)) { + VStack(alignment: .leading) { + Text("Customer Event Alias") + .font(.headline) + TextField("Eg. customAlias", text: $eventAlias) + .textFieldStyle(RoundedBorderTextFieldStyle()) + } + .padding(.vertical, 8) + + VStack(alignment: .leading) { + Text("Branch Link Simulator Session ID") + .font(.headline) + TextField("ID Goes Here", text: $sessionID) + .textFieldStyle(RoundedBorderTextFieldStyle()) } + .padding(.vertical, 8) + + Button("Save Settings") { + saveSettings() + } + .foregroundColor(.blue) } + .headerProminence(.standard) } .navigationTitle("Branch Link Simulator") .navigationBarTitleDisplayMode(.large) + .navigationDestination(isPresented: $deepLinkViewModel.deepLinkHandled) { + if let deepLinkData = deepLinkViewModel.deepLinkData { + DeeplinkDetailView(pageTitle: deepLinkData["page"] as? String ?? "Data", deepLinkParameters: deepLinkData) + } + } .onAppear { requestIDFAPermission() } @@ -155,91 +147,100 @@ struct HomeView: View { deepLinkViewModel.deepLinkHandled = false } .alert(item: $deepLinkViewModel.errorItem) { errorItem in - Alert( - title: Text("Error"), - message: Text(errorItem.message), - dismissButton: .default(Text("OK")) - ) - } + Alert( + title: Text("Error"), + message: Text(errorItem.message), + dismissButton: .default(Text("OK")) + ) + } } - + func sendEventOfType(_ eventType: BranchStandardEvent) { + BranchLogger.shared().logVerbose("Sending standard event: \(eventType.rawValue)", error: nil) let event = BranchEvent.standardEvent(eventType) event.alias = eventAlias event.customData["bls_session_id"] = sessionID - event.logEvent { result, error in - if error == nil { - self.showToast(message: "Sent \(eventType.rawValue) Event!") - } else { + event.logEvent { success, error in + if let error = error { + BranchLogger.shared().logError("Event error: \(error.localizedDescription)", error: error) self.showToast(message: "Error Sending \(eventType.rawValue) Event!") + } else { + BranchLogger.shared().logVerbose("Event sent successfully (success=\(success))", error: nil) + self.showToast(message: "Sent \(eventType.rawValue) Event!") } } } - + func sendCustomEvent() { - let event = BranchEvent.customEvent(withName:"testedCustomEvent") + BranchLogger.shared().logVerbose("Sending custom event: testedCustomEvent", error: nil) + let event = BranchEvent.customEvent(withName: "testedCustomEvent") event.alias = eventAlias event.customData["bls_session_id"] = sessionID - event.logEvent { result, error in - if error == nil { - self.showToast(message: "Sent Custom Event!") - } else { + event.logEvent { success, error in + if let error = error { + BranchLogger.shared().logError("Custom event error: \(error.localizedDescription)", error: error) self.showToast(message: "Error Sending Custom Event!") + } else { + BranchLogger.shared().logVerbose("Custom event sent successfully (success=\(success))", error: nil) + self.showToast(message: "Sent Custom Event!") } } } - + func saveSettings() { - print("Setting API URL to \(branchAPIURL)") + BranchLogger.shared().logDebug("Setting API URL to \(branchAPIURL)", error: nil) Branch.setAPIUrl(branchAPIURL) - + UserDefaults.standard.set(eventAlias, forKey: "customerEventAlias") UserDefaults.standard.set(sessionID, forKey: "blsSessionId") - + Branch.getInstance().setRequestMetadataKey("bls_session_id", value: sessionID) - - self.showToast(message: "Saved Settings!") - } - + + showToast(message: "Saved Settings!") + } + func showToast(message: String) { - self.toastMessage = message - self.showingToast = true + toastMessage = message + showingToast = true DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.showingToast = false } } - + func requestIDFAPermission() { if #available(iOS 14, *) { DispatchQueue.main.async { - ATTrackingManager.requestTrackingAuthorization { (status) in - if (status == .authorized) { + ATTrackingManager.requestTrackingAuthorization { status in + if status == .authorized { let idfa = ASIdentifierManager.shared().advertisingIdentifier - print("IDFA: " + idfa.uuidString) + BranchLogger.shared().logDebug("IDFA: \(idfa.uuidString)", error: nil) } else { - print("Failed to get IDFA") + BranchLogger.shared().logWarning("Failed to get IDFA", error: nil) } } } } } - + func createURL() { - let buo: BranchUniversalObject = BranchUniversalObject(canonicalIdentifier: "item/12345") - let lp: BranchLinkProperties = BranchLinkProperties() + BranchLogger.shared().logVerbose("Creating Branch link...", error: nil) + let buo = BranchUniversalObject(canonicalIdentifier: "item/12345") + let lp = BranchLinkProperties() buo.getShortUrl(with: lp) { url, error in if let error = error { + BranchLogger.shared().logError("Link creation error: \(error.localizedDescription)", error: error) self.showToast(message: "Error creating link: \(error)") } else { + BranchLogger.shared().logVerbose("Link created: \(url ?? "N/A")", error: nil) self.showToast(message: "Created \(url ?? "N/A")") } } } - + func createQRCode() { - let buo: BranchUniversalObject = BranchUniversalObject(canonicalIdentifier: "item/12345") - let lp: BranchLinkProperties = BranchLinkProperties() + let buo = BranchUniversalObject(canonicalIdentifier: "item/12345") + let lp = BranchLinkProperties() let qrCode = BranchQRCode() qrCode.getAsImage(buo, linkProperties: lp) { image, error in @@ -248,19 +249,17 @@ struct HomeView: View { self.showToast(message: "Error creating QR Code: \(error.localizedDescription)") } else if let image = image { self.qrCodeImage = image - self.showingQRSheet = true } } } } - } extension View { func toast(isShowing: Binding, message: String) -> some View { ZStack(alignment: .bottom) { self - + if isShowing.wrappedValue { VStack { Spacer() @@ -286,7 +285,6 @@ extension View { } } - #Preview { HomeView() } diff --git a/BranchLinkSimulator/RoundTripStore.swift b/BranchLinkSimulator/RoundTripStore.swift index b1456a7..71ed94a 100644 --- a/BranchLinkSimulator/RoundTripStore.swift +++ b/BranchLinkSimulator/RoundTripStore.swift @@ -1,9 +1,9 @@ -import Foundation import BranchSDK +import Foundation class RoundTripStore: ObservableObject { let FAILED = "failed to parse" - + @Published var roundTrips: [RoundTrip] = [] { didSet { saveRoundTrips() @@ -38,7 +38,6 @@ class RoundTripStore: ObservableObject { if roundTrips.count > 30 { roundTrips = Array(roundTrips.prefix(30)) } - } private func sortRoundTrips() { @@ -63,7 +62,7 @@ class RoundTripStore: ObservableObject { print("Failed to load round trips: \(error)") } } - + func processLog(_ request: NSMutableURLRequest?, _ response: BNCServerResponse?) { if let req = request { let branchReq = process(request: req) @@ -77,16 +76,16 @@ class RoundTripStore: ObservableObject { func process(request req: NSMutableURLRequest) -> BranchRequest { let body = req.httpBody.flatMap { String(data: $0, encoding: .utf8) } - + return BranchRequest( headers: req.allHTTPHeaderFields?.description ?? FAILED, body: body ?? FAILED ) } - + func process(response resp: BNCServerResponse) -> BranchResponse { let statusCode = String(resp.statusCode.intValue) - + var body = FAILED if let dictionary = resp.data as? NSDictionary { do { @@ -99,5 +98,3 @@ class RoundTripStore: ObservableObject { return BranchResponse(statusCode: statusCode, body: body) } } - -