Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added SDK config #1

Merged
merged 5 commits into from
Nov 24, 2022
Merged

feat: added SDK config #1

merged 5 commits into from
Nov 24, 2022

Conversation

Shahroz16
Copy link
Collaborator

@Shahroz16 Shahroz16 self-assigned this Nov 15, 2022
}

private func initialize(params : Dictionary<String, Any>){
guard let siteId = params[Keys.Environment.siteId] as? String,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we expect organisation id in these parameters?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we will have it in next PRs

private func setUserAgentClient(params : Dictionary<String, Any>){
let version = params[Keys.PackageConfig.version] as? String ?? "n/a"
let sdkSource = SdkWrapperConfig.Source.flutter
CustomerIO.config {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set SDK configuration during initialisation only.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure will do

}

private func setupConfig(params : Dictionary<String, Any>){
CustomerIO.config {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set SDK configuration during initialisation and all attributes can be set in one go !

class CustomerIOConfig {
final String siteId;
final String apiKey;
Region region;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Region is also optional with a default value. I could be mistaken as this is dart and setting a default value could be done in a different way.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup its optional, late in this file constructor is available which shows required attributes

 CustomerIOConfig(
      {required this.siteId,
      required this.apiKey,
      this.region = Region.us,
      this.organizationId,
      this.logLevel = CioLogLevel.debug,
      this.autoTrackDeviceAttributes = true,
      this.trackingApiUrl = "",
      this.autoTrackPushEvents = true,
      this.backgroundQueueMinNumberOfTasks = 10,
      this.backgroundQueueSecondsDelay = 30.0,
      this.version = ""});

// customer_io
//
// Created by ShahrozAli on 11/11/22.
//

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be ignored right now, but we would need to remove the headers across all files before final release.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Swift format and swift lint tools that we use on iOS SDK do this for us.

We can configure git hooks like the Android SDK in this project that run the linter/formatter against this code?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup will move on to lint/hooks/ci/cd after the basic implementation is done. Since i am the only one working, i dont get any conflicts as such either.

result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else {
result.notImplemented()
class CustomerIoPlugin : FlutterPlugin, MethodCallHandler {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class CustomerIoPlugin : FlutterPlugin, MethodCallHandler {
class CustomerIOPlugin : FlutterPlugin, MethodCallHandler {

Usually when referring to CIO, we use CustomerIO instead of CustomerIo.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since our team is not knowledgable with flutter, classes like this could benefit from more comment explaining what a Flutter plugin is?

Comment on lines +20 to +23
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great comment! I appreciate that since our team doesn't know Flutter.

///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel: MethodChannel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private lateinit var channel: MethodChannel
private lateinit var flutterCommunicationChannel: MethodChannel

I like the idea of having a more descriptive variable name so it's easy to understand that MethodChannel is specific to flutter and it's purpose.


override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
context = flutterPluginBinding.applicationContext
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "customer_io")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of "customer_io"? Is this string meant to be unique for the host Flutter app?

If so, should we use package name? io.customer.sdk.flutter?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its the channel name, we can have multiple channels to communicate with the native platform and flutter, also the convention in dart is to use "_" rather than "."

Comment on lines +38 to +40
"getPlatformVersion" -> {
result.success("Android-${android.os.Build.VERSION.RELEASE}")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function just for your own testing or is this something we need to implement for a flutter plugin?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just for internal testing, will remove it afterwards.

@@ -15,7 +15,8 @@ A plugin for Customer.io
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.platform = :ios, '9.0'
s.dependency 'CustomerIO/Tracking'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file used for the example Flutter iOS app? Or is this the file used for us to push the flutter SDK to cocoapods so our flutter customers can use it in their app?

If it's the cocoapods file that we use for publishing, I would like to make some changes to the file to match the naming style of our iOS SDK so the SDK is easier to find.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is used by iOS internally only, it fetches CustomerIO native SDK for us that we make native bindings with, but i'll dig down more once i start looking into publishing the flutter plugins.

import 'customer_io_platform_interface.dart';

class CustomerIo {
Future<String?> getPlatformVersion() {
return CustomerIoPlatform.instance.getPlatformVersion();
const CustomerIo._();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 What is this for? Curious....

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how you make singleton classes in dart

return _customerIO.getPlatformVersion();
}

static Future<void> initialize({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this must be why the other Dart file said await CustomerIO.initialize().

Does this function have to be a Future since the native SDK initialize() function isn't async?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't have to be Future but it's a common practice in plugin development that I have noticed, they return back with success/failures.

I believe it's for the sake of state management as if they want to perform all initializations first and then move on to the other screens, native platforms provide it themselves, but maybe Cross platform doesn't

Comment on lines +5 to +6
final String siteId;
final String apiKey;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move these 2 properties out of the config object and into parameters of Dart's CustomerIO.initialize() function? To match the native SDKs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can but then we will have to make another map that combines these values along with the other config, cause we can only pass 1 map from Flutter/React to native bindings.

Thats why we keep it in one class in both wrappers (RN/Flutter)

import 'customer_io_enums.dart';

/// Configure plugin using CustomerIOConfig
class CustomerIOConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, bummer. Looks like we might need to keep a Dart equivalent to the native SDK CustomerIOConfig maintained?

Sounds like a lot of work that every time that we add a value to the Android or iOS SDK config object, we need to update it across RN SDK and Flutter SDK. But, I am not sure if there is a way around this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that's the only way, we have to keep these wrapper updated with native SDK

Comment on lines +91 to +104
val logLevel = config.getProperty<String>(Keys.Config.LOG_LEVEL).toCIOLogLevel()
setLogLevel(level = logLevel)
config.getProperty<String>(Keys.Config.TRACKING_API_URL)?.takeIfNotBlank()?.let { value ->
setTrackingApiURL(value)
}
config.getProperty<Boolean>(Keys.Config.AUTO_TRACK_DEVICE_ATTRIBUTES)?.let { value ->
autoTrackDeviceAttributes(shouldTrackDeviceAttributes = value)
}
config.getProperty<Double>(Keys.Config.BACKGROUND_QUEUE_MIN_NUMBER_OF_TASKS)?.let { value ->
setBackgroundQueueMinNumberOfTasks(backgroundQueueMinNumberOfTasks = value.toInt())
}
config.getProperty<Double>(Keys.Config.BACKGROUND_QUEUE_SECONDS_DELAY)?.let { value ->
setBackgroundQueueSecondsDelay(backgroundQueueSecondsDelay = value)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can support initialization through maps in Native SDKs to help in this for both React Native and Flutter. But we need to be careful and not rename any key used by these wrappers or change its type to avoid breaking this.

Copy link

@matt-frizzell matt-frizzell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good enough to push through on

Copy link
Contributor

@mrehan27 mrehan27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍🏻

@Shahroz16 Shahroz16 merged commit e8ed7dd into main Nov 24, 2022
ami-ci pushed a commit that referenced this pull request Dec 22, 2022
## 1.0.0-alpha.1 (2022-12-22)

### Features

* added SDK config  ([#1](#1)) ([e8ed7dd](e8ed7dd))
* tracking and in-app added ([#2](#2)) ([c23f2d9](c23f2d9))

### Bug Fixes

* typo fixed ([#9](#9)) ([a5107df](a5107df)), closes [#7](#7) [#8](#8)
@ami-ci
Copy link

ami-ci commented Dec 22, 2022

🎉 This PR is included in version 1.0.0-alpha.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

ami-ci pushed a commit that referenced this pull request Dec 22, 2022
## 1.0.0-alpha.1 (2022-12-22)

### Features

* added SDK config  ([#1](#1)) ([e8ed7dd](e8ed7dd))
* tracking and in-app added ([#2](#2)) ([c23f2d9](c23f2d9))

### Bug Fixes

* typo fixed ([#9](#9)) ([a5107df](a5107df)), closes [#7](#7) [#8](#8)
@ami-ci
Copy link

ami-ci commented Dec 22, 2022

🎉 This PR is included in version 1.0.0-alpha.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

ami-ci pushed a commit that referenced this pull request Mar 7, 2023
## 1.0.0-beta.1 (2023-03-07)

### Features

* added missing methods ([#17](#17)) ([73f29e6](73f29e6))
* added SDK config  ([#1](#1)) ([e8ed7dd](e8ed7dd))
* tracking and in-app added ([#2](#2)) ([c23f2d9](c23f2d9))

### Bug Fixes

* formatting issues ([d67fa7e](d67fa7e))
* in-app remove gist org id ([#19](#19)) ([ce4cc9e](ce4cc9e))
* missing methods and extra dependency ([2c5deca](2c5deca))
* obj-c bindings issue ([0dbe4ef](0dbe4ef))
* plugin version in user-agent ([a10e482](a10e482))
* typo fixed ([#9](#9)) ([a5107df](a5107df)), closes [#7](#7) [#8](#8)
* updated android dependency to auto update ([#24](#24)) ([040cef2](040cef2))
* updated icon and typo ([57c6eef](57c6eef))
@ami-ci
Copy link

ami-ci commented Mar 7, 2023

🎉 This PR is included in version 1.0.0-beta.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

ami-ci pushed a commit that referenced this pull request Apr 3, 2023
## 1.0.0 (2023-04-03)

### Features

* added missing methods ([#17](#17)) ([73f29e6](73f29e6))
* added SDK config  ([#1](#1)) ([e8ed7dd](e8ed7dd))
* tracking and in-app added ([#2](#2)) ([c23f2d9](c23f2d9))

### Bug Fixes

* add test coverage and refactored scripts ([#34](#34)) ([f7f2387](f7f2387))
* formatting issues ([d67fa7e](d67fa7e))
* in-app remove gist org id ([#19](#19)) ([ce4cc9e](ce4cc9e))
* missing methods and extra dependency ([2c5deca](2c5deca))
* obj-c bindings issue ([0dbe4ef](0dbe4ef))
* plugin version in user-agent ([a10e482](a10e482))
* release script typo ([2a8b7ae](2a8b7ae))
* typo fixed ([#9](#9)) ([a5107df](a5107df)), closes [#7](#7) [#8](#8)
* updated android dependency to auto update ([#24](#24)) ([040cef2](040cef2))
* updated icon and typo ([57c6eef](57c6eef))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants