精华 Ionic 集成 jpush(极光推送)之 IOS 篇
发布于 2年前 作者 DongHongfei 31107 次浏览 来自 分享

Ionic 集成 jpush(极光)推送之 IOS 篇

极光推送官方版的 phonegap 插件在这里。 由于官方版插件 ios 版暂时没有打开通知的方法,所以在官方基础上修改了下,修改后的插件放在了这里,下面说明以修改后的插件为准。(感谢极光官方大神viper耐心帮助,同时也参考了下@lanceli大神的cnodejs-ionic项目)

极光账户设置部分可以参考小和尚的这篇分享。

下面主要说明项目代码部分修改。

新建一个 ionic项目

$ ionic start --id com.ionichina.ionicjpush ionic_jpush tabs

注:修改 id 为自己应用的 Bundle identifier

添加 IOS 平台

$ cd ionic_jpush
$ ionic platform add ios

安装插件

$ ionic plugin add https://github.com/DongHongfei/jpush-phonegap-plugin.git

等待时间比较长,你也可以像小和尚文章里介绍的先下载下来,再安装,但这个过程是跑不了的

(接下来,蛋疼的事情开始了)

修改配置

  • 修改: ionic_jpush\plugins\cn.jpush.phonegap.JPushPlugin\src\ios\PushConfig.plist 修改对应的APP_KEY和CHANNEL(渠道)

注意 确保有如下代码,不然后面 Xcode 运行会警告:

<key>APS_FOR_PRODUCTION</key>
<string>0</string>

在 js 中添加通知实现

  .factory('Push', function() {
    var push;
    return {
      setBadge: function(badge) {
        if (push) {
          console.log('jpush: set badge', badge);
          plugins.jPushPlugin.setBadge(badge);
        }
      },
      setAlias: function(alias) {
        if (push) {
          console.log('jpush: set alias', alias);
          plugins.jPushPlugin.setAlias(alias);
        }
      },
      check: function() {
        if (window.jpush && push) {
          plugins.jPushPlugin.receiveNotificationIniOSCallback(window.jpush);
          window.jpush = null;
        }
      },
      init: function(notificationCallback) {
        console.log('jpush: start init-----------------------');
        push = window.plugins && window.plugins.jPushPlugin;
        if (push) {
          console.log('jpush: init');
          plugins.jPushPlugin.init();
          plugins.jPushPlugin.setDebugMode(true);
          plugins.jPushPlugin.openNotificationInAndroidCallback = notificationCallback;
          plugins.jPushPlugin.receiveNotificationIniOSCallback = notificationCallback;
        }
      }
    };
  });

在 app.js 的 run 函数里定义通知回调函数

记得在 run 函数里引用 Push 先

  // push notification callback
  var notificationCallback = function(data) {
    console.log('received data :' + data);
    var notification = angular.fromJson(data);
    //app 是否处于正在运行状态
    var isActive = notification.notification;

    // here add your code


    //ios
    if (ionic.Platform.isIOS()) {
      window.alert(notification);

    } else {
    //非 ios(android)
    }
  };

在 $ionicPlatform.ready 里进行初始化

//初始化
Push.init(notificationCallback);
//设置别名
Push.setAlias("12345678");

编译 IOS 项目

$ ionic build ios

(接下来,更蛋疼的事情开始了)

修改配置 IOS 项目(不要问我为啥)

  • 修改 AppDelegate.m, 添加
#import "APService.h"
#import "JPushPlugin.h"  //viper

didFinishLaunchingWithOptions函数中添加


    // Required
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        //可以添加自定义categories
        [APService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                       UIUserNotificationTypeSound |
                                                       UIUserNotificationTypeAlert)
                                           categories:nil];
    } else {
        //categories 必须为nil
        [APService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                       UIRemoteNotificationTypeSound |
                                                       UIRemoteNotificationTypeAlert)
                                           categories:nil];
    }
#else
    //categories 必须为nil
    [APService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                   UIRemoteNotificationTypeSound |
                                                   UIRemoteNotificationTypeAlert)
                                       categories:nil];
#endif
    // Required
    [APService setupWithOption:launchOptions];

didRegisterForRemoteNotificationsWithDeviceToken中添加

// Required
[APService registerDeviceToken:deviceToken];
[APService setDebugMode];

