ReactNative 之 NSNotificationCenter 系统通知

本文主要以 ReactNative IOS 端为演示;以下为正文。

安装

npm install @react-native-community/push-notification-ios --save 

# pod install
cd ios && pod install && cd ../

IOS配置

在工程里面找到 AppDekegate.h,在头部引入下面依赖。

#import <RCTAppDelegate.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UNUserNotificationCenter.h> // add line

// add UNUserNotificationCenterDelegate
@interface AppDelegate : RCTAppDelegate <UNUserNotificationCenterDelegate>

@end

同样,在 AppDekegate.mm 里面添加如下代码。

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTRootView.h>
#import <React/RCTBundleURLProvider.h>
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"timememory";
  // 定义通知实例 UNUserNotificationCenter
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  // You can add your custom initial props in the dictionary below.
  // They will be passed down to the ViewController used by React Native.
  self.initialProps = @{};

  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

// 新架构使用了JavaScript Instanface(JSI)设计,Fabric 替代之前的 UI Manager 渲染系统
// UI Manager 是绘制元素位置,用于渲染。在Android里面就是viewGroup, Ios里面就是 UIView
// 新架构的 JSI 可以直接调用 Native/UI Thread, JSI 支持其他引擎渲染、例如 V8
// JSI 直接通讯 Native 省略了,之前异步调用过程
// 在 JSI 里 Native 方法会通过 C++ Host Objects 暴露给 JS, 而 JS 可以持有对这些对象的引用,并且使用这些引用直接调用对应的方法。

// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
 [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}

// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
 [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}

// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
}

// 注入前台通知 Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(nonnull UNNotification *)notification withCompletionHandler:(nonnull void (^)(UNNotificationPresentationOptions))completionHandler {
  completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [[NSBundle mainBundle] URLForResource:@"bundle/main" withExtension:@"jsbundle"];
#endif
}

/// 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` feature is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
  return true;
}

@end

项目中使用


useEffect(() => {
	const type: "notification" | "localNotification" = 'notification'
  PushNotificationIOS.addEventListener(type, onRemoteNotification)
  return () => {
    PushNotificationIOS.removeEventListener(type)
  }
}, [])


const onRemoteNotification = () => {
 	const isChecked = notification.getData().userInteraction === 1;
  if (isChecked) {
    console.log('isChecked', isChecked)
  } else {
  	// TODO
  }
  const result = PushNotificationIOS.FetchResult.NoData;
  notification.finish(result)
}

示例

推送一条通知消息。

const setNotificationCategories = () => {
  PushNotificationIOS.setNotificationCategories([
    {
      id: 'userAction',
      actions: [
        { id: 'open', title: '消息通知', options: { foreground: true }},
        { id: 'ignore', title: 'Desruptive', options: { foreground: true, destructive: true }},
        {
          id: 'text',
          title: 'Text Input',
          options: { foreground: true },
          textInput: { buttonTitle: 'Send' }
        }
      ]
    }
  ])
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执念1012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值