155 lines
5.3 KiB
JavaScript
155 lines
5.3 KiB
JavaScript
|
|
const {
|
||
|
|
withAndroidManifest,
|
||
|
|
withDangerousMod,
|
||
|
|
withAppDelegate,
|
||
|
|
withInfoPlist,
|
||
|
|
withAppBuildGradle,
|
||
|
|
} = require('@expo/config-plugins');
|
||
|
|
const fs = require('fs');
|
||
|
|
const path = require('path');
|
||
|
|
|
||
|
|
const withJPush = (config, options = {}) => {
|
||
|
|
const { appKey, channel = 'developer-default' } = options;
|
||
|
|
|
||
|
|
if (!appKey) {
|
||
|
|
throw new Error('JPush appKey is required in plugin options');
|
||
|
|
}
|
||
|
|
|
||
|
|
// 1. Android: Inject manifestPlaceholders into app/build.gradle
|
||
|
|
config = withAppBuildGradle(config, (config) => {
|
||
|
|
const block = '\n manifestPlaceholders = [\n' +
|
||
|
|
' JPUSH_APPKEY: "' + appKey + '",\n' +
|
||
|
|
' JPUSH_CHANNEL: "' + channel + '"\n' +
|
||
|
|
' ]';
|
||
|
|
|
||
|
|
const contents = config.modResults.contents;
|
||
|
|
|
||
|
|
if (contents.includes('manifestPlaceholders')) {
|
||
|
|
config.modResults.contents = contents.replace(
|
||
|
|
/manifestPlaceholders\s*=\s*\[[\s\S]*?\]/,
|
||
|
|
block.trim()
|
||
|
|
);
|
||
|
|
} else if (contents.includes('REACT_NATIVE_RELEASE_LEVEL')) {
|
||
|
|
const lines = contents.split('\n');
|
||
|
|
for (let i = 0; i < lines.length; i++) {
|
||
|
|
if (lines[i].includes('REACT_NATIVE_RELEASE_LEVEL')) {
|
||
|
|
lines.splice(i + 1, 0, block);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
config.modResults.contents = lines.join('\n');
|
||
|
|
}
|
||
|
|
|
||
|
|
return config;
|
||
|
|
});
|
||
|
|
|
||
|
|
// 2. Android: Add JPush metadata and permissions to AndroidManifest
|
||
|
|
config = withAndroidManifest(config, (config) => {
|
||
|
|
const manifest = config.modResults;
|
||
|
|
|
||
|
|
if (!manifest.manifest['uses-permission']) {
|
||
|
|
manifest.manifest['uses-permission'] = [];
|
||
|
|
}
|
||
|
|
|
||
|
|
const requiredPermissions = [
|
||
|
|
'android.permission.RECEIVE_USER_PRESENT',
|
||
|
|
'android.permission.POST_NOTIFICATIONS',
|
||
|
|
];
|
||
|
|
|
||
|
|
requiredPermissions.forEach((permission) => {
|
||
|
|
const exists = manifest.manifest['uses-permission'].find(
|
||
|
|
(p) => p.$['android:name'] === permission
|
||
|
|
);
|
||
|
|
if (!exists) {
|
||
|
|
manifest.manifest['uses-permission'].push({
|
||
|
|
$: { 'android:name': permission },
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
return config;
|
||
|
|
});
|
||
|
|
|
||
|
|
// 3. iOS: Add JPush initialization to AppDelegate
|
||
|
|
config = withAppDelegate(config, (config) => {
|
||
|
|
const { contents } = config.modResults;
|
||
|
|
|
||
|
|
if (!contents.includes('JPush')) {
|
||
|
|
let newContents = contents;
|
||
|
|
|
||
|
|
if (!newContents.includes('#import <UserNotifications/UserNotifications.h>')) {
|
||
|
|
newContents = newContents.replace(
|
||
|
|
/(#import "AppDelegate.h")/,
|
||
|
|
`$1\n#import <UserNotifications/UserNotifications.h>`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!newContents.includes('#import <jcore-react-native/JCoreModule.h>')) {
|
||
|
|
newContents = newContents.replace(
|
||
|
|
/(#import "AppDelegate.h")/,
|
||
|
|
`$1\n#import <jcore-react-native/JCoreModule.h>`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
const didFinishLaunchPattern = /(- \(BOOL\)application:\(UIApplication \*\)application didFinishLaunchingWithOptions:\(NSDictionary \*\)launchOptions\s*\{)/;
|
||
|
|
if (didFinishLaunchPattern.test(newContents)) {
|
||
|
|
newContents = newContents.replace(
|
||
|
|
didFinishLaunchPattern,
|
||
|
|
`$1\n // JPush initialization\n [JCoreModule setupWithOption:launchOptions appKey:@"${appKey}" channel:@"${channel}" apsForProduction:NO];\n`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
const jpushMethods = `
|
||
|
|
// JPush: Register for remote notifications
|
||
|
|
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
|
||
|
|
[JCoreModule registerDeviceToken:deviceToken];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
|
||
|
|
NSLog(@"did fail to register for remote notifications with error: %@", error);
|
||
|
|
}
|
||
|
|
|
||
|
|
// JPush: Handle remote notification
|
||
|
|
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
|
||
|
|
[JCoreModule didReceiveRemoteNotification:userInfo];
|
||
|
|
completionHandler(UIBackgroundFetchResultNewData);
|
||
|
|
}
|
||
|
|
|
||
|
|
// UNUserNotificationCenter delegate
|
||
|
|
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
|
||
|
|
completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound);
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
|
||
|
|
[JCoreModule didReceiveRemoteNotification:response.notification.request.content.userInfo];
|
||
|
|
completionHandler();
|
||
|
|
}
|
||
|
|
`;
|
||
|
|
|
||
|
|
if (!newContents.includes('JCoreModule registerDeviceToken')) {
|
||
|
|
newContents = newContents.replace(
|
||
|
|
/@end\s*$/,
|
||
|
|
`${jpushMethods}\n@end\n`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
config.modResults.contents = newContents;
|
||
|
|
}
|
||
|
|
|
||
|
|
return config;
|
||
|
|
});
|
||
|
|
|
||
|
|
// 4. iOS: Add required capabilities and permissions to Info.plist
|
||
|
|
config = withInfoPlist(config, (config) => {
|
||
|
|
config.modResults.UIBackgroundModes = config.modResults.UIBackgroundModes || [];
|
||
|
|
if (!config.modResults.UIBackgroundModes.includes('remote-notification')) {
|
||
|
|
config.modResults.UIBackgroundModes.push('remote-notification');
|
||
|
|
}
|
||
|
|
|
||
|
|
return config;
|
||
|
|
});
|
||
|
|
|
||
|
|
return config;
|
||
|
|
};
|
||
|
|
|
||
|
|
module.exports = withJPush;
|