-
Notifications
You must be signed in to change notification settings - Fork 11
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 missing methods #17
Conversation
- register device - metric tracking
Pull request title looks good 👍! If this pull request gets merged, it will cause a new release of the software. Example: If this project's latest release version is All merged pull requests will eventually get deployed. But some types of pull requests will trigger a deployment (such as features and bug fixes) while some pull requests will wait to get deployed until a later time. To merge this pull request, add the label This project uses a special format for pull requests titles. Expand this section to learn more (expand by clicking the ᐅ symbol on the left side of this sentence)...This project uses a special format for pull requests titles. Don't worry, it's easy! This pull request title should be in this format:
If your pull request introduces breaking changes to the code, use this format:
where
Examples:
Need more examples? Want to learn more about this format? Check out the official docs. Note: If your pull request does multiple things such as adding a feature and makes changes to the CI server and fixes some bugs then you might want to consider splitting this pull request up into multiple smaller pull requests. |
… shahroz/shared-wrapper-code
Changes the Slack channel for deployment messages to the new mobile-deployments channel See customerio/issues#9014
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few small queries, rest looks good 👍🏻
return | ||
} | ||
|
||
CustomerIO.shared.registerDeviceToken(token) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ain't an iOS expert 😅 But doesn't if statement looks better here? e.g.
if let token = params[Keys.Tracking.token] as? String {
CustomerIO.shared.registerDeviceToken(token)
}
Mainly because I think the method is too small for early returns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha! I don't have any preference but I saw this being followed in RN iOS, so kept the same format. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer guard statements. Even beyond iOS development, the guard
design pattern I find quite nice 😄. I have made suggestions in our RN SDK code reviews in the past to use the guard design pattern.
IMO, since this function is short, either solution proposed would do. When a function gets long and more complex, I think guard statements show their value more.
But even in short functions, I like to use guards.
|
||
CustomerIO.shared.trackMetric(deliveryID: deliveryId, | ||
event: event, | ||
deviceToken: deviceToken) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above comment
@@ -38,13 +40,13 @@ class CustomerIoPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { | |||
/// when the Flutter Engine is detached from the Activity | |||
private lateinit var flutterCommunicationChannel: MethodChannel | |||
private lateinit var context: Context | |||
private var activity: Activity? = null | |||
private var activity: WeakReference<Activity>? = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private var activity: WeakReference<Activity>? = null | |
private var activity: WeakReference<Activity> = WeakReference() |
This feels overly complicated to me to have a WeakReference
object that can be null since the object it keeps reference to can also be null.
Instead, I suggest making WeakReference
never null and modify it when we want to make the Activity
null.
So, we would also modify:
override fun onDetachedFromActivity() {
this.activity.clear()
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Levi, that was my first attempt too. We can't use WeakReference()
but will have to use WeakReference(Activity())
I was unsure about this, so I searched more and the conclusion was It's better to initialize the WeakReference
with null
initially, rather than with a new Activity
object. This is because the new Activity object will immediately become eligible for garbage collection, since it has no strong references to it, which could potentially lead to unexpected behavior.
By initializing the WeakReference with null, you ensure that the WeakReference does not hold a reference to an object that could be immediately eligible for garbage collection. When the plugin is attached to the host activity, you can then update the WeakReference to hold a reference to the host activity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see.
From the javadoc, it does appear that the constructor does not allow a null
value.
Bummer, but this solution is OK.
lib/customer_io_method_channel.dart
Outdated
if (kDebugMode) { | ||
print(exception); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this logic something we should pull out into a Util method? To avoid copy/pasting it in many places in the code?
Have a method that contains the default logic behind how we handle caught exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point, I'll create a method in the same class.
lib/customer_io_method_channel.dart
Outdated
if (kDebugMode) { | ||
print(exception); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See other comment in this file.
test/customer_io_test.dart
Outdated
@override | ||
void registerDeviceToken({required String deviceToken}) { | ||
// TODO: implement registerDeviceToken | ||
} | ||
|
||
@override | ||
void trackMetric({required String deliveryID, required String deviceToken, required MetricEvent event}) { | ||
// TODO: implement trackMetric | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for asking a question about a file that's already been in the code base for a while. But I want to ask, what is this file used for? Could we add a comment to this file explaining the reason behind having it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comment for it.
return | ||
} | ||
|
||
CustomerIO.shared.registerDeviceToken(token) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer guard statements. Even beyond iOS development, the guard
design pattern I find quite nice 😄. I have made suggestions in our RN SDK code reviews in the past to use the guard design pattern.
IMO, since this function is short, either solution proposed would do. When a function gets long and more complex, I think guard statements show their value more.
But even in short functions, I like to use guards.
@@ -142,9 +154,28 @@ class CustomerIoPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { | |||
} | |||
} | |||
|
|||
private fun registerDeviceToken(params: Map<String, Any>) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious, why this params
a Map
? I was expecting to see a String
param?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly for consistency, Since other methods are sending Map
we have now a utility method that verifies the map and its keys.
Also, if we ever wanted to send more params along with token
we won't have to change the signature of the method or implementation but rather just add another pair
to the map.
But I agree that this looks like overkill and I might deviate away from this as well if we get 1 more method that just takes 1 string
parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand how it would be convenient that if we ever added another parameter besides token
, the signature would not need modified.
I would agree with you that this does feel like overkill because (1) this method is private so modifying the parameters would not introduce breaking changes to the code base and (2) if you never add a new parameter besides token
, this solution feels boilerplate and overkill.
I also prefer not using Map
as you lose compiler checks. Instead of a strongly typed parameter of type String
, the compiler wouldn't as easily find potential bugs with Map<String, Any>
.
android/src/main/kotlin/io/customer/customer_io/CustomerIoPlugin.kt
Outdated
Show resolved
Hide resolved
private fun setDeviceAttributes(params: Map<String, Any>) { | ||
val attributes = | ||
params.getProperty<Map<String, Any>>(Keys.Tracking.ATTRIBUTES) ?: emptyMap() | ||
val attributes = params.getProperty<Map<String, Any>>(Keys.Tracking.ATTRIBUTES) ?: return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's relevant to this PR, I wanted to put a comment here.
This is an example of using the guard design pattern in Kotlin 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good besides 1 new PR conversation I started in lib/customer_io_method_channel.dart
file.
lib/customer_io_method_channel.dart
Outdated
@@ -91,11 +89,10 @@ class CustomerIOMethodChannel extends CustomerIOPlatform { | |||
TrackingConsts.identifier: identifier, | |||
TrackingConsts.attributes: attributes | |||
}; | |||
methodChannel.invokeMethod("method", ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this? Added by mistake maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, such a good carch, that was added by mistake while I tried to convert Map
to String
. This line is leftover from there, will remove it. And create another PR with changes.
## [1.0.0-alpha.8](1.0.0-alpha.7...1.0.0-alpha.8) (2023-02-13) ### Features * added missing methods ([#17](#17)) ([73f29e6](73f29e6))
🎉 This PR is included in version 1.0.0-alpha.8 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
## 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))
🎉 This PR is included in version 1.0.0-beta.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
## 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))
## 1.0.0 (2023-10-18) ### Features * added missing methods ([customerio#17](https://github.com/nagyist/customerio-flutter/issues/17)) ([73f29e6](73f29e6)) * added SDK config ([#1](#1)) ([e8ed7dd](e8ed7dd)) * in-app dismiss support ([customerio#51](https://github.com/nagyist/customerio-flutter/issues/51)) ([c4d21f2](c4d21f2)) * process push notifications received outside CIO SDK ([customerio#38](https://github.com/nagyist/customerio-flutter/issues/38)) ([7b5cb7e](7b5cb7e)) * tracking and in-app added ([#2](#2)) ([c23f2d9](c23f2d9)) ### Bug Fixes * add test coverage and refactored scripts ([customerio#34](https://github.com/nagyist/customerio-flutter/issues/34)) ([f7f2387](f7f2387)) * autoupdate to latest major version of iOS SDK ([customerio#40](https://github.com/nagyist/customerio-flutter/issues/40)) ([974a342](974a342)) * formatting issues ([d67fa7e](d67fa7e)) * hardcode android native SDK version ([customerio#61](https://github.com/nagyist/customerio-flutter/issues/61)) ([587f559](587f559)) * in-app concurrency issue android ([customerio#73](https://github.com/nagyist/customerio-flutter/issues/73)) ([93332a4](93332a4)) * in-app crash for no browser ([customerio#94](https://github.com/nagyist/customerio-flutter/issues/94)) ([8b859ed](8b859ed)) * in-app messages not displaying for release builds on Android ([customerio#65](https://github.com/nagyist/customerio-flutter/issues/65)) ([1d742c2](1d742c2)) * in-app remove gist org id ([customerio#19](https://github.com/nagyist/customerio-flutter/issues/19)) ([ce4cc9e](ce4cc9e)) * iOS crash on forced unwrapping ([customerio#59](https://github.com/nagyist/customerio-flutter/issues/59)) ([f514174](f514174)) * missing methods and extra dependency ([2c5deca](2c5deca)) * missing opened metric on android 12 and above ([customerio#43](https://github.com/nagyist/customerio-flutter/issues/43)) ([1a61e0e](1a61e0e)) * obj-c bindings issue ([0dbe4ef](0dbe4ef)) * plugin version in user-agent ([a10e482](a10e482)) * release script typo ([2a8b7ae](2a8b7ae)) * stack-overflow caused by BQ recursion ([customerio#90](https://github.com/nagyist/customerio-flutter/issues/90)) ([ebc7511](ebc7511)) * typo fixed ([customerio#9](https://github.com/nagyist/customerio-flutter/issues/9)) ([a5107df](a5107df)), closes [#7](#7) [#8](#8) * updated android dependency to auto update ([customerio#24](https://github.com/nagyist/customerio-flutter/issues/24)) ([040cef2](040cef2)) * updated icon and typo ([57c6eef](57c6eef)) * updated module name from common to CioInternalCommon ([customerio#55](https://github.com/nagyist/customerio-flutter/issues/55)) ([d81f8df](d81f8df))
## 1.0.0 (2024-10-12) ### Features * added missing methods ([customerio#17](https://github.com/AristideVB/customerio-flutter/issues/17)) ([73f29e6](73f29e6)) * added SDK config ([customerio#1](https://github.com/AristideVB/customerio-flutter/issues/1)) ([e8ed7dd](e8ed7dd)) * do not show modal message if screen changes and page rule mismatches ([customerio#131](https://github.com/AristideVB/customerio-flutter/issues/131)) ([a563055](a563055)) * in-app dismiss support ([customerio#51](https://github.com/AristideVB/customerio-flutter/issues/51)) ([c4d21f2](c4d21f2)) * in-app message persistence ([customerio#97](https://github.com/AristideVB/customerio-flutter/issues/97)) ([71d85cc](71d85cc)) * process push notifications received outside CIO SDK ([customerio#38](https://github.com/AristideVB/customerio-flutter/issues/38)) ([7b5cb7e](7b5cb7e)) * support for android gradle plugin 8 ([customerio#117](https://github.com/AristideVB/customerio-flutter/issues/117)) ([48b4e06](48b4e06)) * tracking and in-app added ([customerio#2](https://github.com/AristideVB/customerio-flutter/issues/2)) ([c23f2d9](c23f2d9)) ### Bug Fixes * add test coverage and refactored scripts ([customerio#34](https://github.com/AristideVB/customerio-flutter/issues/34)) ([f7f2387](f7f2387)) * added proguard rules for R8 strict mode ([customerio#116](https://github.com/AristideVB/customerio-flutter/issues/116)) ([9946fe7](9946fe7)) * autoupdate to latest major version of iOS SDK ([customerio#40](https://github.com/AristideVB/customerio-flutter/issues/40)) ([974a342](974a342)) * formatting issues ([d67fa7e](d67fa7e)) * hardcode android native SDK version ([customerio#61](https://github.com/AristideVB/customerio-flutter/issues/61)) ([587f559](587f559)) * improve android push click behavior ([customerio#89](https://github.com/AristideVB/customerio-flutter/issues/89)) ([62b9e61](62b9e61)) * improve in-app logs ([customerio#139](https://github.com/AristideVB/customerio-flutter/issues/139)) ([b10cc75](b10cc75)) * in-app concurrency issue android ([customerio#73](https://github.com/AristideVB/customerio-flutter/issues/73)) ([93332a4](93332a4)) * in-app crash for no browser ([customerio#94](https://github.com/AristideVB/customerio-flutter/issues/94)) ([8b859ed](8b859ed)) * in-app messages not displaying for release builds on Android ([customerio#65](https://github.com/AristideVB/customerio-flutter/issues/65)) ([1d742c2](1d742c2)) * in-app remove gist org id ([customerio#19](https://github.com/AristideVB/customerio-flutter/issues/19)) ([ce4cc9e](ce4cc9e)) * iOS crash on forced unwrapping ([customerio#59](https://github.com/AristideVB/customerio-flutter/issues/59)) ([f514174](f514174)) * missing methods and extra dependency ([2c5deca](2c5deca)) * missing opened metric on android 12 and above ([customerio#43](https://github.com/AristideVB/customerio-flutter/issues/43)) ([1a61e0e](1a61e0e)) * obj-c bindings issue ([0dbe4ef](0dbe4ef)) * plugin version in user-agent ([a10e482](a10e482)) * release script typo ([2a8b7ae](2a8b7ae)) * send native to flutter messages on main thread ([customerio#134](https://github.com/AristideVB/customerio-flutter/issues/134)) ([bc8704b](bc8704b)) * stack-overflow caused by BQ recursion ([customerio#90](https://github.com/AristideVB/customerio-flutter/issues/90)) ([ebc7511](ebc7511)) * typo fixed ([customerio#9](https://github.com/AristideVB/customerio-flutter/issues/9)) ([a5107df](a5107df)), closes [customerio#7](https://github.com/AristideVB/customerio-flutter/issues/7) [customerio#8](https://github.com/AristideVB/customerio-flutter/issues/8) * updated android dependency to auto update ([customerio#24](https://github.com/AristideVB/customerio-flutter/issues/24)) ([040cef2](040cef2)) * updated icon and typo ([57c6eef](57c6eef)) * updated module name from common to CioInternalCommon ([customerio#55](https://github.com/AristideVB/customerio-flutter/issues/55)) ([d81f8df](d81f8df))
closes : #20, https://github.com/customerio/issues/issues/8960
and #13