iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
0
Modern Web

我不用Expo啦,React Native!系列 第 23

[Day23] 提醒功能-5:被遺忘的iOS

關鍵字:notification


點擊通知時重新導向未成功

延續昨天
Day16~19時有試著做了一個點擊通知後可以跳轉回細節頁面的功能
可是在以實機測試時,這個功能是卻沒有用了
試了不同的模擬機後有著以下結論

  1. Android7:OK
  2. Android9:無效
  3. iOS:無效

這時想到了兩種寫法

  • A(原本的)
navigation.navigate('Home', {
  screen: 'AnimeDetail',
  params: { anime: notification.anime }
})
  • B
navigation.navigate('Home')
navigation.navigate('AnimeDetail', {
    anime: notification.anime
})

試了一下

  1. Android7:A OK, B 無效
  2. Android9:A 無效, B OK
  3. iOS:無效

以後android就改用B寫法

被遺忘的iOS

但iOS問題依舊
因為最近主要使用android模擬機觀看狀況,iOS被晾在一邊
仔細一看,iOS並非重新導向失敗
而是onNotification事件本身根本沒被觸發

正當我沒什麼頭緒,在google東看西看時
看到了這篇文
底下的這篇
https://ithelp.ithome.com.tw/upload/images/20200923/20121828C7TheIffqI.png

雖然沒有直接關係,但讓我突然想到了react-native-push-notification中的一段話


NOTE: If you target iOS you also need to follow the installation instructions for PushNotificationIOS since this package depends on it.


前幾天的我沒有仔細看,就只有安裝而已,也沒點進去看步驟
會不會是有東西我沒有設定到/images/emoticon/emoticon04.gif

打開ios/專案名

AppDelegate.h

#import <UserNotifications/UNUserNotificationCenter.h> // add

@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate> // add UNUserNotificationCenterDelegate

AppDelegate.m

先在上面增加

#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

並把下面這坨貼上

// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
 [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// 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];
}
// IOS 10+ Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
  completionHandler();
}
// IOS 4-10 Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
 [RNCPushNotificationIOS didReceiveLocalNotification:notification];
}

並修改以下內容

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  ...
  // Define UNUserNotificationCenter
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self;

  return YES;
}

// Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}

原來從第一天開始我就沒設定好...
順帶一提,再測試上面的A,B兩個方法後

  1. Android7:A OK, B 無效
  2. Android9:A 無效, B OK
  3. iOS:A OK, B 無效

也就是目前來說需要針對平台來設定不同的導向方法...總覺得怪怪的,列入issue裡看有沒有解決的方法吧


然後這裡又遇上一個問題

問題描述:如果從APP剛打開時,拉下通知欄點擊提醒後,不會有動作,如果進去我的最愛頁面後再點擊通知又可以重新導向

這是首頁
https://ithelp.ithome.com.tw/upload/images/20200923/20121828tLTa5bz3AW.png
這是我的最愛
https://ithelp.ithome.com.tw/upload/images/20200923/20121828YA8HSIPvbl.png
然後現在我把提醒的功能寫在鈴鐺按鈕中

所以原因其實是為了不讓App.tsx內太混亂
我將NotifService的實例於提醒的鈴鐺按鈕內生成
但是首頁並沒有鈴鐺按鈕被渲染,導致NotifService的實例無法生成
裡面的重新導向當然也無法運作
(範例的NotifService的實例於最頂層的App.js生成)

由於重新導向需要使用useNavigation這個hook
hook只能在function component或是hook內使用
這裡只好來自己寫一個hook了(官方:Building Your Own Hooks

import { useState } from 'react'
import { Platform } from 'react-native'
import { useNavigation } from '@react-navigation/native'

import NotifService from '../notification/NotifService'

const useNotif = () => {
  const navigation = useNavigation()

  const handleNotification = (notification: any) => {
   ...
  }
  const onNotification = (notification: any) => {
    handleNotification(notification)
  }

  const notif = new NotifService(onRegister, onNotification)

  return notif
}

然後鈴鐺按鈕內的實例從自行生成改成import的方式

...
import useNotif from '../../hook/useNotif'

const NotificationButton = ({ anime }: NotificationButtonProps) => {
  const notif = useNotif()
  ...

最後在home screen找個地方生成實例

const HomeContent = () => {
  ...
  // generate NotifService Object
  useNotif()
  ...

這樣就解決首頁重新導向無效的問題了

最後把今天的雙平台的重新導向方式不同的問題加入issue
https://ithelp.ithome.com.tw/upload/images/20200923/20121828ANao38P4tL.png
緩慢上升中...


明天要來寫切換語言的功能

參考:


上一篇
[Day22] 實機測試
下一篇
[Day24] 語言切換-1:沒有萬能的許願機
系列文
我不用Expo啦,React Native!33

尚未有邦友留言

立即登入留言