或许很多童鞋还不知道,在 iOS 中收到推送通知时,如果 App 处于前台运行的情况下,推送的顶部弹窗是不会弹出来的。
然而就是有很多**
的产品经理都会提出类似这样的**
需求:
那就是在 App 处于前台时一样要弹出推送的窗口,而且还要能点击,能跳转到指定页面,甚至这一需求还涉及到了产品的核心功能。
今天 Pikacode 就跟大家分享一下自己写的小插件,仅仅只需 1、2 行代码,即可搞定这一需求。
Github: https://github.com/Yasashi/EBForeNotification
EBForeNotification
在 App 处于前台时展示跟系统完全一样的推送弹窗
和声音
。获取推送内容,并且处理点击事件。
支持 iOS 7~10 beta,支持模拟器
和真机
运行。
效果
实际效果如下:
本地弹窗
在任意方法内调用以下任 1 行代码即可弹窗
#import "EBForeNotification.h"
{...
//普通弹窗(系统声音)
[EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":@"展示内容"}} soundID:1312];
//普通弹窗(指定声音文件)
[EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":@"展示内容"}} customSound:@"my_sound.wav"];
//带自定义参数的弹窗(系统声音)
[EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":@"展示内容"}, @"key1":@"value1", @"key2":@"value2"} soundID:1312];
//普通弹窗(指定声音文件)
[EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":@"展示内容"}, @"key1":@"value1", @"key2":@"value2"} customSound:@"my_sound.wav"];
...}
接收远程/本地推送后弹窗
接收远程/本地推送后,自动在前台展示推送弹窗及声音。
在 AppDelegate.m
中添加代码
//AppDelegate.m
#import "EBForeNotification.h"
//ios7 before
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
...
//系统声音弹窗
[EBForeNotification handleRemoteNotification:userInfo soundID:1312];
//指定声音文件弹窗
[EBForeNotification handleRemoteNotification:userInfo customSound:@"my_sound.wav"];
...
}
//ios7 later
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
...
//系统声音弹窗
[EBForeNotification handleRemoteNotification:userInfo soundID:1312];
//指定声音文件弹窗
[EBForeNotification handleRemoteNotification:userInfo customSound:@"my_sound.wav"];
...
completionHandler(UIBackgroundFetchResultNewData);
}
soundID 参数
iOS 系统自带的声音 id,系统级的推送服务默认使用的是三全音
,id = 1312
其他系统声音 id 可以在这里查询到 iOS Predefined sounds
备用地址 AudioServices sounds
监听并处理点击事件
添加 Observer
监听 EBBannerViewDidClick
,获取推送内容,通过推送时自定义的字段处理自己逻辑,如:跳转到对应页面等。
接收到的推送内容类似以下:
{
"aps":
{
"alert":"推送内容",
"sound":"sound",
"badge":"3"
},
"key1":"跳转页面1" //自定义此字段以跳转到相应页面
}
添加 Observer
获取自定义的字段,并处理:
#import "EBForeNotification.h"
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(eBBannerViewDidClick:) name:EBBannerViewDidClick object:nil];
-(void)eBBannerViewDidClick:(NSNotification*)noti{
if(noti[@"key1" == @"跳转页面1"]){
//跳转到页面1
}
}
网友评论
// iOS 10 Support前台
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
}
CGFloat bannerHeight = self.isIos10 ? BannerHeightiOS10 : BannerHeight;
self.frame = CGRectMake(0, 0, ScreenWidth, 0);
WEAK_SELF(weakSelf);
[UIView animateWithDuration:BannerSwipeUpTime animations:^{
weakSelf.frame = CGRectMake(0, 0, ScreenWidth, bannerHeight);
} completion:^(BOOL finished) {
weakSelf.frame = CGRectMake(0, 0, ScreenWidth, bannerHeight);
}];
[NSTimer scheduledTimerWithTimeInterval:BannerStayTime target:self selector:@selector(removeWithAnimation) userInfo:nil repeats:NO];
}
报错报在第二个 “weakSelf.frame = CGRectMake(0, 0, ScreenWidth, bannerHeight);”
错误信息:
warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
死循环?
(
"<_UIWindowAnchoringConstraint:0x161a4f90 h=--- v=--- _UIAlertControllerShimPresenterWindow:0x14feb530.midX == + 160>",
"<_UIWindowAnchoringConstraint:0x160000d0 h=-&- v=-&- EBBannerView:0x161a0d30.midX == + 160>",
"<NSAutoresizingMaskLayoutConstraint:0x161a4bf0 h=-&- v=-&- UITransitionView:0x161b4950.midX == _UIAlertControllerShimPresenterWindow:0x14feb530.midX>",
"<NSAutoresizingMaskLayoutConstraint:0x16002a30 h=-&- v=-&- EBBannerView:0x161a0d30.midX == _UIAlertControllerView:0x165147e0'\U53d6\U6d88\U8ba2\U5355'.midX + 25>",
"<NSLayoutConstraint:0x14e87720 _UIAlertControllerView:0x165147e0'\U53d6\U6d88\U8ba2\U5355'.centerX == UIView:0x14fd7a30.centerX>",
"<NSLayoutConstraint:0x161b24c0 UIView:0x14fd7a30.width == UITransitionView:0x161b4950.width>",
"<NSLayoutConstraint:0x161a35f0 H:|-(0)-[UIView:0x14fd7a30](LTR) (Names: '|':UITransitionView:0x161b4950 )>"
)
// Required, iOS 7 Support
[EBForeNotification handleRemoteNotification:@{@"aps":@{@"alert":userInfo[@"aps"][@"alert"]}} soundID:1312 isIos10:NO];
[JPUSHService handleRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
} 点击系统弹窗打开app时,走这个方法的时候app应该都是运行的状态了,没法区分啊