jpush-react-native

安裝

  • 安裝,打開終端項目目錄下運行,安卓jpush-react-native jpush-react-native包,并自動添加依賴
npm install jpush-react-native --save
npm install jcore-react-native --save
react-native link
  • 自動配置
npm run configureJPush <yourAppKey> <yourModuleName>
//module name 指的是你 Android 項目中的模塊名字(對 iOS 沒有影響,不填寫的話默認值為 app,會影響到查找 AndroidManifest 問題,
//如果沒找到 AndroidManifest,則需要手動修改,參考下面的 AndroidManifest 配置相關說明)
//舉個例子:
npm run configureJPush d4ee2375846bc30fa51334f5 app

iOS

  • 手動配置檢查
  • 在 iOS 工程中如果找不到頭文件可能要在 TARGETS-> BUILD SETTINGS -> Search Paths -> Header Search Paths 添加如下如路徑
$(SRCROOT)/../node_modules/jpush-react-native/ios/RCTJPushModule/RCTJPushModule
  • 打開 iOS 工程,在 link 之后,RCTJPushModule.xcodeproj 工程會自動添加到 Libraries 目錄里面
  • 在 iOS 工程 target 的 Build Phases->Link Binary with Libraries 中加入如下庫
libz.tbd
CoreTelephony.framework
Security.framework
CFNetwork.framework
CoreFoundation.framework
SystemConfiguration.framework
Foundation.framework
UIKit.framework
UserNotifications.framework
libresolv.tbd
  • 添加原生代碼
  • 在 AppDelegate.h 文件中 導入頭文件
#import <RCTJPushModule.h>
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
  • 在 AppDelegate.h 文件中 填寫如下代碼,這里的的 appkey、channel、和 isProduction 填寫自己的
static NSString *appKey = @"";     //填寫appkey
static NSString *channel = @"";    //填寫channel   一般為nil
static BOOL isProduction = false;  //填寫isProdurion  平時測試時為false ,生產時填寫true
  • 在AppDelegate.m 的didFinishLaunchingWithOptions 方法里面添加如下代碼
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
 #ifdef NSFoundationVersionNumber_iOS_9_x_Max
    JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
     entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound;
     [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
#endif
} else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
    [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                      UIUserNotificationTypeSound |
                                                      UIUserNotificationTypeAlert)
                                          categories:nil];
  } else {
    [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                      UIRemoteNotificationTypeSound |
                                                      UIRemoteNotificationTypeAlert)
                                          categories:nil];
  }
  [JPUSHService setupWithOption:launchOptions appKey:appKey
                        channel:channel apsForProduction:isProduction];
}
  • 在AppDelegate.m 的didRegisterForRemoteNotificationsWithDeviceToken 方法中添加 [JPUSHService registerDeviceToken:deviceToken];如下所示
