OdinPush 0.2.1

OdinPush 0.2.1

odin 维护。



OdinPush 0.2.1

  • 作者:
  • Bacon

OdinPush

Build Status Build Status

OdinPush是一个iOS的远程推送库,集成简单且功能丰富。


OdinPush使用步骤

  1. 安装
  2. 申请AppKey和AppSecret
  3. 配置AppKey和AppSecret
  4. 开启远程推送权限
  5. 配置推送证书
  6. 代码权限申请及配置
  7. 具体功能使用
    7.1 App前台通知权限配置
    7.2 跳转指定链接
    7.3 跳转指定界面
    7.4 富媒体通知
    7.5 差异化推送

1.安装

OdinPush提供了两种方式将其集成到工程中。

1.1 手动集成

奥丁数据开发者服务中心或者GitHub的Odin账号下载OdinPush.framework的最新版本,并将其添加到项目中。

必须添加以下依赖库:libc++.tbdlibz.1.2.5.tbd,选中对应的target -> Build Phases -> Link Binary with Libraries,点击加号,添加上述的两个依赖库:

libc++.tbd
libz.1.2.5.tbd

image

然后通过Build Settings > Other Linker Flags,添加

-ObjC

如下图所示:
image

1.2 pod集成

1.2.1 启动命令行工具,切换到工程目录下,如果项目之前没有使用pod集成,那么执行

$ pod init

该命令会在当前目录下生成对应的Podfile文件。

1.2.2 在Podfile中添加

pod 'OdinPush'

1.2.3 执行pod的集成命令

$ pod install

pod install成功后,可能报以下警告:

[!] The `OdinPushDemo [Debug]` target overrides the `OTHER_LDFLAGS` build setting defined in `Pods/Target Support Files/Pods-OdinPushDemo/Pods-OdinPushDemo.debug.xcconfig'. This can lead to problems with the CocoaPods installation
    - Use the `$(inherited)` flag, or
    - Remove the build settings from the target.

[!] The `OdinPushDemo [Release]` target overrides the `OTHER_LDFLAGS` build setting defined in `Pods/Target Support Files/Pods-OdinPushDemo/Pods-OdinPushDemo.release.xcconfig'. This can lead to problems with the CocoaPods installation
    - Use the `$(inherited)` flag, or
    - Remove the build settings from the target.

因为在Cocoapod里面会设置Other Linker Flags,而开发者之前也设置过,那么就会冲突,需要根据Cocoapod的提示,额外配置Other Linker Flags,添加

$(inherited)

如下图所示:

image

1.2.4 如果安装失败,提示原因是没有找到OdinPush,那么执行以下命令更新本地库,然后再执行pod install

$ pod repo update

2.申请AppKey和AppSecret

奥丁数据开发者服务中心申请并获得OdinPush的AppKeyAppSecret

image

3.配置AppKey和AppSecret

在工程的info.plist中进行配置,AppKey对应plist的key是OdinKey,AppSecret对应plist的key是OdinSecret,两者都是string类型。

<key>OdinKey</key>  
<string>填写你自己申请的AppKey</string>  
<key>OdinSecret</key>  
<string>填写你自己申请的AppSecret</string>  

OdinPush_info.plist

网络请求权限配置

由于OdinPush的请求是http,需要运行app设置请求权限。源代码如下:

<key>NSAppTransportSecurity</key>  
<dict>  
<key>NSAllowsArbitraryLoads</key>  
<true/>  
</dict>  

开发者可以将上面代码直接加入到info.plist中。 或者自行添加,在info.plist最外层点击加号,添加新的键值对,key为App Transport Security Settings,类型为Dictionary,在刚添加的Dictionary下面添加键值对,key为Allow Arbitrary Loads,类型为Boolean,值为YES,如下图所示:

image

4.开启远程推送权限

选择项目的project文件,project -> targets -> Capabilities,分别打开Push Notifications和Background Modes,在Background Modes中选中Remote notifications

参照下图所示,打开远程推送配置开关。

project setting

打开后台推送权限设置

project setting

5.配置推送证书

推送证书的配置分为2种,在服务中心 > PushSDK > 推送设置。

其一是APNs证书,这种配置分别有开发和生产环境;在苹果开发网站获得开发和生产环境的p12证书及密码后,在奥丁数据开发者即可;

certificate p12

其二就是授权验证,这种配置方式不区分正式和测试,需要p8证书(该证书只能在生成后下载一次)、KeyId,TeamId以及BundleId,在奥丁数据开发者服务中心配置即可。

certificate p8

KeyId是在创建p8证书之后,自动生成该证书对应的KeyId。

certificate p8 KeyId

TeamId可以通过登录苹果开发者网站获得,Account -> MemberShip。

certificate p8 TeamId

BundleId就是工程的bundle Identifier

6. 代码权限申请及配置

在代码中添加环境配置,申请通知权限的代码和接受消息通知的代码。
下面的代码是配置SDK的使用环境:

#ifdef DEBUG
    [OdinPush setAPNsForProduction:NO];
#else
    [OdinPush setAPNsForProduction:YES];
#endif

下面的代码是配置远程通知的通知形式:

OPushNotificationConfiguration *config = [[OPushNotificationConfiguration alloc] init];
config.types = (OPushAuthorizationOptionsSound|OPushAuthorizationOptionsAlert|OPushAuthorizationOptionsBadge);
[OdinPush setupNotification:config];

7. 具体功能使用

下面介绍OdinPush的具体的功能使用。在远程推送,app集成Push的功能后,只是对消息的接受和处理,自身并不发送消息,而是后台根据业务逻辑发送消息。

7.1 App前台通知权限配置

在iOS 10之前,应用程序在前台环境下无法展示通知,但在iOS之后,可以通过UNUserNotification框架来设置前台展示的权限。开发者需要创建一个类并遵守UNUserNotificationCenterDelegate协议,然后在初始化时设置代理,并实现对应的协议方法。以下代码以PushDelegation类为例,开发者在userNotificationCenter: willPresentNotification: withCompletionHandler:方法中调用completionHandler,根据不同情况判断是否以及如何展示前台通知;由于OdinPush内部已实现此方法,如果开发者没有实现该方法,则OdinPush的回调将

completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound)。

PushDelegation.m代码

@interface PushDelegation () <UNUserNotificationCenterDelegate>
@end

@implementation PushDelegation
- (instancetype)init {
    self = [super init];
    if (self) {
       UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
       center.delegate = self;
    }
    return self;
}

-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        //远程通知
        completionHandler(UNNotificationPresentationOptionNone);
    } else {
        //本地通知
        completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound);
    }
}
@end

在Appdelegate.m中,导入头文件,添加字段,并在application: didFinishLaunchingWithOptions:进行初始化。

@property (nonatomic, strong) PushDelegation *pushDelegation;

_pushDelegation = [[PushDelegation alloc] init];

该功能的实现,需要在奥丁数据开发者服务中心进行配置和客户端代码的添加。
客户端代码如下:

[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(pushMessage:) name:OdinPushDidReceiveMessageNotification object:nil];

- (void)pushMessage:(NSNotification *)noti {
    OPushMessage *message = noti.object;
    switch (message.messageType) {
        case OPushMessageTypeClicked:{
        NSString *link = message.msgInfo[@"url"];
            if (link) {
                //开发者拿到链接后自行处理
            }
        }
            break;
    }
}

而在奥丁数据开发者服务中心的设置:PushSDK -> 创建推送 -> 通知推送 -> 后续动作,选择打开链接,然后填写链接地址即可。

image

7.3 跳转指定界面

该功能的实现,需要在奥丁数据开发者服务中心进行配置和客户端代码的配置。在需要跳转的UIViewController里面导入

#import <OdinPushSDK/UIViewController+OdinPush.h>

在implementation里面重写刚导入的分类的2个方法,如下所示

+ (NSString *)OdinPushPath {
    return @"page1";
}

-(instancetype)initWithOdinPushScene:(NSDictionary *)params {
    self = [super init];
    if (self) {
        if (params[@"title"]) {
            self.title = params[@"title"];
        }
        if (params[@"subtitle"]) {
            NSLog(@"%@", params[@"subtitle"]);
        }
    }
    return self;
}

在奥丁数据开发者服务中心的配置:PushSDK -> 创建推送 -> 通知推送 -> 后续动作,选择“应用内跳转”,在scheme地址中填写的参数,添加上面代码中OdinPushPath返回的参数,而下面的参数的键值对,则对应上面初始化方法的params,客户端在接受到该通知之后,点击该通知即可跳转对应的界面,对应的参数也会传递进去。

注意!!

