Skip to content

Commit

Permalink
remove default notification service and support notification channels
Browse files Browse the repository at this point in the history
  • Loading branch information
Ulrico972 committed Dec 2, 2024
1 parent c896b36 commit 9ba1d1e
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 30 deletions.

This file was deleted.

21 changes: 20 additions & 1 deletion plugin/src/withAirship.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,31 @@ import { withAirshipIOS } from './withAirshipIOS';
const pkg = require('airship-expo-plugin/package.json');

export type AirshipAndroidPluginProps = {
/**
* Required. The notification icons for Android.
*/
icon: string;
/**
* Optional. The local path to a Custom Notification Channels resource file.
*/
customNotificationChannels?: string;
};

export type AirshipIOSPluginProps = {
/**
* Required. Used to configure APNs environment entitlement.
* The accepted values are "development" and "production".
*/
mode: 'development' | 'production';
notificationServiceExtension?: boolean;
/**
* Optional. The local path to a custom Notification Service Extension.
*/
notificationService?: string;
/**
* Optional. Airship will use a default one if not provided.
* The local path to a Notification Service Extension Info.plist.
*/
notificationServiceInfo?: string;
}

export type AirshipPluginProps = {
Expand Down
40 changes: 38 additions & 2 deletions plugin/src/withAirshipAndroid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
} from '@expo/config-plugins';

import { generateImageAsync, ImageOptions } from '@expo/image-utils';
import { writeFileSync, existsSync, mkdirSync } from 'fs';
import { resolve, basename } from 'path';
import { readFile, writeFileSync, existsSync, mkdirSync } from 'fs';
import { resolve, basename, join } from 'path';

import { AirshipAndroidPluginProps } from './withAirship';

Expand All @@ -18,6 +18,8 @@ const iconSizeMap: Record<string, number> = {
xxxhdpi: 96,
};

const NOTIFICATIONS_CHANNELS_FILE_NAME = "ua_custom_notification_channels.xml";

async function writeNotificationIconImageFilesAsync(props: AirshipAndroidPluginProps, projectRoot: string) {
const fileName = basename(props.icon)
await Promise.all(
Expand Down Expand Up @@ -72,8 +74,42 @@ const withCompileSDKVersionFix: ConfigPlugin<AirshipAndroidPluginProps> = (confi
});
};

const withCustomNotificationChannels: ConfigPlugin<AirshipAndroidPluginProps> = (config, props) => {
return withDangerousMod(config, [
'android',
async config => {
await writeNotificationChannelsFileAsync(props, config.modRequest.projectRoot);
return config;
},
]);
}

// TODO copy the file from assets to xml res
async function writeNotificationChannelsFileAsync(props: AirshipAndroidPluginProps, projectRoot: string) {
if (!props.customNotificationChannels) {
return;
}

const xmlResPath = join(projectRoot, "android/app/src/main/res/xml");

if (!existsSync(xmlResPath)) {
mkdirSync(xmlResPath, { recursive: true });
}

// Copy the custom notification channels file into the Android expo project as ua_custom_notification_channels.xml.
readFile(props.customNotificationChannels, 'utf8', (err, data) => {
if (err || !data) {
console.error("Airship couldn't read file " + props.customNotificationChannels);
console.error(err);
return;
}
writeFileSync(join(xmlResPath, NOTIFICATIONS_CHANNELS_FILE_NAME), data);
});
};

export const withAirshipAndroid: ConfigPlugin<AirshipAndroidPluginProps> = (config, props) => {
config = withCompileSDKVersionFix(config, props);
config = withNotificationIcons(config, props);
config = withCustomNotificationChannels(config, props);
return config;
};
48 changes: 29 additions & 19 deletions plugin/src/withAirshipIOS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@expo/config-plugins';

import { readFile, writeFileSync, existsSync, mkdirSync } from 'fs';
import { join } from 'path';
import { basename, join } from 'path';

import { AirshipIOSPluginProps } from './withAirship';
import { mergeContents, MergeResults } from '@expo/config-plugins/build/utils/generateCode';
Expand Down Expand Up @@ -37,7 +37,21 @@ const withAPNSEnvironment: ConfigPlugin<AirshipIOSPluginProps> = (config, props)
});
};

