OdinPush
OdinPush是一个iOS的远程推送库,集成简单且功能丰富。
OdinPush使用步骤
- 安装
- 申请AppKey和AppSecret
- 配置AppKey和AppSecret
- 开启远程推送权限
- 配置推送证书
- 代码权限申请及配置
- 具体功能使用
7.1 App前台通知权限配置
7.2 跳转指定链接
7.3 跳转指定界面
7.4 富媒体通知
7.5 差异化推送
1.安装
OdinPush提供了两种方式将其集成到工程中。
1.1 手动集成
从奥丁数据开发者服务中心或者GitHub的Odin账号下载OdinPush.framework的最新版本,并将其添加到项目中。
必须添加以下依赖库:libc++.tbd和libz.1.2.5.tbd,选中对应的target -> Build Phases -> Link Binary with Libraries,点击加号,添加上述的两个依赖库:
libc++.tbd
libz.1.2.5.tbd
然后通过Build Settings > Other Linker Flags,添加
-ObjC
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)
如下图所示:
1.2.4 如果安装失败,提示原因是没有找到OdinPush,那么执行以下命令更新本地库,然后再执行pod install
$ pod repo update
2.申请AppKey和AppSecret
在奥丁数据开发者服务中心申请并获得OdinPush的AppKey和AppSecret。
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的请求是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,如下图所示:
4.开启远程推送权限
选择项目的project文件,project -> targets -> Capabilities,分别打开Push Notifications和Background Modes,在Background Modes中选中Remote notifications
参照下图所示,打开远程推送配置开关。
打开后台推送权限设置
5.配置推送证书
推送证书的配置分为2种,在服务中心 > PushSDK > 推送设置。
其一是APNs证书,这种配置分别有开发和生产环境;在苹果开发网站获得开发和生产环境的p12证书及密码后,在奥丁数据开发者即可;
其二就是授权验证,这种配置方式不区分正式和测试,需要p8证书(该证书只能在生成后下载一次)、KeyId,TeamId以及BundleId,在奥丁数据开发者服务中心配置即可。
KeyId是在创建p8证书之后,自动生成该证书对应的KeyId。
TeamId可以通过登录苹果开发者网站获得,Account -> MemberShip。
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协议,然后在初始化时设置代理,并实现对应的协议方法。以下代码以
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中,导入头文件,添加字段,并在
@property (nonatomic, strong) PushDelegation *pushDelegation;
_pushDelegation = [[PushDelegation alloc] init];
7.2 跳转指定链接
该功能的实现,需要在奥丁数据开发者服务中心进行配置和客户端代码的添加。
客户端代码如下:
[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 -> 创建推送 -> 通知推送 -> 后续动作,选择打开链接,然后填写链接地址即可。
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;
}
在奥丁数据开发者服务中心的配置:
注意!!
开发者需要在代码中提前设置,例如开发者根据需求配置了5个界面,那么每个界面的+(NSString *)OdinPushPath返回值都必须不同,并且需要记录下来,在后台创建推送时,跳转到哪个界面,就填写对应界面的+(NSString *)OdinPushPath返回值。
上面的代码与下面的示例图相对应:
7.4 富媒体通知
在iOS 10之后,通过UserNotifications框架和Notification Service Extension实现富媒体通知,示例图如下:
无论是本地通知还是远程通知,都必须构造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,示例图如下:
新添加的Extension是以target形式添加到工程中的,因为是新的target,所以bundle Identifier不能与项目的工程的bundle Identifier一致,且需要配置对应的provision file。
添加成功后,系统会自动生成NotificationService对应的.h和.m文件。
使用OdinPush下载媒体文件,分为2种情况:
- 手动集成
选中OdinPush.framework,查看Xcode右侧的文件信息的Target Membership,可以看到2个target,一个是app的项目,还有一个就是刚才添加的Notification Service Extension对应的target,然后点击选中该target,至此就已经将OdinPush.framework添加到新的target中,然后可以导入头文件使用,示例图如下所示:
- 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选中。配置的示例图如下:
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;
而在奥丁数据开发者服务中心对应的是创建推送里面的目标人群,示例图如下: