Discuz iOS应用开发 (bigApp iOS源码分析 - Remote Notification)

源代码中没有发现Remote Notification的代码。
代码中有发现JPush相关的引用,但JPush库并没有引用。考虑可能是之前使用了JPush,但后面删除了。
BigApp源码中有JPush相关的PHP代码,因此考虑之前是使用JPush来实现iOS端的推送的。

Todo:

  • 调查JPush的使用
  • 调查JPush相关的PHP代码的使用

发现了一份最新的iOS客户端源码,带JPush相关的设置,fork到https://github.com/Inspirelife96/Discuz_IOS 。

新代码,从工程文件的变化来看,添加了JPush和SMS。
Diff了一下其他代码的变化,修正了发帖崩溃的代码,还有就是添加了分享的代码。

5/24 更新
看来bigApp确实使用了JPush,但最新的源码只是添加了JPush的注册代码,但并没有和用户绑定。

我们需要做的是:

  1. 向JPush Server注册Device Token。
  2. 绑定Device Token和用户的UserName (UserId?)
  3. 修改Badge的值(?根据推送来源分类?修改会困难?)

剩下的交给服务器端来做,需要根据UserName和JPushServer通信向指定的Device推送信息。

【极光推送】给指定用户发送消息

接下来就是各种配置了:
https://developer.apple.com官网要做的事:

  1. 申请app id (例如com.xxxxxxx.bigapp)。记得开Push Notification选项
  2. 配置Push Notificaiton的开发和生产证书。导出相应的.p12文件。
  3. 配置项目对应的开发和生产Provisioning 文件。

极光https://www.jiguang.cn需要做的事:

  1. 注册并添加一个新的应用
  2. 配置iOS的推送信息。需要用到上面的.p12文件。
Discuz iOS应用开发 (bigApp iOS源码分析 - Remote Notification)_第1张图片
配置iOS的推送信息.png

具体的流程可以参考这里iOS最新极光推送详解

客户端开发
参考官方文档https://docs.jiguang.cn/jpush/client/iOS/ios_guide_new/,稍微做了下整合。

  1. 暂时是手动添加的,希望以后能改成cocoapods
  2. iOS8适配,开启Push Notification 功能。
  3. iOS9适配, 开启jpush.cn http白名单
  4. iOS10适配, UserNotifications

代码

  • 添加Delegate
@interface AppDelegate ()

@end
  • 添加初始化APNs代码以及添加初始化JPush代码,适配iOS10,封装在下面这个函数并在-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions调用
 - (void)setupJPush:(NSDictionary *)launchOptions {
    JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
    entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
    [self registerForRemoteNotification];
    [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
    
    [JPUSHService setupWithOption:launchOptions appKey:@"56acc62e21172eafa0c54091"
                          channel:@"iOS"
                 apsForProduction:NO
            advertisingIdentifier:nil];
}
/**
 * 初始化UNUserNotificationCenter
 */
- (void)registerForRemoteNotification {
    // iOS10 兼容
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
        // 使用 UNUserNotificationCenter 来管理通知
        UNUserNotificationCenter *uncenter = [UNUserNotificationCenter currentNotificationCenter];
        // 监听回调事件
        [uncenter setDelegate:self];
        //iOS10 使用以下方法注册,才能得到授权
        [uncenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert+UNAuthorizationOptionBadge+UNAuthorizationOptionSound)
                                completionHandler:^(BOOL granted, NSError * _Nullable error) {
                                    [[UIApplication sharedApplication] registerForRemoteNotifications];
                                    //TODO:授权状态改变
                                    NSLog(@"%@" , granted ? @"授权成功" : @"授权失败");
                                }];
        // 获取当前的通知授权状态, UNNotificationSettings
        [uncenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
            NSLog(@"%s\nline:%@\n-----\n%@\n\n", __func__, @(__LINE__), settings);
            /*
             UNAuthorizationStatusNotDetermined : 没有做出选择
             UNAuthorizationStatusDenied : 用户未授权
             UNAuthorizationStatusAuthorized :用户已授权
             */
            if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
                NSLog(@"未选择");
            } else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
                NSLog(@"未授权");
            } else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
                NSLog(@"已授权");
            }
        }];
    }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        UIUserNotificationType types = UIUserNotificationTypeAlert |
        UIUserNotificationTypeBadge |
        UIUserNotificationTypeSound;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        UIRemoteNotificationType types = UIRemoteNotificationTypeBadge |
        UIRemoteNotificationTypeAlert |
        UIRemoteNotificationTypeSound;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];
    }
#pragma clang diagnostic pop
}
  • 注册APNs成功并上报DeviceToken
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    /// Required - 注册 DeviceToken
    [JPUSHService registerDeviceToken:deviceToken];
}
  • 其他回调函数
// 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];
    }
    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];
    }
    completionHandler();  // 系统要求执行这个方法
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    
    // Required, iOS 7 Support
    [JPUSHService handleRemoteNotification:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    
    // Required,For systems with less than or equal to iOS6
    [JPUSHService handleRemoteNotification:userInfo];
}

#pragma mark - 实现注册APNs失败接口(可选)
///=============================================================================
/// @name 实现注册APNs失败接口(可选)
///=============================================================================

/**
 * also used in iOS10
 */
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"%s\n[无法注册远程提醒, 错误信息]\nline:%@\n-----\n%@\n\n", __func__, @(__LINE__), error);
}

测试log输出:成功在JPush Server上进行了注册

屏幕快照 2017-05-23 下午7.28.06.png

利用JPush的测试工具进行测试,可以看到收到了推送的消息


Discuz iOS应用开发 (bigApp iOS源码分析 - Remote Notification)_第2张图片
Bitmap.png

剩下的事:

  • 用户登录时或自动登录时将UserName绑定这个registrationID。
  • 用户退出登录时将UserName和这个registrationID解除绑定。
  • 其余的交给服务器端处理。现在不清楚BigApp插件的php代码是否已经可以顺利的进行推送。

服务器端开发
Todo

你可能感兴趣的:(Discuz iOS应用开发 (bigApp iOS源码分析 - Remote Notification))