#import "AppDelegate.h" #import #import #import #import //#import #if RCT_NEW_ARCH_ENABLED #import #import #import #import #import #import #import static NSString *const kRNConcurrentRoot = @"concurrentRoot"; @interface AppDelegate () { RCTTurboModuleManager *_turboModuleManager; RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; std::shared_ptr _reactNativeConfig; facebook::react::ContextContainer::Shared _contextContainer; } @end #endif @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenNotificationSettingsURLString]]; // NSString *url = UIApplicationOpenNotificationSettingsURLString; // APNS self.rnLoaded = NO; NSDate *date = [NSDate date]; //zone为当前时区信息 在我的程序中打印的是@"Asia/Shanghai" NSTimeZone *zone = [NSTimeZone systemTimeZone]; //所在地区时间与协调世界时差距 NSInteger interval = [zone secondsFromGMTForDate: date]; //加上时差,得到本地时间 NSDate *localeDate = [date dateByAddingTimeInterval: interval]; // JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init]; // if (@available(iOS 12.0, *)) { // entity.types = JPAuthorizationOptionNone; //JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSou//nd|JPAuthorizationOptionProvidesAppNotificationSettings; // } // [JPUSHService registerForRemoteNotificationConfig:entity delegate:self]; RCTAppSetupPrepareApp(application); RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions]; UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; #if RCT_NEW_ARCH_ENABLED _contextContainer = std::make_shared(); _reactNativeConfig = std::make_shared(); _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer]; bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; #endif NSDictionary *initProps = [self prepareInitialProps]; UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"taroDemo" initialProperties:initProps]; if (@available(iOS 13.0, *)) { rootView.backgroundColor = [UIColor systemBackgroundColor]; } else { rootView.backgroundColor = [UIColor blackColor]; } self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor = [UIColor blackColor]; UIViewController *rootViewController = [self.reactDelegate createRootViewController]; rootViewController.view = rootView; rootViewController.view.backgroundColor = [UIColor blackColor]; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; [super application:application didFinishLaunchingWithOptions:launchOptions]; // NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; // [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; // NSDate *date1 = [dateFormatter dateFromString:@"2024-05-30 22:00:00"]; // [self scheduleCalendarNotificationWithTitle:@"你好" body:@"推送" date:date1 repeats:YES identifier:@"push1"]; // [self demo]; // [self registerForPushNotifications]; [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(timerFired:) userInfo:nil repeats:NO]; [self clearAllDeliveredNotifications]; return YES; } - (void)timerFired:(NSTimer *)timer { // 定时器触发后执行的代码 NSLog(@"Timer fired!"); // [self.nativeBridge.bridge.eventDispatcher sendAppEventWithName:@"notificationReceive" body:@{ // @"title":@"hello", // @"value":@"world" // }]; } - (void)registerForPushNotifications { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (granted) { dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] registerForRemoteNotifications]; }); } else { // 用户拒绝通知或发生错误 } }]; } /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. /// /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture). /// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`. - (BOOL)concurrentRootEnabled { // Switch this bool to turn on and off the concurrent root return true; } - (NSDictionary *)prepareInitialProps { NSMutableDictionary *initProps = [NSMutableDictionary new]; #ifdef RCT_NEW_ARCH_ENABLED initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); #endif return initProps; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { // return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } #if RCT_NEW_ARCH_ENABLED #pragma mark - RCTCxxBridgeDelegate - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge { _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self jsInvoker:bridge.jsCallInvoker]; return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); } #pragma mark RCTTurboModuleManagerDelegate - (Class)getModuleClassFromName:(const char *)name { return RCTCoreModulesClassProvider(name); } - (std::shared_ptr)getTurboModule:(const std::string &)name jsInvoker:(std::shared_ptr)jsInvoker { return nullptr; } - (std::shared_ptr)getTurboModule:(const std::string &)name initParams: (const facebook::react::ObjCTurboModule::InitParams &)params { return nullptr; } - (id)getModuleInstanceFromClass:(Class)moduleClass { return RCTAppSetupDefaultModuleFromClass(moduleClass); } #endif //************************************************JPush start************************************************ //注册 APNS 成功并上报 DeviceToken - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // [JPUSHService registerDeviceToken:deviceToken]; } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{ NSLog(@"get notification error"); } //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); } - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler { if ([response.actionIdentifier isEqualToString:@"action1"]) { // 处理"动作1" } else if ([response.actionIdentifier isEqualToString:@"action2"]) { // 处理"动作2" } completionHandler(); } //再实现UNUserNotificationCenterDelegate代理的方法 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { //应用在前台时候接收到本地推送通知、远程推送通知调用此方法 } - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler { //应用程序在后台,用户通过点击本地推送、远程推送进入app时调用此方法 } //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]; } self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(postNotificationData:) userInfo:response repeats:YES]; // NSString *categoryIdentifier = response.notification.request.content.categoryIdentifier; // [self.nativeBridge.bridge.eventDispatcher sendAppEventWithName:@"notificationReceive" body:@{@"category_id":categoryIdentifier,@"action_id":response.actionIdentifier}]; // 处理用户交互 // if ([response.actionIdentifier isEqualToString:@"ALLOW_ACTION"]) { // // 用户点击了"允许"按钮,发起网络请求 // NSLog(@"User allow the request"); // //// [self.nativeBridge.bridge.eventDispatcher sendAppEventWithName:@"notificationReceive" body:@{@"name":@"1",@"value":@"2"}]; // //// [self makeNetworkRequest]; // } else if ([response.actionIdentifier isEqualToString:@"DENY_ACTION"]) { // // 用户点击了"拒绝"按钮 // NSLog(@"User denied the request"); //// [self makeNetworkRequest]; // } else if ([response.actionIdentifier isEqualToString:@"START_TIMER_NOW"]){ // if ([categoryIdentifier isEqualToString:@"REMINDER_FS_START_FAST"]){ // // } // else if ([categoryIdentifier isEqualToString:@"REMINDER_FS_START_SLEEP"]){ // // } // } else if ([response.actionIdentifier isEqualToString:@"PICK_EARLIER_START"]){ // if ([categoryIdentifier isEqualToString:@"REMINDER_FS_START_FAST"]){ // // } // else if ([categoryIdentifier isEqualToString:@"REMINDER_FS_START_SLEEP"]){ // // } // } // else if ([response.actionIdentifier isEqualToString:@"END_TIMER_NOW"]){ // // } // else if ([response.actionIdentifier isEqualToString:@"PICK_EARLIER_END"]){ // // } // else if ([response.actionIdentifier isEqualToString:@"SKIP"]){ // // } // 系统要求执行这个方法 completionHandler(); } - (void)postNotificationData:(NSTimer *)timerInfo{ if (self.rnLoaded){ UNNotificationResponse *response = timerInfo.userInfo; [self.timer invalidate]; self.timer = nil; NSString *categoryIdentifier = response.notification.request.content.categoryIdentifier; NSString *identifier = response.notification.request.identifier; [self.nativeBridge.bridge.eventDispatcher sendAppEventWithName:@"notificationReceive" body:@{@"category_id":categoryIdentifier,@"action_id":response.actionIdentifier,@"id":identifier}]; [self clearAllDeliveredNotifications]; } else { } } - (void)makeNetworkRequest{ //https://api.fast.dev.liveplus.fun/api/static-resource-urls NSURL *url = [NSURL URLWithString:@"https://api.fast.dev.liveplus.fun/api/static-resource-urls"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { NSLog(@"Error: %@", error.localizedDescription); } else { // 处理返回的数据 NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSLog(@"Response: %@", json); } }]; [dataTask resume]; } //自定义消息 - (void)networkDidReceiveMessage:(NSNotification *)notification { NSDictionary * userInfo = [notification userInfo]; // [[NSNotificationCenter defaultCenter] postNotificationName:J_CUSTOM_NOTIFICATION_EVENT object:userInfo]; } - (void)demo{ // 1. 设置 notification 内容 UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.title = @"Daily Reminder"; content.body = @"It's 9:00 AM, time to start your day!"; content.sound = [UNNotificationSound defaultSound]; // 2. 设置触发条件 - 每天 9:00 AM NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; dateComponents.hour = 9; dateComponents.minute = 0; UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:dateComponents repeats:YES]; // 3. 创建 notification request UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"DailyReminder" content:content trigger:trigger]; // 4. 添加 notification request 到通知中心 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if (error != nil) { NSLog(@"Error adding notification request: %@", error); } }]; } - (void)scheduleCalendarNotificationWithTitle:(NSString *)title body:(NSString *)body date:(NSDate *)date repeats:(BOOL)repeats identifier:(NSString *)identifier { NSLog(@"%s", __FUNCTION__); UNMutableNotificationContent *content = [UNMutableNotificationContent new]; content.title = title; content.body = body; NSCalendar *calendar = NSCalendar.currentCalendar; NSDateComponents *components = [calendar components:(NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:date]; UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:repeats]; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger]; [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if (error) { NSLog(@"%@", error); } }]; } - (void)clearAllDeliveredNotifications { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center removeAllDeliveredNotifications]; } @end