添加函数

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    // Required
    [APService handleRemoteNotification:userInfo];
    BOOL isActive;
    if (application.applicationState == UIApplicationStateActive) {
        isActive = TRUE;
    } else {
        isActive = FALSE;
    }
    NSDictionary *dict=[[NSMutableDictionary alloc] initWithDictionary:userInfo];
    
    [dict setValue: [[NSNumber alloc] initWithBool:isActive] forKey:@"isActive" ];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:kJPushPlugReceiveNotificaiton
                                                        object:dict] ;//viper
    
    
}

OC 代码算是完事儿,然后就是配置

  • 修改项目 Capabilities,打开 Background Modes,勾选最后一项Remote notications
  • 设置证书,这个就不教了,网上一大堆
  • Xcode 这边就算配置完了

接下就是设置一些Xcode常规操作,编译运行,从极光官方控制台发送一条通知,然后查看Xcode控制台,应该就会有推送的通知数据打印了。 下面的事儿你自己应该搞的定。

示例代码我放在了这里

30 回复

收了备用 辛苦了~

Dong牛人, 感谢你的教程! 如久旱逢甘霖啊! 辛苦!

@pennsong 我擦,我只是个小学生而已啊~

Screen Shot 2015-04-15 at 10.46.29 PM.png Dong牛人, 如图所示, 蓝色部分的信息我在客户端如何用js得到啊, 请指教, 不胜感激!

@pennsong notificationCallback函数里的data就包含了推送过来的消息了,你可以本地跑起来,然后打印下日志具体看看就明白了

@DongHongfei 问题解决了, 是我误解了, 我声明了如下函数, 结果用了console.log来打信息, 还期望在xcode的console里看到信息, 其实应该是用safari里的console来看, 谢谢! window.plugins.jPushPlugin.receiveMessageIniOSCallback = function (data) { console.log(‘abc’); try { console.log("receiveMessageIniOSCallback " + data); } catch (exception) { console.log("receiveMessageIniOSCallback " + exception); } }

@DongHongfei 能帮上我的忙就是牛人

@DongHongfei 兄弟, 我刚刚发现Push.setAlias在你github: https://github.com/DongHongfei/jpush-phonegap-plugin.git上的插件中已经失效了, 我看了下https://github.com/jpush/jpush-phonegap-plugin上的15天前更新过, 不知道是不是这个是导致的原因, 我正在痛苦排查中, 你有线索请告知我下, 谢谢!

@DongHongfei 我换回了官方的https://github.com/jpush/jpush-phonegap-plugin, 可以正常setAlias了, 不过一个细节是: 我根据官方的readme, 做了cordova plugin add org.apache.cordova.device, 不知道是不是由于做了这个导致可以正常使用setAlias的, 仅供参考 不过官方文档中的如图高亮部分似乎不对, 这个函数是后来加上去的: Screen Shot 2015-05-01 at 12.11.07 AM.png

@pennsong org.apache.cordova.device应该默认就有的,官方最新版倒是没试过,不过按说应该是完善了之前的问题的

@DongHongfei 兄弟能教我下在官方的https://github.com/jpush/jpush-phonegap-plugin的基础上添加JPushPlugin.prototype.receiveNotificationIniOSCallback的步骤么?正在摸索中, 谢谢!

@pennsong 这个就爱莫能助了,需要有 object-c 基础才行,之前我是在官方的viper帮助下添加的。 不过我看这里https://github.com/jpush/jpush-phonegap-plugin/blob/master/document/iOS_detail_api.md的文档上有方法啊,我没有试,这个方法不好使么?

在你需要接收通知的的js文件中加入:

document.addEventListener("jpush.receiveNotification", onReceiveNotification, false);
onOpenNotification需要这样写:

    var onReceiveNotification = function(event){
        try{
            var alert   = event.aps.alert;
            console.log("JPushPlugin:onReceiveNotification key aps.alert:"+alert);
        }
        catch(exeption){
            console.log(exception)
        }
    }  
    

@DongHongfei 我尝试成功了 //app在前台运行中 document.addEventListener("jpush.receiveNotification", function(event) {}); //app在后台 document.addEventListener(“jpush.openNotification", function(event) {}); 这两个可以在ios捕捉到发来的"通知” 感谢兄弟的一路陪伴, 祝论坛越办越好

就是oc调用javascript嘛,java和oc都是可以调用javascript引擎的

@pennsong app前台,后台指那个地方,我监听不到

@mimosa 如果正在微信中看朋友圈, 或打字, 就是指微信这个app在前台运行中, 如果你现在在手机上正在用其他app(如正在用陌陌约…), 那么微信app就在后台

