一、原因
ios18下不允许使用openUrl,微信ios sdk需要更新到2.0.4解决此问题。
而"jshare-react-native": "1.4.2"
或 "react-native-wechat-lib": "1.1.26",
都还没有解决分享到微信的问题。
二、解决方法
在ios的runtime运行时,将所有的openUrl替换成open,则解决react-native-wechat-lib
的分享问题。
注意没有解决jshare-react-native
的分享问题(因为jshare他也写了一个runtime替换openUrl,我得先删除这个)。
1、在ios下编辑AppDelegate.m
文件
添加以下头文件,注意靠前面一些引入
,否则会报错
// 导入 Runtime 头文件
#import <objc/runtime.h>
2、在下面方法的最前面
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// ⚠️ 首先进行方法交换!放在最前面!
[AppDelegate hookOldOpenUrl:AppDelegate.class];
在@end 之前添加
// 你提供的替换方法
- (BOOL)g_openURL:(NSURL*)url{
// 使用新的 API,并添加 completionHandler
[UIApplication.sharedApplication openURL:url options:@{} completionHandler:nil];
return YES;
}
// 你提供的交换方法
+ (void)hookOldOpenUrl:(Class)targetCls{
Class cls = [UIApplication class];
if (cls) {
Method originalMethod = class_getInstanceMethod(cls, @selector(openURL:));
Method swizzledMethod = class_getInstanceMethod(targetCls, @selector(g_openURL:));
if (!originalMethod || !swizzledMethod) {
return;
}
IMP originalIMP = method_getImplementation(originalMethod);
IMP swizzledIMP = method_getImplementation(swizzledMethod);
const char *originalType = method_getTypeEncoding(originalMethod);
const char *swizzledType = method_getTypeEncoding(swizzledMethod);
// 核心交换操作
class_replaceMethod(cls, @selector(openURL:), swizzledIMP, swizzledType);
class_replaceMethod(cls, @selector(g_openURL:), originalIMP, originalType);
}
}
// ... 其他可能存在的 React Native 相关方法(如 deep linking 处理)保持不变
// 这些方法会在你交换后的 g_openURL: 中被调用
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [RCTLinkingManager application:application openURL:url options:options];
}
注意,openURL和JShare重复了
删除掉
// work in iOS(9_0,++)
// - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
// [JSHAREService handleOpenUrl:url];
// return YES;
// }
三、怕你们还搞不清楚,我直接全贴上来
#import "AppDelegate.h"
#import <RCTJPushModule.h>
#import <RCTJShareModule.h>
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
// 导入 Runtime 头文件
#import <objc/runtime.h>
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
static void InitializeFlipper(UIApplication *application) {
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
[client addPlugin:[FlipperKitReactPlugin new]];
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
[client start];
}
#endif
// #import "Orientation.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ⚠️ 首先进行方法交换!放在最前面!
[AppDelegate hookOldOpenUrl:AppDelegate.class];
#ifdef FB_SONARKIT_ENABLED
InitializeFlipper(application);
#endif
// *** 极光推送start ***
// APNS
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
if (@available(iOS 12.0, *)) {
entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound|JPAuthorizationOptionProvidesAppNotificationSettings;
}
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
[launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
// 自定义消息
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidReceiveMessageNotification object:nil];
// 地理围栏
[JPUSHService registerLbsGeofenceDelegate:self withLaunchOptions:launchOptions];
// *** 极光推送end ***
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"xxxxxxx"
initialProperties:nil];
if (@available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
rootView.backgroundColor = [UIColor whiteColor];
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
// 启动图片延时: 1秒
[NSThread sleepForTimeInterval:1];
return YES;
}
//************************************************JPush start************************************************
//注册 APNS 成功并上报 DeviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[JPUSHService registerDeviceToken:deviceToken];
}
//iOS 7 APNS
- (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// iOS 10 以下 Required
NSLog(@"iOS 7 APNS");
[JPUSHService handleRemoteNotification:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:J_APNS_NOTIFICATION_ARRIVED_EVENT object:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
//iOS 10 前台收到消息
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
NSDictionary * userInfo = notification.request.content.userInfo;
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
// Apns
NSLog(@"iOS 10 APNS 前台收到消息");
[JPUSHService handleRemoteNotification:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:J_APNS_NOTIFICATION_ARRIVED_EVENT object:userInfo];
}
else {
// 本地通知 todo
NSLog(@"iOS 10 本地通知 前台收到消息");
[[NSNotificationCenter defaultCenter] postNotificationName:J_LOCAL_NOTIFICATION_ARRIVED_EVENT object:userInfo];
}
//需要执行这个方法,选择是否提醒用户,有 Badge、Sound、Alert 三种类型可以选择设置
completionHandler(UNNotificationPresentationOptionAlert);
}
//iOS 10 消息事件回调
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler: (void (^)(void))completionHandler {
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
// Apns
NSLog(@"iOS 10 APNS 消息事件回调");
[JPUSHService handleRemoteNotification:userInfo];
// 保障应用被杀死状态下,用户点击推送消息,打开app后可以收到点击通知事件
[[RCTJPushEventQueue sharedInstance]._notificationQueue insertObject:userInfo atIndex:0];
[[NSNotificationCenter defaultCenter] postNotificationName:J_APNS_NOTIFICATION_OPENED_EVENT object:userInfo];
}
else {
// 本地通知
NSLog(@"iOS 10 本地通知 消息事件回调");
// 保障应用被杀死状态下,用户点击推送消息,打开app后可以收到点击通知事件
[[RCTJPushEventQueue sharedInstance]._localNotificationQueue insertObject:userInfo atIndex:0];
[[NSNotificationCenter defaultCenter] postNotificationName:J_LOCAL_NOTIFICATION_OPENED_EVENT object:userInfo];
}
// 系统要求执行这个方法
completionHandler();
}
//自定义消息
- (void)networkDidReceiveMessage:(NSNotification *)notification {
NSDictionary * userInfo = [notification userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:J_CUSTOM_NOTIFICATION_EVENT object:userInfo];
}
//************************************************JPush end************************************************
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [WXApi handleOpenURL:url delegate:self];
}
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable
restorableObjects))restorationHandler {
// 触发回调方法
[RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
return [WXApi handleOpenUniversalLink:userActivity
delegate:self];
}
// - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
// options:(NSDictionary<NSString*, id> *)options
// {
// // Triggers a callback event.
// // 触发回调事件
// [RCTLinkingManager application:application openURL:url options:options];
// return [WXApi handleOpenURL:url delegate:self];
// }
// work in iOS(9_0,++)
// - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
// [JSHAREService handleOpenUrl:url];
// return YES;
// }
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
//- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
// return [Orientation getOrientation];
// }
// 你提供的替换方法
- (BOOL)g_openURL:(NSURL*)url{
// 使用新的 API,并添加 completionHandler
[UIApplication.sharedApplication openURL:url options:@{} completionHandler:nil];
return YES;
}
// 你提供的交换方法
+ (void)hookOldOpenUrl:(Class)targetCls{
Class cls = [UIApplication class];
if (cls) {
Method originalMethod = class_getInstanceMethod(cls, @selector(openURL:));
Method swizzledMethod = class_getInstanceMethod(targetCls, @selector(g_openURL:));
if (!originalMethod || !swizzledMethod) {
return;
}
IMP originalIMP = method_getImplementation(originalMethod);
IMP swizzledIMP = method_getImplementation(swizzledMethod);
const char *originalType = method_getTypeEncoding(originalMethod);
const char *swizzledType = method_getTypeEncoding(swizzledMethod);
// 核心交换操作
class_replaceMethod(cls, @selector(openURL:), swizzledIMP, swizzledType);
class_replaceMethod(cls, @selector(g_openURL:), originalIMP, originalType);
}
}
// ... 其他可能存在的 React Native 相关方法(如 deep linking 处理)保持不变
// 这些方法会在你交换后的 g_openURL: 中被调用
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [RCTLinkingManager application:application openURL:url options:options];
}
@end