diff --git a/packages/core/android/src/main/kotlin/com/segment/analytics/AnalyticsPlugin.kt b/packages/core/android/src/main/kotlin/com/segment/analytics/AnalyticsPlugin.kt index 6f4a3fd..ef8d597 100644 --- a/packages/core/android/src/main/kotlin/com/segment/analytics/AnalyticsPlugin.kt +++ b/packages/core/android/src/main/kotlin/com/segment/analytics/AnalyticsPlugin.kt @@ -31,10 +31,10 @@ import java.util.* val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L) /** AnalyticsPlugin */ -class AnalyticsPlugin : FlutterPlugin, NativeContextApi, EventChannel.StreamHandler, ActivityAware, +class AnalyticsPlugin : FlutterPlugin, NativeContextApi, EventChannel.StreamHandler, ActivityAware, PluginRegistry.NewIntentListener { private var context: Context? = null - + private val pendingDeeplinkEventsQueue: Queue = LinkedList() private fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) } private val eventsChannel = "analytics/deep_link_events" @@ -182,13 +182,13 @@ class AnalyticsPlugin : FlutterPlugin, NativeContextApi, EventChannel.StreamHand private fun createChangeReceiver(events: EventSink): BroadcastReceiver { return object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent) { - val referringApplication = intent.getStringExtra("referringApplication") + val referringApplication = intent.getStringExtra("referring_application") // NOTE: assuming intent.getAction() is Intent.ACTION_VIEW val dataString: String? = intent.dataString if (dataString == null) { events.error("UNAVAILABLE", "Link unavailable", null) } else { - val data = mapOf("url" to dataString, "referringApplication" to referringApplication) + val data = mapOf("url" to dataString, "referring_application" to referringApplication) events.success(data) } } @@ -198,13 +198,30 @@ class AnalyticsPlugin : FlutterPlugin, NativeContextApi, EventChannel.StreamHand private fun handleIntent(context: Context, intent: Intent) { val action = intent.action if (Intent.ACTION_VIEW == action) { - if (changeReceiver != null) changeReceiver!!.onReceive(context, intent) + if (changeReceiver != null) { + changeReceiver!!.onReceive(context, intent) + } else { + pendingDeeplinkEventsQueue.add(intent.cloneFilter()) + } + } + } + + private fun processPendingDeeplinkEventsQueue() { + if (this.context == null || + changeReceiver == null + ) { + return + } + while (pendingDeeplinkEventsQueue.isNotEmpty()) { + val intent = pendingDeeplinkEventsQueue.poll() + changeReceiver!!.onReceive(context, intent) } } override fun onListen(arguments: Any?, events: EventSink?) { if (events != null) { this.changeReceiver = createChangeReceiver(events) + processPendingDeeplinkEventsQueue() } } @@ -216,7 +233,10 @@ class AnalyticsPlugin : FlutterPlugin, NativeContextApi, EventChannel.StreamHand binding.addOnNewIntentListener(this) if (this.context != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { - binding.activity.intent.putExtra("referringApplication", binding.activity.referrer.toString()) + binding.activity.intent.putExtra( + "referring_application", + binding.activity.referrer.toString() + ) } this.handleIntent(this.context!!, binding.activity.intent) } diff --git a/packages/core/ios/Classes/AnalyticsPlugin.swift b/packages/core/ios/Classes/AnalyticsPlugin.swift index db5cdd7..0dde117 100644 --- a/packages/core/ios/Classes/AnalyticsPlugin.swift +++ b/packages/core/ios/Classes/AnalyticsPlugin.swift @@ -3,8 +3,10 @@ import UIKit import Foundation public class AnalyticsPlugin: NSObject, FlutterPlugin, NativeContextApi, FlutterStreamHandler, FlutterApplicationLifeCycleDelegate { + private var pendingDeeplinkEventsQueue:[[String:String?]] = [] public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { _eventSink = events + processPendingDeeplinkEventsQueue(); return nil } @@ -14,19 +16,27 @@ public class AnalyticsPlugin: NSObject, FlutterPlugin, NativeContextApi, Flutter } var _eventSink:FlutterEventSink?; - public func application(_ application: UIApplication, open url: URL, sourceApplication: String, annotation: Any) -> Bool { + public func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool{ + let sourceApplication = options[.sourceApplication] as? String; if (_eventSink != nil) { - _eventSink?(["url": url.absoluteString, "referringApplication": sourceApplication]) + _eventSink?(["url": url.absoluteString, "referring_application": sourceApplication]) + }else{ + pendingDeeplinkEventsQueue.append(["url": url.absoluteString, "referring_application": sourceApplication]); } - return true + + + return false } - public func application(_ application: UIApplication, handleOpen url: URL) -> Bool { - if (_eventSink != nil) { - _eventSink?([url: url.absoluteString]) + + private func processPendingDeeplinkEventsQueue() -> Void{ + if(_eventSink == nil){ + return; + } + while(!pendingDeeplinkEventsQueue.isEmpty){ + let eventData:[String:String?] = pendingDeeplinkEventsQueue.removeFirst(); + _eventSink?(eventData); } - return true } - internal static var device = VendorSystem.current func getContext(collectDeviceId: Bool, completion: @escaping (Result) -> Void) { @@ -88,10 +98,12 @@ public class AnalyticsPlugin: NSObject, FlutterPlugin, NativeContextApi, Flutter public static func register(with registrar: FlutterPluginRegistrar) { let messenger : FlutterBinaryMessenger = registrar.messenger() - let api : NativeContextApi & NSObjectProtocol & AnalyticsPlugin = AnalyticsPlugin.init() + let plugin = AnalyticsPlugin.init(); + let api : NativeContextApi & NSObjectProtocol & AnalyticsPlugin = plugin NativeContextApiSetup.setUp(binaryMessenger: messenger, api: api) let channel:FlutterEventChannel = FlutterEventChannel(name: "analytics/deep_link_events", binaryMessenger: registrar.messenger()) channel.setStreamHandler(api) + registrar.addApplicationDelegate(plugin) } } diff --git a/packages/core/lib/state.dart b/packages/core/lib/state.dart index 1b3698b..eaec773 100644 --- a/packages/core/lib/state.dart +++ b/packages/core/lib/state.dart @@ -360,7 +360,7 @@ class DeepLinkDataState extends PersistedState { @JsonSerializable(explicitToJson: true, includeIfNull: false) class DeepLinkData { - final String referringApplication; + final String? referringApplication; final String url; DeepLinkData(this.referringApplication, this.url); diff --git a/packages/core/lib/state.g.dart b/packages/core/lib/state.g.dart index 1996a68..0eb2f14 100644 --- a/packages/core/lib/state.g.dart +++ b/packages/core/lib/state.g.dart @@ -35,15 +35,23 @@ Map _$UserInfoToJson(UserInfo instance) { } DeepLinkData _$DeepLinkDataFromJson(Map json) => DeepLinkData( - json['referringApplication'] as String, + json['referring_application'] as String?, json['url'] as String, ); -Map _$DeepLinkDataToJson(DeepLinkData instance) => - { - 'referringApplication': instance.referringApplication, - 'url': instance.url, - }; +Map _$DeepLinkDataToJson(DeepLinkData instance) { + final val = {}; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull('referring_application', instance.referringApplication); + val['url'] = instance.url; + return val; +} SegmentAPISettings _$SegmentAPISettingsFromJson(Map json) => SegmentAPISettings(