refactor(plugins): update JPush config and improve SmartImage loading
- Update `withJPush` plugin to support Expo SDK 56+ by using `JPUSHService.setup` instead of `JCoreModule.setup` and adding `UNUserNotificationCenterDelegate` conformance. - Improve `SmartImage` component by adding a ref to prevent loading state flickering when transitioning from preview to original image. - Upgrade `@shopify/flash-list` dependency. - Add transition prop to `SmartImage` for smoother image loading.
This commit is contained in:
@@ -95,7 +95,7 @@ const withJPush = (config, options = {}) => {
|
||||
config = withAppDelegate(config, (config) => {
|
||||
const { contents } = config.modResults;
|
||||
|
||||
if (contents.includes('JPush') || contents.includes('JCoreModule')) {
|
||||
if (contents.includes('JPush initialization') && contents.includes('JPUSHService.registerDeviceToken')) {
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,8 @@ const withJPush = (config, options = {}) => {
|
||||
if (isSwift) {
|
||||
let newContents = contents;
|
||||
|
||||
if (!newContents.includes('import JPushRN')) {
|
||||
// Add UNUserNotifications import if needed
|
||||
if (!newContents.includes('import UserNotifications')) {
|
||||
if (newContents.includes('import UIKit')) {
|
||||
newContents = newContents.replace(
|
||||
/(import UIKit\n)/,
|
||||
@@ -118,56 +119,62 @@ const withJPush = (config, options = {}) => {
|
||||
}
|
||||
}
|
||||
|
||||
// Swift: Add JPush init in application(_:didFinishLaunchingWithOptions:)
|
||||
// Match various Swift signatures
|
||||
const swiftDidFinishPatterns = [
|
||||
/public override func application\(\s*_ application: UIApplication,\s*didFinishLaunchingWithOptions launchOptions: \[UIApplication\.LaunchOptionsKey: Any\]\? = nil\s*\) -> Bool \{/,
|
||||
/func application\(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: \[UIApplication\.LaunchOptionsKey: Any\]\?\?\) -> Bool \{/,
|
||||
];
|
||||
|
||||
let didInsertInit = false;
|
||||
for (const pattern of swiftDidFinishPatterns) {
|
||||
if (pattern.test(newContents)) {
|
||||
newContents = newContents.replace(
|
||||
pattern,
|
||||
`$&\n // JPush initialization\n #if DEBUG\n JCoreModule.setup(withOption: launchOptions, appKey: "${appKey}", channel: "${channel}", apsForProduction: false)\n #else\n JCoreModule.setup(withOption: launchOptions, appKey: "${appKey}", channel: "${channel}", apsForProduction: true)\n #endif`
|
||||
);
|
||||
didInsertInit = true;
|
||||
break;
|
||||
}
|
||||
// Add UNUserNotificationCenterDelegate conformance if needed
|
||||
if (!newContents.includes('UNUserNotificationCenterDelegate')) {
|
||||
newContents = newContents.replace(
|
||||
/class AppDelegate: ExpoAppDelegate \{/,
|
||||
'class AppDelegate: ExpoAppDelegate, UNUserNotificationCenterDelegate {'
|
||||
);
|
||||
}
|
||||
|
||||
// Fallback: find the didFinishLaunchingWithOptions method start and insert after the opening brace
|
||||
if (!didInsertInit && newContents.includes('didFinishLaunchingWithOptions')) {
|
||||
const lines = newContents.split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].includes('didFinishLaunchingWithOptions') && lines[i].includes('{')) {
|
||||
lines.splice(i + 1, 0,
|
||||
' // JPush initialization',
|
||||
' #if DEBUG',
|
||||
` JPUSHService.setup(withOption: launchOptions, appKey: "${appKey}", channel: "${channel}", apsForProduction: false)`,
|
||||
' #else',
|
||||
` JPUSHService.setup(withOption: launchOptions, appKey: "${appKey}", channel: "${channel}", apsForProduction: true)`,
|
||||
' #endif',
|
||||
' UNUserNotificationCenter.current().delegate = self'
|
||||
);
|
||||
newContents = lines.join('\n');
|
||||
didInsertInit = true;
|
||||
break;
|
||||
// Swift: Add JPush init in application(_:didFinishLaunchingWithOptions:)
|
||||
// Expo SDK 56+ uses JPUSHService.setup (not JCoreModule.setup)
|
||||
if (!newContents.includes('JPUSHService.setup') && !newContents.includes('JCoreModule.setup')) {
|
||||
const jpushInitBlock = `
|
||||
// JPush initialization
|
||||
#if DEBUG
|
||||
JPUSHService.setup(withOption: launchOptions, appKey: "${appKey}", channel: "${channel}", apsForProduction: false)
|
||||
#else
|
||||
JPUSHService.setup(withOption: launchOptions, appKey: "${appKey}", channel: "${channel}", apsForProduction: true)
|
||||
#endif
|
||||
UNUserNotificationCenter.current().delegate = self`;
|
||||
|
||||
// Insert after the opening brace of didFinishLaunchingWithOptions
|
||||
// The { may be on the same line as didFinishLaunchingWithOptions or on a subsequent line
|
||||
if (newContents.includes('didFinishLaunchingWithOptions')) {
|
||||
const lines = newContents.split('\n');
|
||||
let foundDidFinish = false;
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].includes('didFinishLaunchingWithOptions')) {
|
||||
foundDidFinish = true;
|
||||
}
|
||||
// Insert after the line that contains the opening brace of this method
|
||||
if (foundDidFinish && lines[i].includes('{')) {
|
||||
const indent = lines[i].match(/^(\s*)/)[1];
|
||||
const initLines = jpushInitBlock.split('\n').map(l => l ? indent + l.trimStart() : l);
|
||||
lines.splice(i + 1, 0, ...initLines);
|
||||
newContents = lines.join('\n');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (newContents.includes('JCoreModule.setup') && !newContents.includes('JPUSHService.setup')) {
|
||||
// Migrate from JCoreModule.setup to JPUSHService.setup
|
||||
newContents = newContents.replace(/JCoreModule\.setup/g, 'JPUSHService.setup');
|
||||
}
|
||||
|
||||
// Also add delegate = self after regex-based insertion if not already present
|
||||
if (didInsertInit && !newContents.includes('UNUserNotificationCenter.current().delegate')) {
|
||||
// Add delegate = self after init insertion if not present
|
||||
if (!newContents.includes('UNUserNotificationCenter.current().delegate')) {
|
||||
newContents = newContents.replace(
|
||||
/(#endif\n)(\s+let delegate)/,
|
||||
`$1 UNUserNotificationCenter.current().delegate = self\n$2`
|
||||
);
|
||||
}
|
||||
|
||||
// Swift: Add delegate methods before the closing brace of the class
|
||||
// Swift: Add JPush notification delegate methods to AppDelegate class (before closing brace)
|
||||
// These go in AppDelegate, NOT ReactNativeDelegate
|
||||
const jpushSwiftMethods = `
|
||||
|
||||
// JPush: Register for remote notifications
|
||||
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
||||
JPUSHService.registerDeviceToken(deviceToken)
|
||||
@@ -195,10 +202,20 @@ const withJPush = (config, options = {}) => {
|
||||
`;
|
||||
|
||||
if (!newContents.includes('JPUSHService.registerDeviceToken')) {
|
||||
// Find the closing brace of the AppDelegate class
|
||||
const lastBraceIndex = newContents.lastIndexOf('}');
|
||||
if (lastBraceIndex !== -1) {
|
||||
newContents = newContents.slice(0, lastBraceIndex) + jpushSwiftMethods + '\n' + newContents.slice(lastBraceIndex);
|
||||
// Insert before the closing brace of the AppDelegate class
|
||||
// Find the last '}' that closes the AppDelegate class (before ReactNativeDelegate)
|
||||
const classEndPattern = /\n\}\n\nclass ReactNativeDelegate/;
|
||||
if (classEndPattern.test(newContents)) {
|
||||
newContents = newContents.replace(
|
||||
classEndPattern,
|
||||
`${jpushSwiftMethods}}\n\nclass ReactNativeDelegate`
|
||||
);
|
||||
} else {
|
||||
// Fallback: insert before the last closing brace
|
||||
const lastBraceIndex = newContents.lastIndexOf('}');
|
||||
if (lastBraceIndex !== -1) {
|
||||
newContents = newContents.slice(0, lastBraceIndex) + jpushSwiftMethods + '\n' + newContents.slice(lastBraceIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user