Skip to content

Commit

Permalink
Add manifest params for Foreground notification customization (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavel-kuznetsov-hypertrack authored Oct 2, 2024
1 parent 43a3990 commit 91533ae
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 36 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [4.4.0] - 2024-09-30

### Added

- Added new plugin prameter:
- `allowMockLocation` - to enable mock locations for testing
- `foregroundNotificationTitle`, `foregroundNotificationText` - to configure foreground notification on Android


## [4.3.0] - 2024-09-18

### Changed
Expand All @@ -25,7 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `proxyDevicePushTokenCall` config plugin property
- Added `proxyDevicePushTokenCall` plugin property to enable calling HyperTrack SDK as soon as the device token is received in the AppDelegate

## [4.0.1] - 2023-11-11

Expand Down Expand Up @@ -75,6 +84,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Initial release of the expo plugin.

[4.4.0]: https://github.com/hypertrack/sdk-expo/releases/tag/4.4.0
[4.3.0]: https://github.com/hypertrack/sdk-expo/releases/tag/4.3.0
[4.2.0]: https://github.com/hypertrack/sdk-expo/releases/tag/4.2.0
[4.1.0]: https://github.com/hypertrack/sdk-expo/releases/tag/4.1.0
Expand Down
30 changes: 30 additions & 0 deletions PARAMS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Plugin configuration parameters

You can provide these params to the plugin in `app.json` to configure the plugin like this:

```json
{
"plugins": [
[
"hypertrack-sdk-expo",
{
<param>: <value>
}
]
],
}
```

## Parameters

Check [SDK configuration](https://hypertrack.com/docs/sdk-config) doc for more detailed informtion about the params.

| Param | Type | Description |
| --------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| allowMockLocation | `boolean` | Allow mocking locations (if set to false any mocked location will be filtered and the outage will be displayed in the Dashboard). Default: false |
| foregroundNotificationText | `string` | Text for the foreground service notification on Android |
| foregroundNotificationTitle | `string` | Title for the foreground service notification on Android |
| locationPermission | `string` | Location permission permission purpose string (see [Configuring permission purpose strings](README.md#configuring-permission-purpose-strings)) |
| motionPermission | `string` | Motion permission purpose string (see [Configuring permission purpose strings](README.md#configuring-permission-purpose-strings)) |
| publishableKey | `string` | HyperTrack publishable key |
| proxyDevicePushTokenCall | `boolean` | Proxy device push token call to the plugin. See [Working around missing device push token on iOS](README.md#working-around-missing-device-push-token-on-ios). False by default. |
25 changes: 6 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,7 @@ Add `hypertrack-sdk-expo` to [`plugins`](https://docs.expo.io/versions/latest/co
}
```

### Set required build properties

Use [expo-build-properties](https://docs.expo.dev/versions/latest/sdk/build-properties/) to set build properties.

Run `npx expo install expo-build-properties` and add this to `plugins` in `app.json` or `app.config.js`:

```json
[
"expo-build-properties",
{
"android": {
"minSdkVersion": 21
}
}
]
```
You can check more plugin configuration options [here](PARAMS.md).

### Set up push notifications

Expand All @@ -91,7 +76,7 @@ Ensure you use versions that work together! These are the ones that have been te

| `expo` | `hypertrack-sdk-expo` | `hypertrack-sdk-react-native` |
| -------- | --------------------- | ----------------------------- |
| ^51.0.32 | 4.3.0 | ^13.5.1 |
| ^51.0.32 | ^4.3.0 | ^13.5.1 |
| ^50.0.4 | 4.2.0 | ^13.1.0 |
| ^50.0.4 | 4.1.0 | ^13.1.0 |
| ^49.0.13 | 4.0.1 | ^11.0.9 |
Expand All @@ -102,11 +87,13 @@ Ensure you use versions that work together! These are the ones that have been te
| ^46.0.14 | 1.1.0 | ^8.2.1 |
| ^45.0.0 | 1.0.0 | ^7.19.1 |

## Working around missing device push token on iOS
## FAQ

### Working around missing device push token on iOS

If your devices are missing the push token, as a workaround you can set `proxyDevicePushTokenCall` plugin property to `true`. This will ensure you are calling HyperTrack SDK as soon as the device token is received in the AppDelegate.

## Configuring permission purpose strings
### Configuring permission purpose strings

iOS requires specifying [permission purpose strings](https://hypertrack.com/docs/install-sdk-ios/#add-location-and-motion-purpose-strings) in `Info.plist` for app to build.

Expand Down
9 changes: 9 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ REPOSITORY_NAME := "sdk-expo"
# \ are escaped
SEMVER_REGEX := "(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?"

# MAKE SURE YOU HAVE
# #!/usr/bin/env sh
# set -e
# AT THE TOP OF YOUR RECIPE
_ask-confirm:
@bash -c 'read confirmation; if [[ $confirmation != "y" && $confirmation != "Y" ]]; then echo "Okay 😮‍💨 😅"; exit 1; fi'


build:
yarn expo-module clean
yarn expo-module build
Expand Down Expand Up @@ -46,6 +54,7 @@ release publish="dry-run":
fi
echo "Are you sure you want to publish version $VERSION? (y/N)"
just _ask-confirm
npm publish
open "https://www.npmjs.com/package/hypertrack-sdk-expo/v/$VERSION"
else
npm publish --dry-run
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hypertrack-sdk-expo",
"version": "4.3.0",
"version": "4.4.0",
"license": "MIT",
"description": "Config plugin to auto configure hypertrack-sdk-react-native on prebuild",
"homepage": "https://github.com/hypertrack/sdk-expo",
Expand Down
5 changes: 4 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { withHyperTrackAndroid } from "./withHyperTrackAndroid";
import { withHyperTrackIOS } from "./withHyperTrackIOS";

export type Props = {
allowMockLocation?: boolean;
foregroundNotificationText?: string;
foregroundNotificationTitle?: string;
locationPermission?: string;
motionPermission?: string;
publishableKey: string;
Expand All @@ -22,5 +25,5 @@ const withHyperTrack: ConfigPlugin<Props> = (config, props) => {
export default createRunOncePlugin(
withHyperTrack,
"hypertrack-sdk-expo",
"4.3.0"
"4.4.0"
);
90 changes: 88 additions & 2 deletions src/withHyperTrackAndroid.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import {
AndroidConfig,
ConfigPlugin,
WarningAggregator,
withAndroidManifest,
withAppBuildGradle,
withProjectBuildGradle,
withStringsXml,
} from "@expo/config-plugins";
import { mergeContents } from "@expo/config-plugins/build/utils/generateCode";
import { Props } from ".";
import {
ManifestApplication,
addMetaDataItemToMainApplication,
} from "@expo/config-plugins/build/android/Manifest";
import { ExpoConfig } from "@expo/config-types";

export const withHyperTrackAndroid: ConfigPlugin<Props> = (config, props) => {
withAndroidPackage(config);
withAndroidPackagingOptions(config);
addCustomStrings(config, props);
updateAndroidManifest(config, props);
return config;
};
Expand Down Expand Up @@ -49,6 +53,24 @@ export function addMaven(src: string) {
});
}

export function addCustomStrings(config: any, props: Props) {
const { foregroundNotificationText, foregroundNotificationTitle } = props || {};
if (foregroundNotificationText !== undefined) {
withCustomString(
config,
"hypertrack_foreground_notification_text",
foregroundNotificationText
);
}
if (foregroundNotificationTitle !== undefined) {
withCustomString(
config,
"hypertrack_foreground_notification_title",
foregroundNotificationTitle
);
}
}

export const withAndroidPackagingOptions: ConfigPlugin = (config) => {
return withAppBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
Expand Down Expand Up @@ -90,9 +112,14 @@ const packagingOptionsContents = `

const updateAndroidManifest: ConfigPlugin<Props> = (config, props) => {
return withAndroidManifest(config, (newConfig) => {
const { publishableKey } = props || {};
const {
allowMockLocation,
foregroundNotificationText,
foregroundNotificationTitle,
publishableKey,
} = props || {};

if (!publishableKey) {
if (publishableKey === undefined) {
throw new Error("'publishableKey' param is required");
}

Expand All @@ -108,6 +135,65 @@ const updateAndroidManifest: ConfigPlugin<Props> = (config, props) => {
}
);

if (allowMockLocation !== undefined) {
if(typeof allowMockLocation !== "boolean") {
throw new Error("'allowMockLocation' param must be a boolean");
}
newConfig.modResults.manifest.application = applications()?.map(
(application: ManifestApplication) => {
return addMetaDataItemToMainApplication(
application,
"HyperTrackAllowMockLocation",
allowMockLocation.toString()
);
}
);
}

if (foregroundNotificationText !== undefined) {
newConfig.modResults.manifest.application = applications()?.map(
(application: ManifestApplication) => {
return addMetaDataItemToMainApplication(
application,
"HyperTrackForegroundNotificationText",
"@string/hypertrack_foreground_notification_text",
"resource"
);
}
);
}

if (foregroundNotificationTitle !== undefined) {
newConfig.modResults.manifest.application = applications()?.map(
(application: ManifestApplication) => {
return addMetaDataItemToMainApplication(
application,
"HyperTrackForegroundNotificationTitle",
"@string/hypertrack_foreground_notification_title",
"resource"
);
}
);
}

return newConfig;
});
};

function withCustomString(
config: any,
name: string,
value: string
): ExpoConfig {
return withStringsXml(config, (config) => {
config.modResults = AndroidConfig.Strings.setStringItem(
[
// XML represented as JSON
// <string name="expo_custom_value" translatable="false">value</string>
{ $: { name, translatable: "false" }, _: value },
],
config.modResults
);
return config;
});
}
25 changes: 13 additions & 12 deletions src/withHyperTrackIOS.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import {
ConfigPlugin,
ExportedConfigWithProps,
withInfoPlist,
withDangerousMod,
withAppDelegate,
withXcodeProject,
} from "@expo/config-plugins";
import { withBuildSourceFile } from "@expo/config-plugins/build/ios/XcodeProjectFile";
import * as codegen from "@expo/config-plugins/build/utils/generateCode";

import { Props } from ".";
import * as fs from "fs";
import * as path from "path";

export const withHyperTrackIOS: ConfigPlugin<Props> = (config, props) => {
withBackgroundModes(config, props);
if (props.proxyDevicePushTokenCall) {
if (typeof props.proxyDevicePushTokenCall !== "boolean") {
throw new Error("'proxyDevicePushTokenCall' param must be a boolean");
}
if (props.proxyDevicePushTokenCall === true) {
withHTRNProxy(config, props);
}
return config;
Expand Down Expand Up @@ -97,14 +96,11 @@ const withBackgroundModes: ConfigPlugin<Props> = (config, props) => {
const {
locationPermission: locationPermissionDescription,
motionPermission: motionPermissionDescription,
allowMockLocation,
publishableKey,
swizzlingDidReceiveRemoteNotificationEnabled,
} = props || {};

if (!publishableKey) {
throw new Error("'publishableKey' param is required");
}

const BACKGROUND_MODE_KEYS = ["location", "remote-notification"];
return withInfoPlist(config, (newConfig) => {
// Set UIBackgroundModes
Expand All @@ -127,14 +123,14 @@ const withBackgroundModes: ConfigPlugin<Props> = (config, props) => {
newConfig.modResults.NSMotionUsageDescription = motionPermissionDescription;

// Set SDK init params
if (publishableKey) {
if (publishableKey !== undefined) {
newConfig.modResults.HyperTrackPublishableKey = publishableKey;
} else {
throw new Error(
"'publishableKey' param is required for HyperTrack Expo plugin"
);
}
if (swizzlingDidReceiveRemoteNotificationEnabled) {
if (swizzlingDidReceiveRemoteNotificationEnabled !== undefined) {
if (typeof swizzlingDidReceiveRemoteNotificationEnabled !== "boolean") {
throw new Error(
"'swizzlingDidReceiveRemoteNotificationEnabled' param must be a boolean"
Expand All @@ -143,7 +139,12 @@ const withBackgroundModes: ConfigPlugin<Props> = (config, props) => {
newConfig.modResults.HyperTrackSwizzlingDidReceiveRemoteNotificationEnabled =
swizzlingDidReceiveRemoteNotificationEnabled;
}

if (allowMockLocation !== undefined) {
if (typeof allowMockLocation !== "boolean") {
throw new Error("'allowMockLocation' param must be a boolean");
}
newConfig.modResults.HyperTrackAllowMockLocation = allowMockLocation;
}
return newConfig;
});
};

0 comments on commit 91533ae

Please sign in to comment.