Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
# Changelog
All notable changes to this package will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.0.0-pre.3] - 2021-08-19

### Fixed

* Updated 3rd party code notices

## [1.0.0-pre.2] - 2021-08-17

### New Features

* The package now uses the Core initialisation flow.

### Fixed

* Subsequent updates of the Android token will no longer cause a null pointer exception

## [1.0.0-pre.1] - 2021-08-05

### New Features

* Support for Android devices, including rich push notifications
* A simplified, unified external interface that allows one registration for both platforms

### Fixed

* Notifications now show when app is in the foreground on iOS

## [0.1.0-preview] - 2021-07-27

### New Features

* Support for iOS platform, including rich push notifications
* Push notification analytics - notificationOpened and notificationServices events

### Known Issues

* Android is not currently supported
* Analytics platform is hard coded to "IOS" as this integration is changing in the next release and currently this is the only platform we support
* Analytics country is hard coded to "GB" as this integration is changing in the next release and the currently released Analytics package doesn't provide this API
  • Loading branch information
Unity Technologies committed Aug 19, 2021
0 parents commit 435e332
Show file tree
Hide file tree
Showing 81 changed files with 2,414 additions and 0 deletions.
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Changelog
All notable changes to this package will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.0.0-pre.3] - 2021-08-19

### Fixed

* Updated 3rd party code notices

## [1.0.0-pre.2] - 2021-08-17

### New Features

* The package now uses the Core initialisation flow.

### Fixed

* Subsequent updates of the Android token will no longer cause a null pointer exception

## [1.0.0-pre.1] - 2021-08-05

### New Features

* Support for Android devices, including rich push notifications
* A simplified, unified external interface that allows one registration for both platforms

### Fixed

* Notifications now show when app is in the foreground on iOS

## [0.1.0-preview] - 2021-07-27

### New Features

* Support for iOS platform, including rich push notifications
* Push notification analytics - notificationOpened and notificationServices events

### Known Issues

* Android is not currently supported
* Analytics platform is hard coded to "IOS" as this integration is changing in the next release and currently this is the only platform we support
* Analytics country is hard coded to "GB" as this integration is changing in the next release and the currently released Analytics package doesn't provide this API
7 changes: 7 additions & 0 deletions CHANGELOG.md.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 78 additions & 0 deletions Documentation~/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Push Notifications SDK Documentation

The Push Notifications SDK allows you to send rich push notifications to mobile devices.

## Platform Support

This SDK supports both iOS and Android. iOS 10+ and Android SDK > 26 (Oreo) are supported.

## Quick Start

The SDK comes with a sample script that will register for push notifications. Simply add this to your project to get going.

## Registering for Push Notifications

To register for push notifications, two steps are required. Firstly, you need to initialise Unity Services, so that the required analytics events can be sent to Unity Analytics 2.0.

Once that is complete, you can then register for notifications. To ensure no notifications are missed, this should be done in the startup code for your game. Note that on first registration on iOS, a user will be shown a permission request, so ensure this call is made at a convenient place in your game. The SDK will handle the showing of notification content, including images, titles and message body.

A full code sample is shown below.

```cs
// In a monobehaviour in a convenient place in your game.
async void Start()
{
await UnityServices.InitializeAsync();
PushNotificationSettings settings = new PushNotificationSettings()
{
AndroidApiKey = "API_KEY",
AndroidSenderId = "SENDER_ID",
AndroidApplicationId = "APPLICATION_ID",
AndroidProjectId = "PROJECT_ID"
};

try
{

string pushToken = await PushNotifications.RegisterForPushNotificationsAsync(settings);

PushNotifications.OnNotificationReceived += notificationData =>
{
Debug.Log("Received a notification!");
};
}
catch (Exception e)
{
Debug.Log("Failed to retrieve a push notification token.");
}
}
```

### Notification Received Callbacks

You can register a delegate to receive a C# event callback when a notification is received, if you wish to perform custom behaviour at that point. To do this, add a delegate / method callback to `PushNotifications.OnNotificationReceived` as indicated in the sample above.

