《微言(官方版)》源码分享 -- 极光推送

### 前言
笔者这几天刚完成《微言(官方版)》的推送功能,今天特分享一下在做的过程中实际解决的问题。如果读者你学到了有用的东西,希望能前往App Store下载《微言(官方版)》支持一下笔者,谢谢!??

笔者使用的是用的比较广泛的**极光推送**,还有其他的什么百度推送、友盟推送等其实原理是一样的,至于选择哪个全凭读者喜好。说一下本文将要解决的几个问题:

1. APP处于前台运行状态,提示并接收保存消息;

2. APP处于后台运行状态,提示并接收保存消息;

3. APP处于退出状态,提示并接收保存消息。

### 一、证书准备
关于推送证书的配置网上有很多的详细说明,这里不再赘述,推荐一篇比较好的博客 [iOS 推送通知 功能简单实现](http://www.jianshu.com/p/fda61af94d09) 。照着里面的步骤完成后,我们得到了这么几个文件:

**四个证书**

![证书](https://static.oschina.net/uploads/img/201703/21161539_xcc4.png "证书")

前两个用于xcode的调试与发布
![xcode证书配置](https://static.oschina.net/uploads/img/201703/21163218_kgwX.png "xcode证书配置")

后两个用于极光推送的证书配置
![极光推送证书配置](https://static.oschina.net/uploads/img/201703/21162525_tbId.png "极光推送证书配置")

**两个配置文件**

![配置文件](https://static.oschina.net/uploads/img/201703/21162824_2LFO.png "配置文件")

**一个带已配置远程推送的APP IDs文件**
![输入图片说明](https://static.oschina.net/uploads/img/201703/21163002_6uJS.png "在这里输入图片标题")

### 二、极光推送代码配置
iOS的代码配置笔者推荐最好去极光推送的官网去下载-> [Demo](https://docs.jiguang.cn/jpush/resources/) 。这里既然说是源码分享,所以贴上笔者的代码,仅供参考:

AppDelegate.h
```
static NSString *appKey = @"*******************";
static NSString *channel = @"App Store";
static BOOL isProduction = TRUE;
```
AppDelegate.m
```
#import "AppDelegate.h"
#import "JKChooseRootVCHelper.h"
#import "JKUtilsHelper.h"
#import "JKRemoteNoticeModel.h"
// 引入JPush功能所需头文件
#import "JPUSHService.h"
// iOS10注册APNs所需头文件
#ifdef NSFoundationversionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    
    // 选择根控制器
    [JKChooseRootVCHelper chooseRootViewController:self.window];
    [self.window makeKeyAndVisible];
    
/******* 极光推送配置 ********/
    // 获取自定义消息
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    
    [defaultCenter addObserver:self selector:@selector(NetworkDidReceivemessage:) name:kJPFNetworkDidReceiveMessageNotification object:nil];
    
    // notice: 3.0.0及以后版本注册可以这样写,也可以继续用之前的注册方式
    JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
    entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
    
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        // 点击通知横幅启动app时获取APNS内容(代理方法也可以处理),可以在这里跳转到指定的界面
//        NSDictionary *remoteNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
        //
        NSInteger unReadCount = [[NSUserDefaults standardUserDefaults] integerForKey:kUnReadCount];
        if (unReadCount == 0) {
            [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
        }
    }
    [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
    
    // 如不需要使用IDFA,advertisingIdentifier 可为nil
    [JPUSHService setupWithOption:launchOptions appKey:appKey
                          channel:channel
                 apsForProduction:isProduction
            advertisingIdentifier:nil];
/**************************/
    
    return YES;
}

// 注册APNs成功并上报DeviceToken
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    
    [JPUSHService registerDeviceToken:deviceToken];
    
    JKLog(@"--Device Token: %@", deviceToken);
}

// 实现注册APNs失败接口(可选)
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    //Optional
    JKLog(@"--did Fail To Register For Remote Notifications With Error: %@", error);
}

#pragma mark- JPUSHRegisterDelegate

// 前台收到 APNs 通知后就会走这个方法,iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
    // Required
    NSDictionary * userInfo = notification.request.content.userInfo;
//    UNNotificationRequest *request = notification.request; // 收到推送的请求
//    UNNotificationContent *content = request.content; // 收到推送的消息内容
//    
//    NSNumber *badge = content.badge;  // 推送消息的角标
//    NSString *body = content.body;    // 推送消息体
//    UNNotificationSound *sound = content.sound;  // 推送消息的声音
//    NSString *subtitle = content.subtitle;  // 推送消息的副标题
//    NSString *title = content.title;  // 推送消息的标题
    
    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
        JKLog(@"--iOS10 前台收到远程通知:%@", userInfo);  // [self logDic:userInfo]
    }
    else {
        // 判断为本地通知
//        JKLog(@"--iOS10 前台收到本地通知:{\nbody:%@,\ntitle:%@,\nsubtitle:%@,\nbadge:%@,\nsound:%@,\nuserInfo:%@\n}", body,title,subtitle,badge,sound,userInfo);
    }
    completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
    // UNNotificationPresentationOptionBadge、UNNotificationPresentationOptionSound、UNNotificationPresentationOptionAlert
}

// 在前台点击通知消息后走该方法(即后台收到通知后,点击通知的回调方法),iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    // Required
    NSDictionary * userInfo = response.notification.request.content.userInfo;
//    UNNotificationRequest *request = response.notification.request; // 收到推送的请求
//    UNNotificationContent *content = request.content; // 收到推送的消息内容
    
//    NSNumber *badge = content.badge;  // 推送消息的角标
//    NSString *body = content.body;    // 推送消息体
//    UNNotificationSound *sound = content.sound;  // 推送消息的声音
//    NSString *subtitle = content.subtitle;  // 推送消息的副标题
//    NSString *title = content.title;  // 推送消息的标题
    
    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
        JKLog(@"--iOS10 前台收到远程通知:%@", userInfo);  // [self logDic:userInfo]
    }
    else {
        // 判断为本地通知
//        JKLog(@"--iOS10 前台收到本地通知:{\nbody:%@,\ntitle:%@,\nsubtitle:%@,\nbadge:%@,\nsound:%@,\nuserInfo:%@\n}", body,title,subtitle,badge,sound,userInfo);
    }
    completionHandler();  // 系统要求执行这个方法
}
```

然后还得打开xcode的远程推送设置:
![xcode的远程推送设置](https://static.oschina.net/uploads/img/201703/21170822_UlEj.png "xcode的远程推送设置")

到这里,要说的 问题1 就实现了,现在APP在前端运行时能收到远程推送通知并能获取通知内容,但是当APP在后台
赞 (0) 评论 分享 ()