From 124adc339209cdd8e797595f0da559d324e0be9e Mon Sep 17 00:00:00 2001 From: VasanthanRajTouchtier Date: Sat, 9 Aug 2025 12:14:49 +0530 Subject: [PATCH] Add setBranchKey support and refactor Branch key handling Introduced setBranchKey method to FlutterBranchSdk for dynamic Branch key assignment, and updated Android and iOS plugins to support this method. Deprecated static Branch key configuration in AndroidManifest.xml and Info.plist in favor of runtime assignment. Refactored and formatted code for improved readability and maintainability, and updated example usage accordingly. --- .../FlutterBranchSdkPlugin.java | 152 +++--- .../android/app/src/main/AndroidManifest.xml | 8 +- example/ios/Podfile.lock | 13 + example/ios/Runner.xcodeproj/project.pbxproj | 18 + .../xcshareddata/swiftpm/Package.resolved | 15 - .../xcshareddata/swiftpm/Package.resolved | 15 - example/ios/Runner/Info.plist | 6 +- example/lib/main.dart | 1 + .../FlutterBranchSdkPlugin.swift | 493 ++++++++++-------- lib/flutter_branch_sdk.dart | 3 + lib/src/flutter_branch_sdk.dart | 116 +++-- 11 files changed, 473 insertions(+), 367 deletions(-) delete mode 100644 example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved delete mode 100644 example/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/android/src/main/java/br/com/rsmarques/flutter_branch_sdk/FlutterBranchSdkPlugin.java b/android/src/main/java/br/com/rsmarques/flutter_branch_sdk/FlutterBranchSdkPlugin.java index 3f343dcb..db89793a 100644 --- a/android/src/main/java/br/com/rsmarques/flutter_branch_sdk/FlutterBranchSdkPlugin.java +++ b/android/src/main/java/br/com/rsmarques/flutter_branch_sdk/FlutterBranchSdkPlugin.java @@ -46,7 +46,8 @@ import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.NewIntentListener; -public class FlutterBranchSdkPlugin implements FlutterPlugin, MethodCallHandler, StreamHandler, NewIntentListener, ActivityAware, +public class FlutterBranchSdkPlugin + implements FlutterPlugin, MethodCallHandler, StreamHandler, NewIntentListener, ActivityAware, Application.ActivityLifecycleCallbacks { private static final String DEBUG_NAME = "FlutterBranchSDK"; private static final String MESSAGE_CHANNEL = "flutter_branch_sdk/message"; @@ -68,46 +69,45 @@ public class FlutterBranchSdkPlugin implements FlutterPlugin, MethodCallHandler, * Branch SDK Call Methods * -------------------------------------------------------------------------------------------- **/ - private final Branch.BranchReferralInitListener branchReferralInitListener = new - Branch.BranchReferralInitListener() { - @Override - public void onInitFinished(JSONObject params, BranchError error) { - LogUtils.debug(DEBUG_NAME, "triggered onInitFinished"); - if (error == null) { - LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener - params: " + params.toString()); - try { - sessionParams = branchSdkHelper.paramsToMap(params); - } catch (JSONException e) { - LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener - error to Map: " + e.getLocalizedMessage()); - return; - } - if (eventSink != null) { - eventSink.success(sessionParams); - sessionParams = null; - } - } else if (error.getErrorCode() == BranchError.ERR_BRANCH_ALREADY_INITIALIZED) { - LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener : " + error.getMessage()); - try { - sessionParams = branchSdkHelper.paramsToMap(Branch.getInstance().getLatestReferringParams()); - } catch (JSONException e) { - LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener - error to Map: " + e.getLocalizedMessage()); - return; - } - if (eventSink != null) { - eventSink.success(sessionParams); - sessionParams = null; - } - } else { - LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener - error: " + error); - if (eventSink != null) { - eventSink.error(String.valueOf(error.getErrorCode()), error.getMessage(), null); - initialError = null; - } else { - initialError = error; - } - } + private final Branch.BranchReferralInitListener branchReferralInitListener = new Branch.BranchReferralInitListener() { + @Override + public void onInitFinished(JSONObject params, BranchError error) { + LogUtils.debug(DEBUG_NAME, "triggered onInitFinished"); + if (error == null) { + LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener - params: " + params.toString()); + try { + sessionParams = branchSdkHelper.paramsToMap(params); + } catch (JSONException e) { + LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener - error to Map: " + e.getLocalizedMessage()); + return; + } + if (eventSink != null) { + eventSink.success(sessionParams); + sessionParams = null; } - }; + } else if (error.getErrorCode() == BranchError.ERR_BRANCH_ALREADY_INITIALIZED) { + LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener : " + error.getMessage()); + try { + sessionParams = branchSdkHelper.paramsToMap(Branch.getInstance().getLatestReferringParams()); + } catch (JSONException e) { + LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener - error to Map: " + e.getLocalizedMessage()); + return; + } + if (eventSink != null) { + eventSink.success(sessionParams); + sessionParams = null; + } + } else { + LogUtils.debug(DEBUG_NAME, "BranchReferralInitListener - error: " + error); + if (eventSink != null) { + eventSink.error(String.valueOf(error.getErrorCode()), error.getMessage(), null); + initialError = null; + } else { + initialError = error; + } + } + } + }; private boolean isInitialized = false; /** @@ -147,7 +147,8 @@ private void setActivity(Activity activity) { activity.getApplication().registerActivityLifecycleCallbacks(this); if (this.activity != null && FlutterFragmentActivity.class.isAssignableFrom(activity.getClass())) { - Branch.sessionBuilder(activity).withCallback(branchReferralInitListener).withData(activity.getIntent().getData()).init(); + Branch.sessionBuilder(activity).withCallback(branchReferralInitListener) + .withData(activity.getIntent().getData()).init(); } } @@ -235,7 +236,8 @@ public void onActivityStarted(@NonNull Activity activity) { return; } LogUtils.debug(DEBUG_NAME, "triggered SessionBuilder init"); - Branch.sessionBuilder(activity).withCallback(branchReferralInitListener).withData(activity.getIntent().getData()).init(); + Branch.sessionBuilder(activity).withCallback(branchReferralInitListener) + .withData(activity.getIntent().getData()).init(); } @Override @@ -295,6 +297,13 @@ public boolean onNewIntent(@NonNull Intent intent) { public void onMethodCall(@NonNull MethodCall call, @NonNull Result rawResult) { Result result = new MethodResultWrapper(rawResult); switch (call.method) { + case "setBranchKey": + String branchKey = call.argument("branchKey"); + if (branchKey != null) { + Branch.getAutoInstance(context).setBranchKey(branchKey); + } + result.success(null); + break; case "init": setupBranch(call, result); break; @@ -462,7 +471,8 @@ private void setupBranch(MethodCall call, final Result result) { final String branchAttributionLevelString = call.argument("branchAttributionLevel"); if (branchAttributionLevelString != null && !branchAttributionLevelString.isEmpty()) { - Branch.getInstance().setConsumerProtectionAttributionLevel(Defines.BranchAttributionLevel.valueOf(branchAttributionLevelString)); + Branch.getInstance().setConsumerProtectionAttributionLevel( + Defines.BranchAttributionLevel.valueOf(branchAttributionLevelString)); } LogUtils.debug(DEBUG_NAME, "notifyNativeToInit()"); @@ -481,7 +491,8 @@ private void getShortUrl(MethodCall call, final Result result) { } HashMap argsMap = (HashMap) call.arguments; BranchUniversalObject buo = branchSdkHelper.convertToBUO((HashMap) argsMap.get("buo")); - LinkProperties linkProperties = branchSdkHelper.convertToLinkProperties((HashMap) argsMap.get("lp")); + LinkProperties linkProperties = branchSdkHelper + .convertToLinkProperties((HashMap) argsMap.get("lp")); final Map response = new HashMap<>(); buo.generateShortUrl(activity, linkProperties, new Branch.BranchLinkCreateListener() { @Override @@ -507,7 +518,8 @@ private void showShareSheet(MethodCall call, final Result result) { } HashMap argsMap = (HashMap) call.arguments; BranchUniversalObject buo = branchSdkHelper.convertToBUO((HashMap) argsMap.get("buo")); - LinkProperties linkProperties = branchSdkHelper.convertToLinkProperties((HashMap) argsMap.get("lp")); + LinkProperties linkProperties = branchSdkHelper + .convertToLinkProperties((HashMap) argsMap.get("lp")); String messageText = (String) argsMap.get("messageText"); String messageTitle = (String) argsMap.get("messageTitle"); String sharingTitle = (String) argsMap.get("sharingTitle"); @@ -516,25 +528,25 @@ private void showShareSheet(MethodCall call, final Result result) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { Branch.getInstance().share(activity, buo, linkProperties, new Branch.BranchNativeLinkShareListener() { - @Override - public void onLinkShareResponse(String sharedLink, BranchError error) { - if (error == null) { - LogUtils.debug(DEBUG_NAME, "Branch link share: " + sharedLink); - response.put("success", Boolean.TRUE); - response.put("url", sharedLink); - } else { - response.put("success", Boolean.FALSE); - response.put("errorCode", String.valueOf(error.getErrorCode())); - response.put("errorMessage", error.getMessage()); - } - result.success(response); - } + @Override + public void onLinkShareResponse(String sharedLink, BranchError error) { + if (error == null) { + LogUtils.debug(DEBUG_NAME, "Branch link share: " + sharedLink); + response.put("success", Boolean.TRUE); + response.put("url", sharedLink); + } else { + response.put("success", Boolean.FALSE); + response.put("errorCode", String.valueOf(error.getErrorCode())); + response.put("errorMessage", error.getMessage()); + } + result.success(response); + } - @Override - public void onChannelSelected(String channelName) { - LogUtils.debug(DEBUG_NAME, "Branch link share channel: " + channelName); - } - }, + @Override + public void onChannelSelected(String channelName) { + LogUtils.debug(DEBUG_NAME, "Branch link share channel: " + channelName); + } + }, messageTitle, messageText); } else { @@ -574,7 +586,8 @@ public void onChannelSelected(String channelName) { } @Override - public boolean onChannelSelected(String channelName, BranchUniversalObject buo, LinkProperties linkProperties) { + public boolean onChannelSelected(String channelName, BranchUniversalObject buo, + LinkProperties linkProperties) { return false; } }); @@ -845,8 +858,10 @@ private void getQRCode(final MethodCall call, final Result result) { } HashMap argsMap = (HashMap) call.arguments; final BranchUniversalObject buo = branchSdkHelper.convertToBUO((HashMap) argsMap.get("buo")); - final LinkProperties linkProperties = branchSdkHelper.convertToLinkProperties((HashMap) argsMap.get("lp")); - final BranchQRCode branchQRCode = branchSdkHelper.convertToQRCode((HashMap) argsMap.get("qrCodeSettings")); + final LinkProperties linkProperties = branchSdkHelper + .convertToLinkProperties((HashMap) argsMap.get("lp")); + final BranchQRCode branchQRCode = branchSdkHelper + .convertToQRCode((HashMap) argsMap.get("qrCodeSettings")); final Map response = new HashMap<>(); try { branchQRCode.getQRCodeAsData(context, buo, linkProperties, new BranchQRCode.BranchQRCodeDataHandler() { @@ -995,8 +1010,7 @@ private void setConsumerProtectionAttributionLevel(MethodCall call) { throw new IllegalArgumentException("Map argument expected"); } final String branchAttributionLevelString = call.argument("branchAttributionLevel"); - Branch.getInstance().setConsumerProtectionAttributionLevel(Defines.BranchAttributionLevel.valueOf(branchAttributionLevelString)); + Branch.getInstance().setConsumerProtectionAttributionLevel( + Defines.BranchAttributionLevel.valueOf(branchAttributionLevelString)); } } - - diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index b1c2a0fd..9fbbcef2 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -49,13 +49,13 @@ android:name="flutterEmbedding" android:value="2" /> - + android:value="key_live_bkJRqpb15wLqUAgsDVNUIobjyviWi6Wx" /> --> - + android:value="key_test_ipQTteg11ENANDeCzSXgqdgfuycWoXYH" /> --> diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index cef6aa64..d3d053b9 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,15 +1,28 @@ PODS: + - BranchSDK (3.12.2) - Flutter (1.0.0) + - flutter_branch_sdk (8.6.0): + - BranchSDK (~> 3.12.0) + - Flutter DEPENDENCIES: - Flutter (from `Flutter`) + - flutter_branch_sdk (from `.symlinks/plugins/flutter_branch_sdk/ios`) + +SPEC REPOS: + trunk: + - BranchSDK EXTERNAL SOURCES: Flutter: :path: Flutter + flutter_branch_sdk: + :path: ".symlinks/plugins/flutter_branch_sdk/ios" SPEC CHECKSUMS: + BranchSDK: db2c2ffa5b85ad3e202f73393ca794878afd3c52 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + flutter_branch_sdk: e61c2074456e7df20555378ba0c7603a6094f6c2 PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index f2400c09..4ffdae9b 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -146,6 +146,7 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 3ECB9F60410FE9CE00AB9B59 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -229,6 +230,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 3ECB9F60410FE9CE00AB9B59 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 4cddd50d..00000000 --- a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,15 +0,0 @@ -{ - "originHash" : "5d76efac60f24ab19e3242c4ab5e2221c42909bca3cd8f4f737ce4a88473446e", - "pins" : [ - { - "identity" : "ios-branch-sdk-spm", - "kind" : "remoteSourceControl", - "location" : "https://github.com/BranchMetrics/ios-branch-sdk-spm", - "state" : { - "revision" : "26d4a43d7b8bda3ecb2a88eabc0d7c09d4baa8b7", - "version" : "3.12.1" - } - } - ], - "version" : 3 -} diff --git a/example/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/example/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 4cddd50d..00000000 --- a/example/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,15 +0,0 @@ -{ - "originHash" : "5d76efac60f24ab19e3242c4ab5e2221c42909bca3cd8f4f737ce4a88473446e", - "pins" : [ - { - "identity" : "ios-branch-sdk-spm", - "kind" : "remoteSourceControl", - "location" : "https://github.com/BranchMetrics/ios-branch-sdk-spm", - "state" : { - "revision" : "26d4a43d7b8bda3ecb2a88eabc0d7c09d4baa8b7", - "version" : "3.12.1" - } - } - ], - "version" : 3 -} diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 4181853d..c3ff6221 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -60,13 +60,13 @@ UIViewControllerBasedStatusBarAppearance - branch_key - + + branch_universal_link_domains flutterbranchsdk.app.link diff --git a/example/lib/main.dart b/example/lib/main.dart index 1bccac12..13e573b9 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -31,6 +31,7 @@ void main() async { FlqutterBranchSdk.setRequestMetadata('key2', 'value2'); */ + await FlutterBranchSdk.e setBranchKey('r'); await FlutterBranchSdk.init(enableLogging: true, branchAttributionLevel: BranchAttributionLevel.FULL); FlutterBranchSdk.setConsumerProtectionAttributionLevel(BranchAttributionLevel.FULL); diff --git a/ios/flutter_branch_sdk/sources/flutter_branch_sdk/FlutterBranchSdkPlugin.swift b/ios/flutter_branch_sdk/sources/flutter_branch_sdk/FlutterBranchSdkPlugin.swift index 2568215d..bad294dc 100644 --- a/ios/flutter_branch_sdk/sources/flutter_branch_sdk/FlutterBranchSdkPlugin.swift +++ b/ios/flutter_branch_sdk/sources/flutter_branch_sdk/FlutterBranchSdkPlugin.swift @@ -1,137 +1,150 @@ +import AdSupport +import AppTrackingTransparency +import BranchSDK import Flutter import UIKit -import BranchSDK -import AppTrackingTransparency -import AdSupport var methodChannel: FlutterMethodChannel? var eventChannel: FlutterEventChannel? -let MESSAGE_CHANNEL = "flutter_branch_sdk/message"; -let EVENT_CHANNEL = "flutter_branch_sdk/event"; -let ERROR_CODE = "FLUTTER_BRANCH_SDK_ERROR"; -let PLUGIN_NAME = "Flutter"; -let PLUGIN_VERSION = "8.6.0"; -let COCOA_POD_NAME = "org.cocoapods.flutter-branch-sdk"; - -public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandler { +let MESSAGE_CHANNEL = "flutter_branch_sdk/message" +let EVENT_CHANNEL = "flutter_branch_sdk/event" +let ERROR_CODE = "FLUTTER_BRANCH_SDK_ERROR" +let PLUGIN_NAME = "Flutter" +let PLUGIN_VERSION = "8.6.0" +let COCOA_POD_NAME = "org.cocoapods.flutter-branch-sdk" + +public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandler { var eventSink: FlutterEventSink? - var initialParams : [String: Any]? = nil - var initialError : NSError? = nil - - var branch : Branch? + var initialParams: [String: Any]? = nil + var initialError: NSError? = nil + + var branch: Branch? var isInitialized = false - - var requestMetadata : [String: String] = [:] - var facebookParameters : [String: String] = [:] - var snapParameters : [String: String] = [:] - + + var launchOptionsStored: [AnyHashable: Any] = [:] + + var requestMetadata: [String: String] = [:] + var facebookParameters: [String: String] = [:] + var snapParameters: [String: String] = [:] + //--------------------------------------------------------------------------------------------- // Plugin registry // -------------------------------------------------------------------------------------------- public static func register(with registrar: FlutterPluginRegistrar) { let instance = FlutterBranchSdkPlugin() - - methodChannel = FlutterMethodChannel(name: MESSAGE_CHANNEL, binaryMessenger: registrar.messenger()) - eventChannel = FlutterEventChannel(name: EVENT_CHANNEL, binaryMessenger: registrar.messenger()) + + methodChannel = FlutterMethodChannel( + name: MESSAGE_CHANNEL, binaryMessenger: registrar.messenger()) + eventChannel = FlutterEventChannel( + name: EVENT_CHANNEL, binaryMessenger: registrar.messenger()) eventChannel!.setStreamHandler(instance) - + registrar.addApplicationDelegate(instance) registrar.addMethodCallDelegate(instance, channel: methodChannel!) } - - public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [AnyHashable : Any] = [:]) -> Bool { - - Branch.getInstance().registerPluginName(PLUGIN_NAME, version: PLUGIN_VERSION) - - let disable_nativelink : Bool = { - guard let value = Bundle.main.object(forInfoDictionaryKey: "branch_disable_nativelink") as? Bool else { + + public func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [AnyHashable: Any] = [:] + ) -> Bool { + + Branch.getInstance().registerPluginName(PLUGIN_NAME, version: PLUGIN_VERSION) + + let disable_nativelink: Bool = { + guard + let value = Bundle.main.object(forInfoDictionaryKey: "branch_disable_nativelink") + as? Bool + else { return false } return value }() - print("Branch Disable NativeLink: \(String(describing:disable_nativelink))"); - + print("Branch Disable NativeLink: \(String(describing:disable_nativelink))") + if !disable_nativelink { if #available(iOS 15.0, *) { Branch.getInstance().checkPasteboardOnInstall() } } - - Branch.getInstance().initSession(launchOptions: launchOptions) { (params, error) in - if error == nil { - print("Branch InitSession params: \(String(describing: params as? [String: Any]))") - guard let _ = self.eventSink else { - self.initialParams = params as? [String: Any] - return - } - self.eventSink!(params as? [String: Any]) - } else { - let err = (error! as NSError) - print("Branch InitSession error: \(err.localizedDescription)") - guard let _ = self.eventSink else { - self.initialError = err - return - } - self.eventSink!(FlutterError(code: String(err.code), - message: err.localizedDescription, - details: nil)) - } - } + + self.launchOptionsStored = launchOptions return true } - - public func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { + + public func application( + _ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:] + ) -> Bool { let branchHandled = Branch.getInstance().application(app, open: url, options: options) return branchHandled } - - public func application(_ app: UIApplication, open url: URL, sourceApplication: String, annotation: Any) -> Bool { - let branchHandled = Branch.getInstance().application(app, open: url, sourceApplication: sourceApplication, annotation: annotation) + + public func application( + _ app: UIApplication, open url: URL, sourceApplication: String, annotation: Any + ) -> Bool { + let branchHandled = Branch.getInstance().application( + app, open: url, sourceApplication: sourceApplication, annotation: annotation) return branchHandled } - - public func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]) -> Void) -> Bool { + + public func application( + _ application: UIApplication, continue userActivity: NSUserActivity, + restorationHandler: @escaping ([Any]) -> Void + ) -> Bool { let handledByBranch = Branch.getInstance().continue(userActivity) return handledByBranch } - - public func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) { + + public func application( + _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any] + ) { Branch.getInstance().handlePushNotification(userInfo) } - + //--------------------------------------------------------------------------------------------- // FlutterStreamHandler Interface Methods // -------------------------------------------------------------------------------------------- - public func onListen(withArguments arguments: Any?, - eventSink: @escaping FlutterEventSink) -> FlutterError? { + public func onListen( + withArguments arguments: Any?, + eventSink: @escaping FlutterEventSink + ) -> FlutterError? { self.eventSink = eventSink - if (initialParams != nil) { + if initialParams != nil { self.eventSink!(self.initialParams) initialParams = nil initialError = nil - } else if (initialError != nil) { - self.eventSink!(FlutterError(code: String(self.initialError!.code), - message: self.initialError!.localizedDescription, - details: nil)) + } else if initialError != nil { + self.eventSink!( + FlutterError( + code: String(self.initialError!.code), + message: self.initialError!.localizedDescription, + details: nil)) initialParams = nil initialError = nil } return nil } - + public func onCancel(withArguments arguments: Any?) -> FlutterError? { eventSink = nil initialParams = nil initialError = nil return nil } - + //--------------------------------------------------------------------------------------------- // FlutterMethodChannel Interface Methods // -------------------------------------------------------------------------------------------- public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch (call.method) { + switch call.method { + case "setBranchKey": + if let args = call.arguments as? [String: Any], + let branchKey = args["branchKey"] as? String, + !branchKey.isEmpty + { + Branch.setBranchKey(branchKey) // <-- change this line + } + result(nil) case "init": setupBranch(call: call, result: result) break @@ -160,7 +173,7 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl setIdentity(call: call) break case "setRequestMetadata": - setRequestMetadata(call: call); + setRequestMetadata(call: call) break case "logout": logout() @@ -180,13 +193,13 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl case "isUserIdentified": isUserIdentified(result: result) break - case "requestTrackingAuthorization" : + case "requestTrackingAuthorization": requestTrackingAuthorization(result: result) break - case "getTrackingAuthorizationStatus" : + case "getTrackingAuthorizationStatus": getTrackingAuthorizationStatus(result: result) break - case "getAdvertisingIdentifier" : + case "getAdvertisingIdentifier": getAdvertisingIdentifier(result: result) break case "setConnectTimeout": @@ -213,91 +226,121 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl case "handleDeepLink": handleDeepLink(call: call) break - case "addFacebookPartnerParameter" : + case "addFacebookPartnerParameter": addFacebookPartnerParameter(call: call) break - case "clearPartnerParameters" : + case "clearPartnerParameters": Branch.getInstance().clearPartnerParameters() break - case "setPreinstallCampaign" : + case "setPreinstallCampaign": setPreinstallPartner(call: call) break - case "setPreinstallPartner" : + case "setPreinstallPartner": setPreinstallPartner(call: call) break - case "addSnapPartnerParameter" : + case "addSnapPartnerParameter": addSnapPartnerParameter(call: call) break case "setDMAParamsForEEA": setDMAParamsForEEA(call: call) - break; - case "setConsumerProtectionAttributionLevel" : + break + case "setConsumerProtectionAttributionLevel": setConsumerProtectionAttributionLevel(call: call) - break; + break default: result(FlutterMethodNotImplemented) break } } - + //--------------------------------------------------------------------------------------------- // Branch SDK Call Methods // -------------------------------------------------------------------------------------------- private func setupBranch(call: FlutterMethodCall, result: @escaping FlutterResult) { - - if (isInitialized) { + + if isInitialized { result(true) } let args = call.arguments as! [String: Any?] - -#if DEBUG - NSLog("setupBranch args: %@", args) -#endif - + + #if DEBUG + NSLog("setupBranch args: %@", args) + #endif + if args["disableTracking"] as! Bool == true { Branch.setTrackingDisabled(true) } else { Branch.setTrackingDisabled(false) } - + let branchAttributionLevel = args["branchAttributionLevel"] as! String - if (!branchAttributionLevel.isEmpty) { - Branch.getInstance().setConsumerProtectionAttributionLevel(BranchAttributionLevel(rawValue: branchAttributionLevel)) + if !branchAttributionLevel.isEmpty { + Branch.getInstance().setConsumerProtectionAttributionLevel( + BranchAttributionLevel(rawValue: branchAttributionLevel)) } - + if args["enableLogging"] as! Bool == true { Branch.enableLogging(at: BranchLogLevel.debug) } - - if (!requestMetadata.isEmpty) { + + if !requestMetadata.isEmpty { for param in requestMetadata { Branch.getInstance().setRequestMetadataKey(param.key, value: param.value) } } - if (!snapParameters.isEmpty) { + if !snapParameters.isEmpty { for param in snapParameters { - Branch.getInstance().addSnapPartnerParameter(withName: param.key, value: param.value) + Branch.getInstance().addSnapPartnerParameter( + withName: param.key, value: param.value) } } - if (!facebookParameters.isEmpty) { + if !facebookParameters.isEmpty { for param in facebookParameters { - Branch.getInstance().addFacebookPartnerParameter(withName: param.key, value: param.value) + Branch.getInstance().addFacebookPartnerParameter( + withName: param.key, value: param.value) } } isInitialized = true + self.startBranchSession() result(true) } - + + private func startBranchSession() { + guard isInitialized else { return } + Branch.getInstance().initSession(launchOptions: launchOptionsStored) { (params, error) in + if error == nil { + print("Branch InitSession params: \(String(describing: params as? [String: Any]))") + guard self.eventSink != nil else { + self.initialParams = params as? [String: Any] + return + } + self.eventSink!(params as? [String: Any]) + } else { + let err = (error! as NSError) + print("Branch InitSession error: \(err.localizedDescription)") + guard self.eventSink != nil else { + self.initialError = err + return + } + self.eventSink!( + FlutterError( + code: String(err.code), + message: err.localizedDescription, + details: nil)) + } + } + } + private func getShortUrl(call: FlutterMethodCall, result: @escaping FlutterResult) { let args = call.arguments as! [String: Any?] let buoDict = args["buo"] as! [String: Any?] let lpDict = args["lp"] as! [String: Any?] let buo: BranchUniversalObject? = convertToBUO(dict: buoDict) - let lp : BranchLinkProperties? = convertToLp(dict: lpDict ) - - let response : NSMutableDictionary! = [:] + let lp: BranchLinkProperties? = convertToLp(dict: lpDict) + + let response: NSMutableDictionary! = [:] buo?.getShortUrl(with: lp!) { (url, error) in - if ((error == nil && url != nil) || (error != nil && url != nil)) { + if (error == nil && url != nil) || (error != nil && url != nil) { NSLog("getShortUrl: %@", url!) response["success"] = NSNumber(value: true) response["url"] = url! @@ -308,7 +351,8 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl response["errorMessage"] = err.localizedDescription } else { response["errorCode"] = "" - response["errorMessage"] = "errorMessage not returned by Branch SDK. See log for details." + response["errorMessage"] = + "errorMessage not returned by Branch SDK. See log for details." } } DispatchQueue.main.async { @@ -316,18 +360,19 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl } } } - + private func showShareSheet(call: FlutterMethodCall, result: @escaping FlutterResult) { let args = call.arguments as! [String: Any?] let buoDict = args["buo"] as! [String: Any?] let lpDict = args["lp"] as! [String: Any?] let shareText = args["messageText"] as! String let buo: BranchUniversalObject? = convertToBUO(dict: buoDict) - let lp : BranchLinkProperties? = convertToLp(dict: lpDict ) + let lp: BranchLinkProperties? = convertToLp(dict: lpDict) let controller = UIApplication.shared.keyWindow!.rootViewController - - let response : NSMutableDictionary! = [:] - buo?.showShareSheet(with: lp, andShareText: shareText, from: controller) { (activityType, completed, error) in + + let response: NSMutableDictionary! = [:] + buo?.showShareSheet(with: lp, andShareText: shareText, from: controller) { + (activityType, completed, error) in if completed { response["success"] = NSNumber(value: true) } else { @@ -345,13 +390,13 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl } } } - + private func validateSDKIntegration() { DispatchQueue.main.async { Branch.getInstance().validateSDKIntegration() } } - + private func trackContent(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let buoDict = args["buo"] as! [[String: Any?]] @@ -359,43 +404,43 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl let buoList: [BranchUniversalObject] = buoDict.map { b in convertToBUO(dict: b)! } - let event: BranchEvent? = convertToEvent(dict : eventDict) - event!.contentItems = buoList - + let event: BranchEvent? = convertToEvent(dict: eventDict) + event!.contentItems = buoList + DispatchQueue.main.async { event!.logEvent() } } - + private func trackContentWithoutBuo(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let eventDict = args["event"] as! [String: Any?] - let event: BranchEvent? = convertToEvent(dict : eventDict) - + let event: BranchEvent? = convertToEvent(dict: eventDict) + DispatchQueue.main.async { event!.logEvent() } } - + private func registerView(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let buoDict = args["buo"] as! [String: Any?] let buo: BranchUniversalObject? = convertToBUO(dict: buoDict) - + DispatchQueue.main.async { buo!.registerView() } } - + private func listOnSearch(call: FlutterMethodCall, result: @escaping FlutterResult) { let args = call.arguments as! [String: Any?] let buoDict = args["buo"] as! [String: Any?] let buo: BranchUniversalObject? = convertToBUO(dict: buoDict) var response = NSNumber(value: true) if let lpDict = args["lp"] as? [String: Any?] { - let lp : BranchLinkProperties! = convertToLp(dict: lpDict) + let lp: BranchLinkProperties! = convertToLp(dict: lpDict) buo!.listOnSpotlight(with: lp) { (url, error) in - if (error == nil) { + if error == nil { print("Successfully indexed on spotlight") response = NSNumber(value: true) } else { @@ -407,8 +452,8 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl } } } else { - buo!.listOnSpotlight() { (url, error) in - if (error == nil) { + buo!.listOnSpotlight { (url, error) in + if error == nil { print("Successfully indexed on spotlight") response = NSNumber(value: true) } else { @@ -421,14 +466,14 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl } } } - + private func removeFromSearch(call: FlutterMethodCall, result: @escaping FlutterResult) { let args = call.arguments as! [String: Any?] let buoDict = args["buo"] as! [String: Any?] let buo: BranchUniversalObject? = convertToBUO(dict: buoDict) var response = NSNumber(value: true) buo!.removeFromSpotlight { (error) in - if (error == nil) { + if error == nil { print("BUO successfully removed from spotlight") response = NSNumber(value: true) } else { @@ -439,74 +484,78 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl } } } - + private func setIdentity(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let userId = args["userId"] as! String - + DispatchQueue.main.async { Branch.getInstance().setIdentity(userId) } } - + private func setRequestMetadata(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let key = args["key"] as! String let value = args["value"] as! String - - - if (requestMetadata.keys.contains(key) && value.isEmpty) { + + if requestMetadata.keys.contains(key) && value.isEmpty { requestMetadata.removeValue(forKey: key) } else { - requestMetadata[key] = value; + requestMetadata[key] = value } - + DispatchQueue.main.async { Branch.getInstance().setRequestMetadataKey(key, value: value) } } - + private func logout() { DispatchQueue.main.async { Branch.getInstance().logout() } } - + private func getLatestReferringParams(result: @escaping FlutterResult) { let latestParams = Branch.getInstance().getLatestReferringParams() DispatchQueue.main.async { result(latestParams) } } - + private func getFirstReferringParams(result: @escaping FlutterResult) { let firstParams = Branch.getInstance().getFirstReferringParams() DispatchQueue.main.async { result(firstParams) } } - + private func setTrackingDisabled(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let value = args["disable"] as! Bool - + DispatchQueue.main.async { Branch.setTrackingDisabled(value) } } - - private func getLastAttributedTouchData(call: FlutterMethodCall, result: @escaping FlutterResult) { - + + private func getLastAttributedTouchData( + call: FlutterMethodCall, result: @escaping FlutterResult + ) { + let args = call.arguments as! [String: Any?] - let response : NSMutableDictionary! = [:] - let data : NSMutableDictionary! = [:] + let response: NSMutableDictionary! = [:] + let data: NSMutableDictionary! = [:] let attributionWindow = args["attributionWindow"] as? Int ?? 0 - - Branch.getInstance().lastAttributedTouchData(withAttributionWindow: attributionWindow) { latd, error in + + Branch.getInstance().lastAttributedTouchData(withAttributionWindow: attributionWindow) { + latd, error in if error == nil { if latd != nil { - data["latd"] = ["attibution_window": latd!.attributionWindow, - "last_atributed_touch_data" : latd!.lastAttributedTouchJSON] + data["latd"] = [ + "attibution_window": latd!.attributionWindow, + "last_atributed_touch_data": latd!.lastAttributedTouchJSON, + ] } else { data["latd"] = [:] } @@ -520,7 +569,8 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl response["errorMessage"] = err.localizedDescription } else { response["errorCode"] = "" - response["errorMessage"] = "errorMessage not returned by Branch SDK. See log for details." + response["errorMessage"] = + "errorMessage not returned by Branch SDK. See log for details." } } DispatchQueue.main.async { @@ -528,18 +578,18 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl } } } - + private func isUserIdentified(result: @escaping FlutterResult) { DispatchQueue.main.async { result(Branch.getInstance().isUserIdentified()) } } - + private func setTimeout(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] - let _ = args["timeout"] as? Int ?? 0 + let _ = args["timeout"] as? Int ?? 0 } - + private func setConnectTimeout(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let connectTimeout = args["connectTimeout"] as? Int ?? 0 @@ -547,12 +597,12 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl Branch.getInstance().setNetworkTimeout(TimeInterval(connectTimeout)) } } - + private func setRetryCount(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let _ = args["retryCount"] as? Int ?? 0 } - + private func setRetryInterval(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let retryInterval = args["retryInterval"] as? Int ?? 0 @@ -560,55 +610,58 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl Branch.getInstance().setRetryInterval(TimeInterval(retryInterval)) } } - + private func getQRCode(call: FlutterMethodCall, result: @escaping FlutterResult) { let args = call.arguments as! [String: Any?] let buoDict = args["buo"] as! [String: Any?] let lpDict = args["lp"] as! [String: Any?] let qrCodeDict = args["qrCodeSettings"] as! [String: Any?] - + let buo: BranchUniversalObject? = convertToBUO(dict: buoDict) - let lp : BranchLinkProperties? = convertToLp(dict: lpDict ) - let qrCode : BranchQRCode? = convertToQRCode(dict: qrCodeDict) - - let response : NSMutableDictionary! = [:] - - qrCode?.getAsData(buo, linkProperties: lp, completion: { data, error in - if (error == nil) { - response["success"] = NSNumber(value: true) - response["result"] = FlutterStandardTypedData(bytes: data!) - } else { - response["success"] = NSNumber(value: false) - if let err = (error as NSError?) { - response["errorCode"] = String(err.code) - response["errorMessage"] = err.localizedDescription + let lp: BranchLinkProperties? = convertToLp(dict: lpDict) + let qrCode: BranchQRCode? = convertToQRCode(dict: qrCodeDict) + + let response: NSMutableDictionary! = [:] + + qrCode?.getAsData( + buo, linkProperties: lp, + completion: { data, error in + if error == nil { + response["success"] = NSNumber(value: true) + response["result"] = FlutterStandardTypedData(bytes: data!) } else { - response["errorCode"] = "" - response["errorMessage"] = "errorMessage not returned by Branch SDK. See log for details." + response["success"] = NSNumber(value: false) + if let err = (error as NSError?) { + response["errorCode"] = String(err.code) + response["errorMessage"] = err.localizedDescription + } else { + response["errorCode"] = "" + response["errorMessage"] = + "errorMessage not returned by Branch SDK. See log for details." + } } - } - DispatchQueue.main.async { - result(response) - } - }) + DispatchQueue.main.async { + result(response) + } + }) } - + private func shareWithLPLinkMetadata(call: FlutterMethodCall, result: @escaping FlutterResult) { - + let args = call.arguments as! [String: Any?] let buoDict = args["buo"] as! [String: Any?] let lpDict = args["lp"] as! [String: Any?] let messageText = args["messageText"] as! String let buo: BranchUniversalObject? = convertToBUO(dict: buoDict) - let lp : BranchLinkProperties? = convertToLp(dict: lpDict ) - var iconImage : UIImage? - + let lp: BranchLinkProperties? = convertToLp(dict: lpDict) + var iconImage: UIImage? + if let iconData = args["iconData"] as? FlutterStandardTypedData { iconImage = UIImage(data: iconData.data) } else { iconImage = Bundle.main.icon } - + let bsl = BranchShareLink(universalObject: buo!, linkProperties: lp!) if #available(iOS 13.0, *) { bsl.addLPLinkMetadata(messageText, icon: iconImage) @@ -618,97 +671,99 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl showShareSheet(call: call, result: result) } } - + private func handleDeepLink(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let url = args["url"] as! String Branch.getInstance().handleDeepLink(withNewSession: URL(string: url)) } - + private func addFacebookPartnerParameter(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let key = args["key"] as! String let value = args["value"] as! String - - if (facebookParameters.keys.contains(key) && value.isEmpty) { + + if facebookParameters.keys.contains(key) && value.isEmpty { facebookParameters.removeValue(forKey: key) } else { - facebookParameters[key] = value; + facebookParameters[key] = value } - + DispatchQueue.main.async { - Branch.getInstance().addFacebookPartnerParameter(withName: key, value:value) + Branch.getInstance().addFacebookPartnerParameter(withName: key, value: value) } } - + private func addSnapPartnerParameter(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let key = args["key"] as! String let value = args["value"] as! String - - if (snapParameters.keys.contains(key) && value.isEmpty) { + + if snapParameters.keys.contains(key) && value.isEmpty { snapParameters.removeValue(forKey: key) } else { - snapParameters[key] = value; + snapParameters[key] = value } - + DispatchQueue.main.async { - Branch.getInstance().addSnapPartnerParameter(withName: key, value:value) + Branch.getInstance().addSnapPartnerParameter(withName: key, value: value) } } - + private func setPreinstallCampaign(call: FlutterMethodCall) { } - + private func setPreinstallPartner(call: FlutterMethodCall) { } - + private func setDMAParamsForEEA(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let eeaRegion = args["eeaRegion"] as! Bool - let adPersonalizationConsent = args["adPersonalizationConsent"] as! Bool + let adPersonalizationConsent = args["adPersonalizationConsent"] as! Bool let adUserDataUsageConsent = args["adUserDataUsageConsent"] as! Bool - + DispatchQueue.main.async { - Branch.setDMAParamsForEEA(eeaRegion,adPersonalizationConsent: adPersonalizationConsent, adUserDataUsageConsent: adUserDataUsageConsent) + Branch.setDMAParamsForEEA( + eeaRegion, adPersonalizationConsent: adPersonalizationConsent, + adUserDataUsageConsent: adUserDataUsageConsent) } } - + private func setConsumerProtectionAttributionLevel(call: FlutterMethodCall) { let args = call.arguments as! [String: Any?] let branchAttributionLevel = args["branchAttributionLevel"] as! String DispatchQueue.main.async { - Branch.getInstance().setConsumerProtectionAttributionLevel(BranchAttributionLevel(rawValue: branchAttributionLevel)) + Branch.getInstance().setConsumerProtectionAttributionLevel( + BranchAttributionLevel(rawValue: branchAttributionLevel)) } } - - + /* https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager - + ATTrackingManager.AuthorizationStatus: - authorized = 3 - denied = 2 - notDetermined = 0 - restricted = 1 */ - + private func requestTrackingAuthorization(result: @escaping FlutterResult) { if #available(iOS 14, *) { ATTrackingManager.requestTrackingAuthorization { (status) in Branch.getInstance().handleATTAuthorizationStatus(status.rawValue) - + DispatchQueue.main.async { result(Int(status.rawValue)) } } } else { DispatchQueue.main.async { - result(Int(4)) // return notSupported + result(Int(4)) // return notSupported } } } - + private func getTrackingAuthorizationStatus(result: @escaping FlutterResult) { if #available(iOS 14, *) { DispatchQueue.main.async { @@ -720,7 +775,7 @@ public class FlutterBranchSdkPlugin: NSObject, FlutterPlugin, FlutterStreamHandl } } } - + private func getAdvertisingIdentifier(result: @escaping FlutterResult) { if #available(iOS 14, *) { let status = ATTrackingManager.trackingAuthorizationStatus diff --git a/lib/flutter_branch_sdk.dart b/lib/flutter_branch_sdk.dart index a2ba79cb..53bd7c39 100644 --- a/lib/flutter_branch_sdk.dart +++ b/lib/flutter_branch_sdk.dart @@ -1,5 +1,8 @@ import 'dart:typed_data'; +import 'package:flutter/services.dart'; + +import 'src/constants.dart'; import 'src/flutter_branch_sdk_platform_interface.dart'; import 'src/objects/app_tracking_transparency.dart'; import 'src/objects/branch_attribution_level.dart'; diff --git a/lib/src/flutter_branch_sdk.dart b/lib/src/flutter_branch_sdk.dart index adf9dc69..262b3c94 100644 --- a/lib/src/flutter_branch_sdk.dart +++ b/lib/src/flutter_branch_sdk.dart @@ -17,12 +17,23 @@ class FlutterBranchSdk { /// **Note:** The `disableTracking` parameter is deprecated and should no longer be used. /// Please use `branchAttributionLevel` to control tracking behavior. /// - static Future init( - {bool enableLogging = false, - @Deprecated('use branchAttributionLevel') bool disableTracking = false, - BranchAttributionLevel? branchAttributionLevel}) async { + + static const messageChannel = MethodChannel(AppConstants.MESSAGE_CHANNEL); + + static Future setBranchKey(String key) async { + await messageChannel.invokeMethod('setBranchKey', {'branchKey': key}); + } + + static Future init({ + bool enableLogging = false, + @Deprecated('use branchAttributionLevel') bool disableTracking = false, + BranchAttributionLevel? branchAttributionLevel, + }) async { await FlutterBranchSdkPlatform.instance.init( - enableLogging: enableLogging, disableTracking: disableTracking, branchAttributionLevel: branchAttributionLevel); + enableLogging: enableLogging, + disableTracking: disableTracking, + branchAttributionLevel: branchAttributionLevel, + ); } ///Identifies the current user to the Branch API by supplying a unique identifier as a userId value @@ -68,24 +79,28 @@ class FlutterBranchSdk { } ///Creates a short url for the BUO - static Future getShortUrl( - {required BranchUniversalObject buo, required BranchLinkProperties linkProperties}) async { + static Future getShortUrl({ + required BranchUniversalObject buo, + required BranchLinkProperties linkProperties, + }) async { return FlutterBranchSdkPlatform.instance.getShortUrl(buo: buo, linkProperties: linkProperties); } ///Showing a Share Sheet - static Future showShareSheet( - {required BranchUniversalObject buo, - required BranchLinkProperties linkProperties, - required String messageText, - String androidMessageTitle = '', - String androidSharingTitle = ''}) async { + static Future showShareSheet({ + required BranchUniversalObject buo, + required BranchLinkProperties linkProperties, + required String messageText, + String androidMessageTitle = '', + String androidSharingTitle = '', + }) async { return FlutterBranchSdkPlatform.instance.showShareSheet( - buo: buo, - linkProperties: linkProperties, - messageText: messageText, - androidMessageTitle: androidMessageTitle, - androidSharingTitle: androidSharingTitle); + buo: buo, + linkProperties: linkProperties, + messageText: messageText, + androidMessageTitle: androidMessageTitle, + androidSharingTitle: androidSharingTitle, + ); } ///Logs this BranchEvent to Branch for tracking and analytics @@ -176,36 +191,49 @@ class FlutterBranchSdk { } ///Creates a Branch QR Code image. Returns the QR code as Uint8List. - static Future getQRCodeAsData( - {required BranchUniversalObject buo, - required BranchLinkProperties linkProperties, - required BranchQrCode qrCode}) async { - return FlutterBranchSdkPlatform.instance - .getQRCodeAsData(buo: buo, linkProperties: linkProperties, qrCodeSettings: qrCode); + static Future getQRCodeAsData({ + required BranchUniversalObject buo, + required BranchLinkProperties linkProperties, + required BranchQrCode qrCode, + }) async { + return FlutterBranchSdkPlatform.instance.getQRCodeAsData( + buo: buo, + linkProperties: linkProperties, + qrCodeSettings: qrCode, + ); } ///Creates a Branch QR Code image. Returns the QR code as a Image. - static Future getQRCodeAsImage( - {required BranchUniversalObject buo, - required BranchLinkProperties linkProperties, - required BranchQrCode qrCode}) async { - return FlutterBranchSdkPlatform.instance - .getQRCodeAsImage(buo: buo, linkProperties: linkProperties, qrCodeSettings: qrCode); + static Future getQRCodeAsImage({ + required BranchUniversalObject buo, + required BranchLinkProperties linkProperties, + required BranchQrCode qrCode, + }) async { + return FlutterBranchSdkPlatform.instance.getQRCodeAsImage( + buo: buo, + linkProperties: linkProperties, + qrCodeSettings: qrCode, + ); } ///Share with LPLinkMetadata on iOS - static void shareWithLPLinkMetadata( - {required BranchUniversalObject buo, - required BranchLinkProperties linkProperties, - required Uint8List icon, - required String title}) { + static void shareWithLPLinkMetadata({ + required BranchUniversalObject buo, + required BranchLinkProperties linkProperties, + required Uint8List icon, + required String title, + }) { Map params = {}; params['buo'] = buo.toMap(); params['lp'] = linkProperties.toMap(); params['title'] = title; - FlutterBranchSdkPlatform.instance - .shareWithLPLinkMetadata(buo: buo, linkProperties: linkProperties, icon: icon, title: title); + FlutterBranchSdkPlatform.instance.shareWithLPLinkMetadata( + buo: buo, + linkProperties: linkProperties, + icon: icon, + title: title, + ); } ///Have Branch end the current deep link session and start a new session with the provided URL. @@ -245,12 +273,16 @@ class FlutterBranchSdk { /// [eeaRegion] `true` If European regulations, including the DMA, apply to this user and conversion. /// [adPersonalizationConsent] `true` If End user has granted/denied ads personalization consent. /// [adUserDataUsageConsent] `true If User has granted/denied consent for 3P transmission of user level data for ads. - static void setDMAParamsForEEA( - {required bool eeaRegion, required bool adPersonalizationConsent, required bool adUserDataUsageConsent}) { + static void setDMAParamsForEEA({ + required bool eeaRegion, + required bool adPersonalizationConsent, + required bool adUserDataUsageConsent, + }) { FlutterBranchSdkPlatform.instance.setDMAParamsForEEA( - eeaRegion: eeaRegion, - adPersonalizationConsent: adPersonalizationConsent, - adUserDataUsageConsent: adUserDataUsageConsent); + eeaRegion: eeaRegion, + adPersonalizationConsent: adPersonalizationConsent, + adUserDataUsageConsent: adUserDataUsageConsent, + ); } /// Sets the consumer protection attribution level.