const withNotificationServiceExtension: ConfigPlugin<AirshipIOSPluginProps> = (config, props) => {
return withDangerousMod(config, [
'ios',
async config => {
await writeNotificationServiceFilesAsync(props, config.modRequest.projectRoot);
return config;
},
]);
};

async function writeNotificationServiceFilesAsync(props: AirshipIOSPluginProps, projectRoot: string) {
if (!props.notificationService) {
return;
}

const pluginDir = require.resolve("airship-expo-plugin/package.json");
const sourceDir = join(pluginDir, "../plugin/NotificationServiceExtension/");

Expand All @@ -47,37 +61,34 @@ async function writeNotificationServiceFilesAsync(props: AirshipIOSPluginProps,
mkdirSync(extensionPath, { recursive: true });
}

// Copy the AirshipNotificationService.swift file into the iOS expo project.
readFile(join(sourceDir, NOTIFICATION_SERVICE_FILE_NAME), 'utf8', (err, data) => {
// Copy the NotificationService.swift file into the iOS expo project as AirshipNotificationService.swift.
readFile(props.notificationService, 'utf8', (err, data) => {
if (err || !data) {
console.error("Airship couldn't read file " + join(sourceDir, NOTIFICATION_SERVICE_FILE_NAME));
console.error("Airship couldn't read file " + props.notificationService);
console.error(err);
return;
}

if (!props.notificationServiceInfo) {
const regexp = /class [A-Za-z]+:/;
const newSubStr = "class AirshipNotificationService:";
data = data.replace(regexp, newSubStr);
}

writeFileSync(join(extensionPath, NOTIFICATION_SERVICE_FILE_NAME), data);
});

// Copy the AirshipNotificationServiceExtension-Info.plist file into the iOS expo project.
readFile(join(sourceDir, NOTIFICATION_SERVICE_INFO_PLIST_FILE_NAME), 'utf8', (err, data) => {
// Copy the Info.plist (default to AirshipNotificationServiceExtension-Info.plist if null) file into the iOS expo project as AirshipNotificationServiceExtension-Info.plist.
readFile(props.notificationServiceInfo ?? join(sourceDir, NOTIFICATION_SERVICE_INFO_PLIST_FILE_NAME), 'utf8', (err, data) => {
if (err || !data) {
console.error("Airship couldn't read file " + join(sourceDir, NOTIFICATION_SERVICE_INFO_PLIST_FILE_NAME));
console.error("Airship couldn't read file " + (props.notificationServiceInfo ?? join(sourceDir, NOTIFICATION_SERVICE_INFO_PLIST_FILE_NAME)));
console.error(err);
return;
}
writeFileSync(join(extensionPath, NOTIFICATION_SERVICE_INFO_PLIST_FILE_NAME), data);
});
};

const withNotificationServiceExtension: ConfigPlugin<AirshipIOSPluginProps> = (config, props) => {
return withDangerousMod(config, [
'ios',
async config => {
await writeNotificationServiceFilesAsync(props, config.modRequest.projectRoot);
return config;
},
]);
};

const withExtensionTargetInXcodeProject: ConfigPlugin<AirshipIOSPluginProps> = (config, props) => {
return withXcodeProject(config, newConfig => {
const xcodeProject = newConfig.modResults;
Expand Down Expand Up @@ -194,8 +205,7 @@ const withAirshipServiceExtensionPod: ConfigPlugin<AirshipIOSPluginProps> = (con
export const withAirshipIOS: ConfigPlugin<AirshipIOSPluginProps> = (config, props) => {
config = withCapabilities(config, props);
config = withAPNSEnvironment(config, props);

if (props.notificationServiceExtension) {
if (props.notificationService) {
config = withNotificationServiceExtension(config, props);
config = withExtensionTargetInXcodeProject(config, props);
config = withAirshipServiceExtensionPod(config, props);
Expand Down

0 comments on commit 9ba1d1e

Please sign in to comment.