Skip to content

Commit

Permalink
Merge pull request #29 from plaidev/android-1
Browse files Browse the repository at this point in the history
[flutter] support global event handler, and update dependencies
  • Loading branch information
RyosukeCla authored Mar 28, 2024
2 parents 5fc68fd + 56d85b2 commit 9199b7b
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 90 deletions.
2 changes: 1 addition & 1 deletion flutter/nativebrik_bridge/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ android {
}

dependencies {
implementation 'com.nativebrik:sdk:0.1.0'
implementation 'com.nativebrik:sdk:0.1.1'
implementation 'androidx.activity:activity-compose:1.8.2'
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation 'org.mockito:mockito-core:5.0.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,57 +49,84 @@ class NativebrikBridgePlugin: FlutterPlugin, MethodCallHandler {

@OptIn(DelicateCoroutinesApi::class)
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getNativebrikSDKVersion") {
result.success(VERSION)
} else if (call.method == "connectClient") {
val projectId = call.arguments as String
if (projectId.isEmpty()) {
result.success("ok")
return
}
val client = NativebrikClient(Config(projectId), context)
this.manager.setNativebrikClient(client)
result.success("ok")
} else if (call.method == "connectEmbedding") {
val channelId = call.argument<String>("channelId") as String
val id = call.argument<String>("id") as String
this.manager.connectEmbedding(channelId, id)
result.success("ok")
} else if (call.method == "disconnectEmbedding") {
val channelId = call.arguments as String
this.manager.disconnectEmbedding(channelId)
result.success("ok")
} else if (call.method == "connectRemoteConfig") {
val channelId = call.argument<String>("channelId") as String
val id = call.argument<String>("id") as String
GlobalScope.launch(Dispatchers.IO) {
manager.connectRemoteConfig(channelId, id).onSuccess {
result.success(it)
}.onFailure {
result.success("failed")
when (call.method) {
"getNativebrikSDKVersion" -> {
result.success(VERSION)
}
"connectClient" -> {
val projectId = call.arguments as String
if (projectId.isEmpty()) {
result.success("no")
return
}
}
} else if (call.method == "disconnectRemoteConfig") {
val channelId = call.arguments as String
this.manager.disconnectRemoteConfig(channelId)
result.success("ok")
} else if (call.method == "getRemoteConfigValue") {
val channelId = call.argument<String>("channelId") as String
val key = call.argument<String>("key") as String
val value = this.manager.getRemoteConfigValue(channelId, key)
result.success(value)
} else if (call.method == "connectEmbeddingInRemoteConfigValue") {
val channelId = call.argument<String>("channelId") as String
val embeddingChannelId = call.argument<String>("embeddingChannelId") as String
val key = call.argument<String>("key") as String
this.manager.connectEmbeddingInRemoteConfigValue(channelId, key, embeddingChannelId)
result.success("ok")
} else if (call.method == "dispatch") {
val event = call.arguments as String
this.manager.dispatch(event)
result.success("ok")
} else {
result.notImplemented()
val client = NativebrikClient(
Config(
projectId,
onEvent = { it ->
this.channel.invokeMethod(ON_EVENT_METHOD, mapOf(
"name" to it.name,
"deepLink" to it.deepLink,
"payload" to it.payload?.map { prop ->
mapOf(
"name" to prop.name,
"value" to prop.value,
"type" to prop.type,
)
}
))
}
), context)
this.manager.setNativebrikClient(client)
result.success("ok")
}
"connectEmbedding" -> {
val channelId = call.argument<String>("channelId") as String
val id = call.argument<String>("id") as String
this.manager.connectEmbedding(channelId, id)
result.success("ok")
}
"disconnectEmbedding" -> {
val channelId = call.arguments as String
this.manager.disconnectEmbedding(channelId)
result.success("ok")
}
"connectRemoteConfig" -> {
val channelId = call.argument<String>("channelId") as String
val id = call.argument<String>("id") as String
GlobalScope.launch(Dispatchers.IO) {
manager.connectRemoteConfig(channelId, id).onSuccess {
result.success(it)
}.onFailure {
result.success("failed")
}
}
}
"disconnectRemoteConfig" -> {
val channelId = call.arguments as String
this.manager.disconnectRemoteConfig(channelId)
result.success("ok")
}
"getRemoteConfigValue" -> {
val channelId = call.argument<String>("channelId") as String
val key = call.argument<String>("key") as String
val value = this.manager.getRemoteConfigValue(channelId, key)
result.success(value)
}
"connectEmbeddingInRemoteConfigValue" -> {
val channelId = call.argument<String>("channelId") as String
val embeddingChannelId = call.argument<String>("embeddingChannelId") as String
val key = call.argument<String>("key") as String
this.manager.connectEmbeddingInRemoteConfigValue(channelId, key, embeddingChannelId)
result.success("ok")
}
"dispatch" -> {
val event = call.arguments as String
this.manager.dispatch(event)
result.success("ok")
}
else -> {
result.notImplemented()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import kotlin.test.Test
import org.mockito.Mockito
import com.nativebrik.sdk.VERSION

/*
* This demonstrates a simple unit test of the Kotlin portion of this plugin's implementation.
Expand All @@ -15,13 +16,13 @@ import org.mockito.Mockito

internal class NativebrikBridgePluginTest {
@Test
fun onMethodCall_getPlatformVersion_returnsExpectedValue() {
fun onMethodCall_getNativebrikSDKVersion_returnsExpectedValue() {
val plugin = NativebrikBridgePlugin()

val call = MethodCall("getPlatformVersion", null)
val call = MethodCall("getNativebrikSDKVersion", null)
val mockResult: MethodChannel.Result = Mockito.mock(MethodChannel.Result::class.java)
plugin.onMethodCall(call, mockResult)

Mockito.verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE)
Mockito.verify(mockResult).success(VERSION)
}
}
8 changes: 4 additions & 4 deletions flutter/nativebrik_bridge/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ PODS:
- Flutter (1.0.0)
- integration_test (0.0.1):
- Flutter
- Nativebrik (0.5.0):
- Nativebrik (0.5.5):
- YogaKit (~> 2.0.0)
- nativebrik_bridge (0.0.1):
- Flutter
- Nativebrik (~> 0.5.0)
- Nativebrik (~> 0.5.5)
- Yoga (2.0.1)
- YogaKit (2.0.1):
- Yoga (~> 2.0.1)
Expand All @@ -33,8 +33,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
integration_test: 13825b8a9334a850581300559b8839134b124670
Nativebrik: cce9625971439ed9b63b649c60b0d11f3e525e75
nativebrik_bridge: 6256bcf5bdd5ad5d5e4069f45b3d9f444275e244
Nativebrik: 6d51f3f905e5535b5638e1d77dbf44f60b9dd411
nativebrik_bridge: 5d36b3d759d3170aa00841f2e0514d169d064a9c
Yoga: 7ac7f65e2d7120bf97e75fd66436ed4c7bf8e37e
YogaKit: 4751ba673fab49df29e2235e23c4ea7d6d5a339c

Expand Down
6 changes: 5 additions & 1 deletion flutter/nativebrik_bridge/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ class _MyAppState extends State<MyApp> {
// setState to update our non-existent appearance.
if (!mounted) return;

nativebrik.addEventListener((event) {
print("Nativebrik Global Embedding Event: $event");
});

var config = NativebrikRemoteConfig("cnoku4223akg00e5m630");
var variant = await config.fetch();
var message = await variant.get("message");
Expand All @@ -55,7 +59,7 @@ class _MyAppState extends State<MyApp> {
children: [
NativebrikEmbedding("TOP_COMPONENT", height: 270,
onEvent: (event) {
print("Nativebrik Event: ${event.payload}");
print("Nativebrik Embedding Event: ${event.payload}");
}),
const Text("Text 2"),
Text(_message),
Expand Down
20 changes: 17 additions & 3 deletions flutter/nativebrik_bridge/ios/Classes/NativebrikBridgePlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ let ON_EVENT_METHOD = "on-event"
public class NativebrikBridgePlugin: NSObject, FlutterPlugin {
private let manager: NativebrikBridgeManager
private let messenger: FlutterBinaryMessenger
init(messenger: FlutterBinaryMessenger, manager: NativebrikBridgeManager) {
private let channel: FlutterMethodChannel
init(messenger: FlutterBinaryMessenger, manager: NativebrikBridgeManager, channel: FlutterMethodChannel) {
self.messenger = messenger
self.manager = manager
self.channel = channel
super.init()
}
public static func register(with registrar: FlutterPluginRegistrar) {
let manager = NativebrikBridgeManager()
let messenger = registrar.messenger()
let channel = FlutterMethodChannel(name: "nativebrik_bridge", binaryMessenger: messenger)
let instance = NativebrikBridgePlugin(messenger: messenger, manager: manager)
let instance = NativebrikBridgePlugin(messenger: messenger, manager: manager, channel: channel)
registrar.addMethodCallDelegate(instance, channel: channel)
registrar.register(
FLNativeViewFactory(messenger: messenger, manager: manager),
Expand All @@ -32,7 +34,19 @@ public class NativebrikBridgePlugin: NSObject, FlutterPlugin {
result(nativebrikSdkVersion)
case "connectClient":
let projectId = call.arguments as! String
self.manager.setNativebrikClient(nativebrik: NativebrikClient(projectId: projectId))
self.manager.setNativebrikClient(nativebrik: NativebrikClient(projectId: projectId, onEvent: { [weak self] event in
self?.channel.invokeMethod(ON_EVENT_METHOD, arguments: [
"name": event.name as Any?,
"deepLink": event.deepLink as Any?,
"payload": event.payload?.map({ prop in
return [
"name": prop.name,
"value": prop.value,
"type": prop.type
]
}),
])
}))
result("ok")

// embedding
Expand Down
2 changes: 1 addition & 1 deletion flutter/nativebrik_bridge/ios/nativebrik_bridge.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ A new Flutter plugin project.
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.dependency 'Nativebrik', '~> 0.5.0'
s.dependency 'Nativebrik', '~> 0.5.5'
s.ios.deployment_target = '14.0'
s.platform = :ios, '14.0'

Expand Down
28 changes: 2 additions & 26 deletions flutter/nativebrik_bridge/lib/embedding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:nativebrik_bridge/remote_config.dart';
import 'package:nativebrik_bridge/utils/random.dart';
import 'package:nativebrik_bridge/utils/parse_event.dart';
import './channel/nativebrik_bridge_platform_interface.dart';

enum EventPayloadType { integer, string, timestamp, unknown }
Expand Down Expand Up @@ -122,7 +123,7 @@ class _EmbeddingState extends State<NativebrikEmbedding> {
return Future.value(true);
case 'on-event':
if (widget.onEvent == null) return Future.value(false);
widget.onEvent?.call(_parseEvent(call.arguments));
widget.onEvent?.call(parseEvent(call.arguments));
return Future.value(true);
default:
return Future.value(false);
Expand Down Expand Up @@ -196,28 +197,3 @@ class _BridgeView extends StatelessWidget {
}
}
}

EventPayloadType _parseEventPayloadType(dynamic type) {
switch (type) {
case "INTEGER":
return EventPayloadType.integer;
case "STRING":
return EventPayloadType.string;
case "TIMESTAMPZ":
return EventPayloadType.timestamp;
default:
return EventPayloadType.unknown;
}
}

Event _parseEvent(dynamic arguments) {
final map = arguments;
final name = map["name"] as String?;
final deepLink = map["deepLink"] as String?;
final rawPayload = map["payload"] as List<dynamic>? ?? [];
final payload = rawPayload
.map((e) => EventPayload(e["name"] as String? ?? "",
e["value"] as String? ?? "", _parseEventPayloadType(e["type"])))
.toList();
return Event(name, deepLink, payload);
}
27 changes: 27 additions & 0 deletions flutter/nativebrik_bridge/lib/nativebrik_bridge.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'package:flutter/services.dart';
import 'package:nativebrik_bridge/embedding.dart';
import 'package:nativebrik_bridge/utils/parse_event.dart';
import 'channel/nativebrik_bridge_platform_interface.dart';

/// A bridge client to the nativebrik SDK.
Expand All @@ -11,12 +14,36 @@ import 'channel/nativebrik_bridge_platform_interface.dart';
/// ```
class NativebrikBridge {
final String projectId;
final List<EventHandler> _listeners = [];
final MethodChannel _channel = const MethodChannel("nativebrik_bridge");

NativebrikBridge(this.projectId) {
NativebrikBridgePlatform.instance.connectClient(projectId);
_channel.setMethodCallHandler(_handleMethod);
}

Future<String?> getNativebrikSDKVersion() {
return NativebrikBridgePlatform.instance.getNativebrikSDKVersion();
}

addEventListener(EventHandler listener) {
_listeners.add(listener);
}

removeEventListener(EventHandler listener) {
_listeners.remove(listener);
}

Future<dynamic> _handleMethod(MethodCall call) async {
switch (call.method) {
case 'on-event':
final event = parseEvent(call.arguments);
for (var listener in _listeners) {
listener(event);
}
return Future.value(true);
default:
return Future.value(true);
}
}
}
26 changes: 26 additions & 0 deletions flutter/nativebrik_bridge/lib/utils/parse_event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:nativebrik_bridge/embedding.dart';

EventPayloadType _parseEventPayloadType(dynamic type) {
switch (type) {
case "INTEGER":
return EventPayloadType.integer;
case "STRING":
return EventPayloadType.string;
case "TIMESTAMPZ":
return EventPayloadType.timestamp;
default:
return EventPayloadType.unknown;
}
}

Event parseEvent(dynamic arguments) {
final map = arguments;
final name = map["name"] as String?;
final deepLink = map["deepLink"] as String?;
final rawPayload = map["payload"] as List<dynamic>? ?? [];
final payload = rawPayload
.map((e) => EventPayload(e["name"] as String? ?? "",
e["value"] as String? ?? "", _parseEventPayloadType(e["type"])))
.toList();
return Event(name, deepLink, payload);
}
2 changes: 1 addition & 1 deletion flutter/nativebrik_bridge/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: nativebrik_bridge
description: "Nativebrik bridge sdk for flutter"
version: 0.1.0
version: 0.2.0
homepage: "https://nativebrik.com"
repository: "https://github.com/plaidev/nativebrik-sdk"

Expand Down

0 comments on commit 9199b7b

Please sign in to comment.