@pennsong 之所以提问,前/后台问题,是因为,我的 app 在 android 手机上,能收到消息,但打开时捕捉不到 :(

  • 能帮我诊断下吗?
  • 定义

//
.factory('Pusher', function ($cordovaDialogs, $localStorage) {
  var pusher = null;

  return {
    onReceiveMessage: function (event) {
      if(pusher){
        $cordovaDialogs.alert(pusher.receiveMessage.message);
      };
    },
    onOpenNotification: function (event) {
      var alert = null;
      if(pusher && pusher.openNotification.alert){
        alert = pusher.openNotification.alert;
      }else{
        alert = event.aps.alert;
      };
      $cordovaDialogs.alert(alert);
    },
    onReceiveNotification: function (event) {
      $cordovaDialogs.alert(event);
    },
    getRegistradionID: function () {
      return $localStorage.get('jPushID', null);
    },
    init: function () {
      if (window.plugins && window.plugins.jPushPlugin) {
        pusher = window.plugins.jPushPlugin;
        // 初始化
        pusher.init();
        // 获取注册ID
        pusher.getRegistrationID(function (id) {
          $localStorage.set('jPushID', id);
        });
        // 设置
        if (ionic.Platform.isAndroid()){
          pusher.setDebugModeFromIos();
          pusher.setApplicationIconBadgeNumber(0);
        } else {
          pusher.setDebugMode(true);
        };
      };
    }
  };
})
  • 调用

$ionicPlatform.ready(function() {
    // 初始化
    Pusher.init();
});
// 获取通知内容
document.addEventListener("jpush.openNotification", Pusher.onOpenNotification, false);
// 获取自定义消息推送内容
document.addEventListener("jpush.receiveMessage", Pusher.onReceiveMessage, false);
// 获取通知内容
document.addEventListener("jpush.receiveNotification", Pusher.onReceiveNotification, false);

使用plugins.jPushPlugin.setApplicationIconBadgeNumber(0)无法消除icon上的badge,请问大家遇到过这个问题么,有什么思路么,谢谢

@yesir1006 https://github.com/jpush/jpush-phonegap-plugin 你试试官方的window.plugins.jPushPlugin.setApplicationIconBadgeNumber(badge)呢?

@DongHongfei 也不行,一样的错误

[jpush]: reset badge 2015-05-27 12:00:34.649 mypush[742:60b] ERROR: Method ‘setApplicationIconBadgeNumber:’ not defined in Plugin ‘JPushPlugin’ 2015-05-27 12:00:34.651 mypush[742:60b] -[CDVCommandQueue executePending] [Line 159] FAILED pluginJSON = ["JPushPlugin1324556164","JPushPlugin","setApplicationIconBadgeNumber",[0]] 2015-05-27 12:00:34.853 mypush[742:5207] JPushLog: set badge:0 succeed

不明白为什么,官方文档也写着有这个函数的

不知道官方推出的推送服务 http://blog.ionic.io/announcing-ionic-push-alpha/

能不能够取代极光推送?

@Thomsen 可以的,但是后面会收费,具体收费模式未定
发自 Ioniclub

@DongHongfei 设置别名可以,我在Push工厂里添加了设置标签setTags方法,为什么客户端无法设置标签呢,服务器端调用的时候就出现1011 cannot find user by this audience

plugins.jPushPlugin.setTags(tag); 插件设置tag就会出错 [__NSCFString count]: unrecognized selector sent to instance 0x15dc12e0 2015-07-22 10:03:20.604 *** WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: <NSInvalidArgumentException> -[__NSCFString count]: unrecognized selector sent to instance 0x15dc12e0

@DongHongfei 5.0中好像默认不存在这个东东
发自 hainuoVersion

楼主 问个问题啊 为什么我的回调方法总是失败 总提示这个application:didReceiveRemoteNotification:fetchCompletionHandler: but the completion handler was never called. 能帮我解答下吗?谢谢 本人ios菜鸟

@pennsong 您好,我想请教下在申请证书的时候,要填写Bundle ID,这个要填写ionic项目里的哪个呢?谢谢您

@ch-hui 您好,集成里以后,在模拟器上运行ionic iOS 可以接收到推送吗

@DongHongfei您好,能请教下怎么后台缓存推送消息吗,我目前只找到了点击推送消息时处理推送消息,没找到后台接收到消息就缓存下来的方法,所以想请教下怎么后台处理收到的推送消息,还请不吝赐教。

回到顶部