### Push Notification Settings

The SDK requires a number of settings in order to function correctly. Some settings are only used on a certain platform, this is indicated in the setting name. The following settings can be set:

* AndroidApiKey: The API key for a Firebase project to be used for Android's Firebase Cloud Messaging API. This can be found in your Firebase dashboard.
* AndroidSenderId: The sender ID to be used for Android's Firebase Cloud Messaging. This can be found in your Firebase dashboard.
* AndroidApplicationId: The application ID for a Firebase application to be used for Android's Firebase Cloud Messaging API. This can be found in your Firebase dashboard.
* AndroidProjectId: The project ID for a Firebase project to be used for Android's Firebase Cloud Messaging API. This can be found in your Firebase dashboard.

### Analytics

The SDK will records two analytics events:

* `notificationServices`: This event is recorded whenever a new token is registered on the client. It contains the push token and is used to register this token with the backend service.
* `notificationOpened`: This event is recorded whenever a notification is opened by a user. It contains data regarding which campaign and cohort the user was in, and whether the app was launched from the notification.

## Analytics Only Mode

> **Note:** This section is only required if you have an existing push notification solution you wish to use alongside the Unity Push Notifications package.
> This will result in reduced functionality of this package - e.g. images in notifications will not be displayed.
It is possible to integrate the SDK with an existing push notification service if required. To do so, use the two methods in the `PushNotifications.Analytics` class.

`RecordPushTokenUpdated` should be called when you receive
8 changes: 8 additions & 0 deletions Editor.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Editor/Android.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.Android;
using UnityEngine;