-(void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [JPUSHService registerDeviceToken:deviceToken];
}
  • 為了在收到推送點擊進入應用能夠獲取該條推送內容需要在 AppDelegate.m didReceiveRemoteNotification方法里面添加 [[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo]方法,注意:這里需要在兩個方法里面加一個是iOS7以前的一個是iOS7即以后的,如果AppDelegate.m 沒有這個兩個方法則直接復制這兩個方法,在 iOS10 的設備則可以使用JPush 提供的兩個方法;如下所示
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  // 取得 APNs 標準信息內容
  [[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
//iOS 7 Remote Notification
-(void)application:(UIApplication *)application didReceiveRemoteNotification:  (NSDictionary *)userInfo fetchCompletionHandler:(void (^)   (UIBackgroundFetchResult))completionHandler {
  [[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
}
// iOS 10 Support
-(void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
  // Required
  NSDictionary * userInfo = notification.request.content.userInfo;
  if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    [JPUSHService handleRemoteNotification:userInfo];
    [[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
  }
  completionHandler(UNNotificationPresentationOptionAlert); // 需要執行這個方法,選擇是否提醒用戶,有Badge、Sound、Alert三種類型可以選擇設置
}
// iOS 10 Support
-(void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
  // Required
  NSDictionary * userInfo = response.notification.request.content.userInfo;
  if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    [JPUSHService handleRemoteNotification:userInfo];
    [[NSNotificationCenter defaultCenter] postNotificationName:kJPFOpenNotification object:userInfo];
  }
  completionHandler();  // 系統要求執行這個方法
}
  • react-native 中的使用
  • 收到推送
this.JPushReceiveNotification = NativeAppEventEmitter.addListener( 'ReceiveNotification',(message) => {
console.log('收到推送的消息'+message)
});
  • 點擊推送
this.JPushReceiveNotification = NativeAppEventEmitter.addListener( 'OpenNotification',(message) => {
console.log('收到推送的消息'+message)
});
  • 常見問題
  • 收不到推送
    • 確保是在真機上測試,而不是在模擬器
    • 能夠獲取 deviceToken 但是收不到推送, 如果是使用 xcode 8,檢查 (Project -> Target -> Capabilities ) Push Notification 選項是否已經點開,如果沒有需要點開
    • 檢查證書配置,以及激光后臺上傳的p12證書
  • 收到一條推送,有多個ReceiveNotification
    • 保存當前消息的messageID,再次接收到的消息時進行比較,如果相同則直接return
  • 點擊推送喚起應用的時候 OpenNotification 不調用
    • 升級 jpush-react-native 到最新版本(舊版本還沒做緩存處理,新版本已修復)
  • 通知在前臺展示問題
    • iOS 10 開始允許通知在前臺展示這個地方在 Native 代碼中控制
// iOS 10 Support
-(void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
  // Required
  NSDictionary * userInfo = notification.request.content.userInfo;
  if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    [JPUSHService handleRemoteNotification:userInfo];
    [[NSNotificationCenter defaultCenter] postNotificationName:kJPFDidReceiveRemoteNotification object:userInfo];
  }
completionHandler(UNNotificationPresentationOptionAlert);  // 需要執行這個方法,選擇是否提醒用戶,有Badge、Sound、Alert三種類型可以選擇設置
}
  • iOS 10 之前是系統控制,應用在前臺推送不展示
  • 找不到頭文件 RCTJPushModule.h
    • 在 iOS 工程中如果找不到頭文件可能要在 TARGETS-> BUILD SETTINGS -> Search Paths -> Header Search Paths 添加如下如路徑
$(SRCROOT)/../node_modules/jpush-react-native/ios/RCTJPushModule/RCTJPushModule
  • 在 iphone 5 的模擬器編譯不通過
    • JPush SDK 在 3.0.0 及以后版本不再支持 i386 的模擬器了血藥在 iphone 5s 以上版本中測試

安卓

  • 檢查配置
  • app/build.gradle
android {
    ...
    defaultConfig {
        applicationId "com.pushdemo" // 此處改成你在極光官網上申請應用時填寫的包名
        ...
        manifestPlaceholders = [
                JPUSH_APPKEY: "d4ee2375846bc30fa51334f5",   //在此替換你的APPKey
                APP_CHANNEL: "developer-default"        //應用渠道號
        ]
    }
}
dependencies {
    ...
    compile project(':jpush-react-native')
    compile project(':jcore-react-native')
    ...
}
  • settings.gradle
include ':app', ':jpush-react-native', ':jcore-react-native'
project(':jpush-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/jpush-react-native/android')
project(':jcore-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/jcore-react-native/android')
  • 添加原生代碼
  • app/src.../MainApplication.java MainApplication.java 文件,加入 JPushPackage
private boolean SHUTDOWN_TOAST = false;
    private boolean SHUTDOWN_LOG = false;

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {

        @Override
        protected boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }
        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage(),
                    //加入 JPushPackage
                    new JPushPackage(SHUTDOWN_TOAST, SHUTDOWN_LOG)
            );
        }
    };
  • app/src.../MainActivity.java MainActivity 中加入一些初始化代碼即可:
public class MainActivity extends ReactActivity {    
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        JPushInterface.init(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        JPushInterface.onPause(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        JPushInterface.onResume(this);
    }
}
  • react-native 中的使用
  • 收到推送
...
import JPushModule from 'jpush-react-native';
...
export default class PushActivity extends React.Component {
    componentDidMount() {
        JPushModule.addReceiveNotificationListener((map) => {
            console.log("alertContent: " + map.alertContent);
            console.log("extras: " + map.extras);
            // var extra = JSON.parse(map.extras);
            // console.log(extra.key + ": " + extra.value);
        });
}
  • 點擊推送
componentDidMount() {
    JPushModule.addReceiveOpenNotificationListener((map) => {
            console.log("Opening notification!");
            console.log("map.extra: " + map.key);
        });
}
  • 清除通知
componentWillUnmount() {
        JPushModule.removeReceiveCustomMsgListener();
        JPushModule.removeReceiveNotificationListener();
    }
  • 常見問題
    • 集成極光推送后遇到兩次點擊物理返回建退出程序,再次進入物理返回鍵監聽失效,網上有種說法是源碼的bug,是錯誤的。是因為我們在組件卸載的時候調用了NativeAppEventEmitter.removeAllListeners();
      DeviceEventEmitter.removeAllListeners();導致的,所以清楚通知的時候改成如下寫法就可以解決
componentWillUnmount() {
        JPushModule.removeReceiveCustomMsgListener();
        JPushModule.removeReceiveNotificationListener();
        if(Platform.OS === 'ios'){
            NativeAppEventEmitter.removeAllListeners(); //移除所有通知事件監聽
            DeviceEventEmitter.removeAllListeners();
        }

    }
  • 在安卓上,toast打印日志,需要我們手動注釋掉源碼中/node_modules/jpush-react-native/android/src/main/java/cn/jpush/reactnativejpush/JPushModule.java的打印Log打印
  • 程序退到后臺的時候(并沒有殺死)點擊通知消息并沒有跳轉到指定頁面,而是重新啟動了程序。


    WechatIMG143.png
  • JPushModule.java中這段代碼是 點擊通知欄的推送消息,如果程序在后臺運行中,殺死程序,啟動一個新的頁面。這需要刪掉Intent.FLAG_ACTIVITY_CLEAR_TOP,就可以直接喚起程序進行跳轉

JS方法

/**
     * Android only
     * 初始化JPush 必須先初始化才能執行其他操作
     */
    static initPush() {
        JPushModule.initPush();
    }

    /**
     * Android
     * 關閉推送
     */
    static stopPush() {
        JPushModule.stopPush();
    }

    /**
     * Android
     * 重新接受推送
     */
    static resumePush() {
        JPushModule.resumePush();
    }

    /**
     * Android
     * 清除所有推送
     */
    static clearAllNotifications() {
        JPushModule.clearAllNotifications();
    }

    /**
     * Android
     * 清除指定的推送消息
     */
    static clearNotificationById(id) {
        JPushModule.clearNotificationById(id);
    }

    /**
     * Android
     */
    static getInfo(cb) {
        JPushModule.getInfo((map) => {
            cb(map);
        });
    }

    /**
     * 通用
     *設置標簽
     */
    static setTags(tag, success, fail) {
        JPushModule.setTags(tag, (resultCode) => {

            if (resultCode === 0) {
                console.log('success');
                success();
            } else {
                console.log('fail');
                fail();
            }
        });
    }
    /**
     * 通用
     * 設置別名
     */
    static setAlias(alias, success, fail) {
        JPushModule.setAlias(alias, (resultCode) => {
            if (resultCode === 0) {
                success();
            } else {
                fail();
            }
        });
    }

    /**
     * Android
     */
    static setStyleBasic() {
        JPushModule.setStyleBasic();
    }

    /**
     * Android
     */
    static setStyleCustom() {
        JPushModule.setStyleCustom();
    }

    /**
     * Android
     * 添加自定義消息監聽
     */
    static addReceiveCustomMsgListener(cb) {
        listeners[cb] = DeviceEventEmitter.addListener(receiveCustomMsgEvent,
            (message) => {
                cb(message);
            });
    }

    /**
     * Android
     * 清除自定義消息監聽
     */
    static removeReceiveCustomMsgListener(cb) {
        if (!listeners[cb]) {
            return;
        }
        listeners[cb].remove();
        listeners[cb] = null;
    }

    /**
     * Android
     * 添加收到消息監聽
     */
    static addReceiveNotificationListener(cb) {
        listeners[cb] = DeviceEventEmitter.addListener(receiveNotificationEvent,
            (map) => {
                cb(map);
            });
    }

    /**
     * Android
     * 移除收到消息監聽
     */
    static removeReceiveNotificationListener(cb) {
        if (!listeners[cb]) {
            return;
        }
        listeners[cb].remove();
        listeners[cb] = null;
    }

    /**
     * Android
     * 添加點擊消息時的監聽
     */
    static addReceiveOpenNotificationListener(cb) {
        listeners[cb] = DeviceEventEmitter.addListener(openNotificationEvent,
            (message) => {
                cb(message);
            });
    }

    /**
     * Android
     * 移除點擊時消息監聽
     */
    static removeReceiveOpenNotificationListener(cb) {
        if (!listeners[cb]) {
            return;
        }
        listeners[cb].remove();
        listeners[cb] = null;
    }

    /**
     * Android
     * If device register succeed, the server will return registrationId
     */
    static addGetRegistrationIdListener(cb) {
        listeners[cb] = DeviceEventEmitter.addListener(getRegistrationIdEvent,
            (registrationId) => {
                cb(registrationId);
            });
    }

    static removeGetRegistrationIdListener(cb) {
        if (!listeners[cb]) {
            return;
        }
        listeners[cb].remove();
        listeners[cb] = null;
    }

    /**
     * iOS,  Android    
     */
    static getRegistrationID(cb) {
        JPushModule.getRegistrationID((id) => {
            cb(id);
        });
    }

    /**
     * iOS
     */
    static setupPush() {
        JPushModule.setupPush();
    }

    /**
     * iOS
     * 獲取appkey的回調
     */
    static getAppkeyWithcallback(cb) {
        JPushModule.getAppkeyWithcallback((appkey) => {
            cb(appkey);
        });
    }


    /**
     * iOS
     */
    static setLocalNotification(date, textContain, badge, alertAction, notificationKey, userInfo, soundName) {
        JPushModule.setLocalNotification(date, textContain, badge, alertAction, notificationKey, userInfo, soundName);
    }

    /**
     * iOS
     * 設置角標消息個數
     */
    static setBadge(badge, cb) {
        JPushModule.setBadge(badge, (value) => {
            cb(value);
        });
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容