开发者需要在代码中提前设置,例如开发者根据需求配置了5个界面,那么每个界面的+(NSString *)OdinPushPath返回值都必须不同,并且需要记录下来,在后台创建推送时,跳转到哪个界面,就填写对应界面的+(NSString *)OdinPushPath返回值。

上面的代码与下面的示例图相对应:

image

7.4 富媒体通知

在iOS 10之后,通过UserNotifications框架和Notification Service Extension实现富媒体通知,示例图如下:

image

无论是本地通知还是远程通知,都必须构造UNNotificationAttachment的实例,进而需要资源的NSURL,该NSURL对应的资源必须是本地资源,不能是网络资源。

本地通知实现富媒体通知

示例代码如下:

UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
NSString *path = [NSBundle.mainBundle pathForResource:@"youth" ofType:@"jpeg"];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"ident" URL:[NSURL fileURLWithPath:path] options:nil error:nil];
content.attachments = @[attachment];
content.title = @"This is a title.";
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.1 repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"requestId" content:content trigger:trigger];
[UNUserNotificationCenter.currentNotificationCenter addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];

上述代码中的富媒体资源为图片,开发者也可将其替换为视频或音频,执行上述代码即可接收到本地富媒体通知。

远程通知实现富媒体通知

要实现远程富媒体通知,需要添加Notification Service Extension,示例图如下:

image

新添加的Extension是以target形式添加到工程中的,因为是新的target,所以bundle Identifier不能与项目的工程的bundle Identifier一致,且需要配置对应的provision file。

添加成功后,系统会自动生成NotificationService对应的.h和.m文件。

使用OdinPush下载媒体文件,分为2种情况:

  1. 手动集成
    选中OdinPush.framework,查看Xcode右侧的文件信息的Target Membership,可以看到2个target,一个是app的项目,还有一个就是刚才添加的Notification Service Extension对应的target,然后点击选中该target,至此就已经将OdinPush.framework添加到新的target中,然后可以导入头文件使用,示例图如下所示:

image

  1. CocoaPod集成 添加新的target之后,需要在Podfile里面添加对应的target,并将pod 'OdinPush'加到对应的target中,下面是示例配置,请将target改成开发者自己设置的target name:
target 'OdinPushDemo' do
  pod 'OdinPush'
end

target 'PushService' do
  pod 'OdinPush'
end

添加完成后,再执行pod install即可。

示例代码如下
导入头文件

#import <OdinPushSDK/OdinPushSDK.h>

使用OdinPush下载媒体文件示例代码如下:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    NSString * url = request.content.userInfo[@"attachment"];
    if (url) {
        [OdinPushServiceExtension handelNotificationServiceRequestUrl:url withAttachmentsComplete:^(NSArray *attachments, NSError *error) {
            self.bestAttemptContent.attachments = attachments;
            self.contentHandler(self.bestAttemptContent);
        }];
    } else {
        self.contentHandler(self.bestAttemptContent);
    }
    self.contentHandler(self.bestAttemptContent);
}

根据上面的代码,之所以取url对应key为attachment,是因为在奥丁数据开发者服务中心推送过来的富媒体通知的地址对应的key就是attachment。

在创建推送中,配置媒体文件有2种形式,本地文件和网络文件。这二者最终给到客户端的都是媒体文件的链接,对应的key值是attachment,并且需要将mutable-content选中。配置的示例图如下:

image

7.5 差异化推送

在OdinPush的OdinPush.h里面可以看到设置标签的四个API和设置别名的三个API,开发者可以通过这几个API,根据用户不同的属性添加不同的标签和别名;开发者在SDK初始化成功后,就能获取RegistrationID

标签API
+ (void)getTagsWithResult:(void (^) (NSArray *tags, NSError *error))handler;
+ (void)addTags:(NSArray<NSString *> *)tags result:(void (^) (NSError *error))handler;
+ (void)deleteTags:(NSArray<NSString *> *)tags result:(void (^) (NSError *error))handler;
+ (void)cleanAllTags:(void (^) (NSError *error))handler;
别名API
+ (void)getAliasWithResult:(void (^) (NSString *alias, NSError *error))handler;
+ (void)setAlias:(NSString *)alias result:(void (^) (NSError *error))handler;
+ (void)deleteAlias:(void (^) (NSError *error))handler;
获取RegistrationID API
+ (void)getRegistrationID:(void(^)(NSString *registrationID, NSError *error))handler;

而在奥丁数据开发者服务中心对应的是创建推送里面的目标人群,示例图如下:

image