namespace Editor
{
public class InsertPushNotificationDependenciesIntoGradleScript: IPostGenerateGradleAndroidProject
{
public int callbackOrder => 0;

const string k_GradleDependencyOpeningTag = "dependencies {";

readonly Dictionary<string, string> m_Dependencies = new Dictionary<string, string>
{
{"com.google.firebase:firebase-messaging-ktx", "22.0.0"}
};

public void OnPostGenerateGradleAndroidProject(string path)
{
string libraryBuildGradlePath = Path.Combine(path, "build.gradle");
string buildGradleFileContent = File.ReadAllText(libraryBuildGradlePath);

string dependencyString = "";

foreach (var keyValuePair in m_Dependencies)
{
string library = keyValuePair.Key;
string version = keyValuePair.Value;

if (!buildGradleFileContent.Contains(library))
{
dependencyString = $"{dependencyString} implementation '{library}:{version}'\n";
}
}

string updatedBuildGradleFileContent = buildGradleFileContent.Replace(k_GradleDependencyOpeningTag, $"{k_GradleDependencyOpeningTag}\n{dependencyString}");
File.WriteAllText(libraryBuildGradlePath, updatedBuildGradleFileContent);

#if UNITY_2020_1_OR_NEWER
string projectRoot = path.Substring(0, path.LastIndexOf(Path.DirectorySeparatorChar));
string gradlePropertiesFilePath = Path.Combine(projectRoot, "gradle.properties");

string gradlePropertiesFileContent = File.Exists(gradlePropertiesFilePath) ? File.ReadAllText(gradlePropertiesFilePath) : "";

string updatedPropertiesFileContent = gradlePropertiesFileContent;
if (!gradlePropertiesFileContent.Contains("android.useAndroidX="))
{
updatedPropertiesFileContent = $"{gradlePropertiesFileContent}\nandroid.useAndroidX=true";
}
else if (gradlePropertiesFileContent.Contains("android.useAndroidX=false"))
{
Debug.LogWarning("The Unity Push Notifications SDK requires androidx support. We've updated your gradle.properties file to enable androidX, check this is appropriate for your use case.");
updatedPropertiesFileContent = gradlePropertiesFileContent.Replace("android.useAndroidX=false", "android.useAndroidX=true");
}
File.WriteAllText(gradlePropertiesFilePath, updatedPropertiesFileContent);
#endif
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions Editor/Unity.Services.PushNotifications.Editor.asmdef
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "Unity.Services.PushNotifications.Editor",
"references": [
"Unity.Services.PushNotifications"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": []
}
7 changes: 7 additions & 0 deletions Editor/Unity.Services.PushNotifications.Editor.asmdef.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Editor/iOS.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

89 changes: 89 additions & 0 deletions Editor/iOS/IOSBasicPushNotificationPostProcess.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#if UNITY_IOS
using System;
using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using UnityEngine;

namespace Unity.Services.PushNotifications.Editor
{
public class IOSBasicPushNotificationPostProcess : MonoBehaviour
{
[PostProcessBuild(0)]
public static void OnPostProcessBuild(BuildTarget buildTarget, String path)
{
if (buildTarget != BuildTarget.iOS)
{
return;
}

string projectPath = PBXProject.GetPBXProjectPath(path);
PBXProject project = new PBXProject();
project.ReadFromFile(projectPath);

string mainTargetGuid = project.GetUnityMainTargetGuid();
string unityFrameworkGuid = project.GetUnityFrameworkTargetGuid();
project.AddFrameworkToProject(unityFrameworkGuid, "UserNotifications.framework", true);

AddCapabilities(project, projectPath, mainTargetGuid, path);
UpdateInfoPlist(path);
UpdatePreprocessorFile(path);

project.WriteToFile(projectPath);
}

static void AddCapabilities(PBXProject project, string projectPath, string mainTargetGuid, string buildPath)
{
var entitlementsFileName = project.GetBuildPropertyForConfig(mainTargetGuid, "CODE_SIGN_ENTITLEMENTS");
if (entitlementsFileName == null)
{
string bundleIdentifier = PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.iOS);
entitlementsFileName = $"{bundleIdentifier.Substring(bundleIdentifier.LastIndexOf(".") + 1)}.entitlements";

// Add the entitlements file to the build
project.AddFile(Path.Combine(buildPath, entitlementsFileName), entitlementsFileName);
project.AddBuildProperty(mainTargetGuid, "CODE_SIGN_ENTITLEMENTS", entitlementsFileName);
}

var capManager = new ProjectCapabilityManager(projectPath, entitlementsFileName, "Unity-iPhone");

// TODO: Do we want to allow the user to specify which push environment they want to use, or should we always assume
// live? If so, the below will need updating with a new setting.
const bool useDevEnvironment = false;
capManager.AddPushNotifications(useDevEnvironment);

capManager.WriteToFile();
}

/*
* Add the remote notification background mode to the Xcode Info.plist file. Without this, we won't
* get access to the correct background modes and iOS won't successfully register for remote notifications.
*/
static void UpdateInfoPlist(string projectPath)
{
string plistPath = projectPath + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromFile(plistPath);

PlistElementArray existingBackgroundModes = (PlistElementArray) plist.root["UIBackgroundModes"] ?? plist.root.CreateArray("UIBackgroundModes");
existingBackgroundModes.AddString("remote-notification");

plist.WriteToFile(plistPath);
}

/*
* Update the preprocessor file to ensure Unity sends us registration callbacks when we register for remote notifications.
* If we don't do this, we are able to register, but we can't get access to the token in the native plugin to pass back
* to Unity.
*/
static void UpdatePreprocessorFile(string projectPath)
{
string preprocessorPath = projectPath + "/Classes/Preprocessor.h";
var preprocessor = File.ReadAllText(preprocessorPath);
preprocessor = preprocessor.Replace("UNITY_USES_REMOTE_NOTIFICATIONS 0", "UNITY_USES_REMOTE_NOTIFICATIONS 1");
File.WriteAllText(preprocessorPath, preprocessor);
}
}
}
#endif
11 changes: 11 additions & 0 deletions Editor/iOS/IOSBasicPushNotificationPostProcess.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 435e332

Please sign in to comment.