Skip to content

Commit

Permalink
Maui notification example
Browse files Browse the repository at this point in the history
  • Loading branch information
adam1929 authored Sep 27, 2023
1 parent 9c50924 commit ff7adf8
Show file tree
Hide file tree
Showing 17 changed files with 370 additions and 54 deletions.
16 changes: 13 additions & 3 deletions BloomreachSDK/Lib/BloomreachSDK.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System.Runtime.Versioning;
using System;
using System.Collections.Generic;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using Bloomreach.Utils;

#if IOS
using UserNotifications;
using Foundation;
#endif

namespace Bloomreach
Expand Down Expand Up @@ -325,7 +328,7 @@ public static void TrackSessionStart()
[SupportedOSPlatform("android")]
public static bool HandleRemoteMessage(NotificationPayload payload)
{
var serializedPayload = ConverterUtils.SerializeInput(payload);
var serializedPayload = ConverterUtils.SerializeInput(payload.RawData);
if (serializedPayload == null)
{
return false;
Expand Down Expand Up @@ -374,6 +377,13 @@ public static void HandlePushToken(string pushToken)
Instance.Channel.InvokeMethod("HandlePushToken", pushToken);
}

#if IOS
public static void HandlePushToken(NSData pushToken)
{
Instance.Channel.InvokeMethod("HandlePushToken", pushToken.ToString(NSStringEncoding.UTF8));
}
#endif

public static bool IsBloomreachNotification(NotificationPayload notificationPayload)
{
var result = Instance.Channel.InvokeMethod(
Expand Down
33 changes: 29 additions & 4 deletions BloomreachSDK/Lib/Models/NotificationAction.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
using System.Collections.Generic;
#if IOS
using Bloomreach.Utils;
using Foundation;
using UserNotifications;
#endif

namespace Bloomreach;

public class NotificationAction
Expand All @@ -15,21 +22,39 @@ public NotificationAction(string actionType, string actionName, string url)

public string? ActionIdentifier { get; set; }

public Dictionary<string, object?> Attributes { get; set; } = new ();
public Dictionary<string, object> Attributes { get; set; } = new ();

public NotificationAction WithAttribute(string key, object? value)
public NotificationAction WithAttribute(string key, object value)
{
return WithAttributes(new Dictionary<string, object?>() {
return WithAttributes(new Dictionary<string, object>() {
{ key, value }
});
}

public NotificationAction WithAttributes(IDictionary<string, object?> properties)
public NotificationAction WithAttributes(IDictionary<string, object> properties)
{
foreach (var each in properties)
{
Attributes[each.Key] = each.Value;
}
return this;
}

#if IOS
public static NotificationAction Parse(UNNotificationResponse response)
{
var payload = response.Notification.Request.Content.UserInfo;
var identifier = response.ActionIdentifier;
return new NotificationAction(
identifier, identifier, identifier
).WithAttributes(ConverterUtils.NormalizeDictionary(payload));
}

public static NotificationAction Parse(NSDictionary userInfo)
{
return new NotificationAction(
"", "", ""
).WithAttributes(ConverterUtils.NormalizeDictionary(userInfo));
}
#endif
}
16 changes: 16 additions & 0 deletions BloomreachSDK/Lib/Utils/ConverterUtils.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
#if IOS
using Foundation;
#endif
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
Expand Down Expand Up @@ -51,5 +57,15 @@ public static IDictionary<string, object> NormalizeDictionary(IDictionary<string
);
}

#if IOS
public static IDictionary<string, object> NormalizeDictionary(NSDictionary source)
{
return source.ToDictionary<KeyValuePair<NSObject, NSObject>, string, object>(
item => item.Key as NSString,
item => item.Value
);
}
#endif

public static bool ToBool(string? result) => result?.ToLower()?.Equals("true") ?? false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ internal fun parseProjectRouteMap(
defaultBaseUrl: String
): Map<EventType, List<ExponeaProject>> {
val mapping: HashMap<EventType, List<ExponeaProject>> = hashMapOf()
map.forEach { (eventTypeString, projectListAny) ->
for ((eventTypeString, projectListAny) in map) {
try {
val eventType = parseEventType(eventTypeString)
val projectList = projectListAny as List<Map<String, Any?>>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.bloomreach.sdk.maui.android

import android.Manifest
import android.app.Activity
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
Expand Down Expand Up @@ -125,7 +127,11 @@ internal fun BloomreachSdkAndroid.requestPushAuthorization(context: Context) {
Logger.i(this, "Push notifications permission already granted")
return
}
context.startActivity(Intent(context, NotificationsPermissionActivity::class.java))
val intent = Intent(context, NotificationsPermissionActivity::class.java)
if (context !is Activity) {
intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(intent)
}

internal fun BloomreachSdkAndroid.setReceivedPushCallback(listener: (Map<String, Any>) -> Unit) {
Expand Down
47 changes: 30 additions & 17 deletions ExampleApp/ExampleApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,35 @@
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-ios|AnyCPU'">
<CreatePackage>false</CreatePackage>
<CodesignProvision>Automatic</CodesignProvision>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchInterpreter>-all</MtouchInterpreter>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<CreatePackage>false</CreatePackage>
<CodesignProvision>Automatic</CodesignProvision>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchInterpreter>-all</MtouchInterpreter>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<CodesignEntitlements>Platforms\iOS\Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<WarningLevel>4</WarningLevel>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net6.0-android|AnyCPU'">
<AndroidEnableMultiDex>true</AndroidEnableMultiDex>
<AndroidDexTool>d8</AndroidDexTool>
<AndroidEnableMultiDex>true</AndroidEnableMultiDex>
<AndroidDexTool>d8</AndroidDexTool>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.Contains('android'))">
<AndroidKeyStore>True</AndroidKeyStore>
<AndroidSigningKeyStore>Platforms\Android\ExampleApp.jks</AndroidSigningKeyStore>
<AndroidSigningStorePass>Exponea</AndroidSigningStorePass>
<AndroidSigningKeyAlias>key0</AndroidSigningKeyAlias>
<AndroidSigningKeyPass>Exponea</AndroidSigningKeyPass>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net7.0-ios|AnyCPU'">
<CreatePackage>false</CreatePackage>
<MtouchInterpreter>-all</MtouchInterpreter>
<MtouchArch>x86_64</MtouchArch>
<CreatePackage>false</CreatePackage>
<MtouchInterpreter>-all</MtouchInterpreter>
<MtouchArch>x86_64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-ios|AnyCPU'">
<CreatePackage>false</CreatePackage>
<CreatePackage>false</CreatePackage>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
Expand All @@ -74,15 +82,18 @@
<ForegroundFile>Resources\AppIcon\appiconexamplefg.svg</ForegroundFile>
<Color>#512BD4</Color>
</MauiIcon>

<!-- Assets -->
<MauiAsset Include="Platforms\Android\Assets\agconnect-services.json" Condition="'$(TargetFramework)' == 'net6.0-android'" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BloomreachSDK\BloomreachSDK.csproj" />
<ProjectReference Include="..\BloomreachSDK\BloomreachSDK.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Platforms\Android\MainApplication.cs">
<ExcludeFromCurrentConfiguration>false</ExcludeFromCurrentConfiguration>
</Compile>
<Compile Update="Platforms\Android\MainApplication.cs">
<ExcludeFromCurrentConfiguration>false</ExcludeFromCurrentConfiguration>
</Compile>
</ItemGroup>

<!-- Android -->
Expand All @@ -107,5 +118,7 @@
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0-android'">
<GoogleServicesJson Include="Platforms\Android\google-services.json" />
<PackageReference Include="Xamarin.Firebase.Messaging" Version="123.1.2.2" />
<PackageReference Include="Huawei.Hms.Push" Version="6.10.0.300" />
<PackageReference Include="Huawei.Hms.NetworkFrameworkCompat" Version="6.0.11.300" />
</ItemGroup>
</Project>
3 changes: 3 additions & 0 deletions ExampleApp/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
<Button BackgroundColor="#fed500" Text="Show Configuration" Clicked="ShowConfiguration" />
<Button BackgroundColor="#fed500" Text="Track custom event" Clicked="TrackCustomEvent" />
<Button BackgroundColor="#fed500" Text="Track payment" Clicked="TrackPayment" />
<Button Text="Register for push notifications" Clicked="Register_For_Push_Clicked"/>
<Button Text="Track push delivered" Clicked="Track_Delivered_Clicked"/>
<Button Text="Track push clicked" Clicked="Track_Clicked_Clicked"/>
<Button BackgroundColor="#fed500" x:Name="SessionStartButton" Text="Track session start"
Clicked="SessionStart" />
<Button BackgroundColor="#fed500" x:Name="SessionEndButton" Text="Track session end"
Expand Down
46 changes: 24 additions & 22 deletions ExampleApp/MainPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Bloomreach;

#if IOS
using Foundation;
using UIKit;
Expand All @@ -17,27 +16,6 @@ public MainPage()
CustomerCookie.Text = "Customer cookie: \n" + Bloomreach.BloomreachSDK.GetCustomerCookie();
SessionStartButton.IsVisible = !Bloomreach.BloomreachSDK.IsAutomaticSessionTracking();
SessionEndButton.IsVisible = !Bloomreach.BloomreachSDK.IsAutomaticSessionTracking();
RegisterForRemoteNotifications();
}

private static void RegisterForRemoteNotifications()
{
#if IOS
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var pushSettings = UIUserNotificationSettings.GetSettingsForTypes(
UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound,
new NSSet());

UIApplication.SharedApplication.RegisterUserNotificationSettings(pushSettings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else
{
UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
}
#endif
}

async void ShowConfiguration(object sender, EventArgs e)
Expand Down Expand Up @@ -121,4 +99,28 @@ async void Switch_Project_ClickedAsync(object sender, EventArgs e)
Preferences.Set("authorization", authorization);
Preferences.Set("baseURL", baseUrl);
}

void Register_For_Push_Clicked(object sender, EventArgs e)
{
Bloomreach.BloomreachSDK.RequestPushAuthorization();
}

void Track_Delivered_Clicked(object sender, EventArgs e)
{
var payload = NotificationPayload.Parse(new Dictionary<string, string>
{
{"campaign_id", "id"}
});
Bloomreach.BloomreachSDK.TrackDeliveredPush(payload);
}

void Track_Clicked_Clicked(object sender, EventArgs e)
{
var action = new NotificationAction(
"click",
"action",
"https://bloomreach.com"
).WithAttribute("campaign_id", "id");
Bloomreach.BloomreachSDK.TrackClickedPush(action);
}
}
2 changes: 1 addition & 1 deletion ExampleApp/Platforms/Android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.bloomreach.maui.exampleapp" android:versionCode="1" android:versionName="1.0">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.exponea.example" android:versionCode="1" android:versionName="1.0">
<!--suppress CheckTagEmptyBody -->
<application android:allowBackup="true" android:icon="@mipmap/appicon_example" android:supportsRtl="true" android:label="ExampleApp"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Expand Down
74 changes: 74 additions & 0 deletions ExampleApp/Platforms/Android/Assets/agconnect-services.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"agcgw":{
"backurl":"connect-dre.hispace.hicloud.com",
"url":"connect-dre.dbankcloud.cn",
"websocketbackurl":"connect-ws-dre.hispace.dbankcloud.com",
"websocketurl":"connect-ws-dre.hispace.dbankcloud.cn"
},
"agcgw_all":{
"CN":"connect-drcn.dbankcloud.cn",
"CN_back":"connect-drcn.hispace.hicloud.com",
"DE":"connect-dre.dbankcloud.cn",
"DE_back":"connect-dre.hispace.hicloud.com",
"RU":"connect-drru.dbankcloud.cn",
"RU_back":"connect-drru.hispace.hicloud.com",
"SG":"connect-dra.dbankcloud.cn",
"SG_back":"connect-dra.hispace.hicloud.com"
},
"client":{
"cp_id":"5190421000024647787",
"product_id":"736430079245957670",
"client_id":"699887186287281088",
"client_secret":"2B8514CF138C6FE78912D20F6F23199B7C7BDEC32D98CC7ABD942CAC2A78B4B3",
"project_id":"736430079245957670",
"app_id":"104661225",
"api_key":"CwEAAAAA0otl+rs1I1lSYRubaxM0QS+eSC9Sr5pHt8k23l1ev3cTNPcH0tbpJ9N8lx3BJbouHxB2knDEv7bNmeZqGdyrRv+M5+E=",
"package_name":"com.exponea.example"
},
"oauth_client":{
"client_id":"104661225",
"client_type":1
},
"app_info":{
"app_id":"104661225",
"package_name":"com.exponea.example"
},
"service":{
"analytics":{
"collector_url":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
"collector_url_ru":"datacollector-drru.dt.hicloud.com,datacollector-drru.dt.dbankcloud.cn",
"collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn",
"collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
"collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
"resource_id":"p1",
"channel_id":""
},
"search":{
"url":"https://search-dre.cloud.huawei.com"
},
"cloudstorage":{
"storage_url":"https://ops-dre.agcstorage.link"
},
"ml":{
"mlservice_url":"ml-api-dre.ai.dbankcloud.com,ml-api-dre.ai.dbankcloud.cn"
}
},
"region":"DE",
"configuration_version":"3.0",
"appInfos":[
{
"package_name":"com.exponea.example",
"client":{
"app_id":"104661225"
},
"app_info":{
"package_name":"com.exponea.example",
"app_id":"104661225"
},
"oauth_client":{
"client_type":1,
"client_id":"104661225"
}
}
]
}
Binary file added ExampleApp/Platforms/Android/ExampleApp.jks
Binary file not shown.
Loading

0 comments on commit ff7adf8

Please sign in to comment.