对于推送,不管是我们开发人员还是用户,都是又爱又恨,特别是iOS的推送苹果爸爸几乎每出一个版本的iOS系统都要给他一两斧子,以改善用户体验和安全性,因为东西实在又多又杂,所以我只说说我们常用到的一些东西。
推送无外乎就两个,一个是本地推送,一个是远程推送,但是二者其实是相互依存的。
我们做出来的时候,还要特别注意第三个东西,那就是APP的状态:
UIApplicationStateActive,// 激活状态,用户正在使用
AppUIApplicationStateInactive,// 待激活状态,即用户切换到其他App、按Home键回到桌面、拉下通知中心
UIApplicationStateBackground// 在后台运行
其实,还有一个更棘手的状态,那就是app被杀死的状态,文章末尾我将说到。
本地推送一般和APP的UIApplicationStateBackground这个状态密切相关,其他状态要么没有多大必要,要么接收不到(杀手状态),在收到远程推送后,先判断状态:
switch (state) {
case UIApplicationStateActive:{}//可以播放声音震动提示
break;
case UIApplicationStateInactive:{}//可以播放声音震动提示
break;
case UIApplicationStateBackground:{
[self showNotificationLocalNotification];//生成本地推送
}
break;
default:
break;
}
本地推送到了iOS10,有很大的改动,所以要判断是否是iOS10:
- (void)showNotificationWithMessage:(EMMessage *)message
{
//接连推送判断
NSTimeInterval timeInterval = [[NSDate date] timeIntervalSinceDate:self.lastPlaySoundDate];
BOOL playSound = NO;
if (!self.lastPlaySoundDate || timeInterval >= kDefaultPlaySoundInterval) {
self.lastPlaySoundDate = [NSDate date];
playSound = YES;
}
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
[userInfo setObject:@"xxx" forKey:@"key"];
if (IOS10) {
//发送本地推送
if (NSClassFromString(@"UNUserNotificationCenter")) {
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.01 repeats:NO];
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
if (playSound) {
content.sound = [UNNotificationSound defaultSound];
}
content.body =alertBody;
content.userInfo = userInfo;
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:message.messageId content:content trigger:trigger];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:nil];
}
else {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate date]; //触发通知的时间
NSString *title = message.ext[kChatUserNick];
}
}
notification.alertBody =[NSString stringWithFormat:@"%@:%@", title, messageStr];;
notification.alertAction = NSLocalizedString(@"open", @"Open");
notification.timeZone = [NSTimeZone defaultTimeZone];
if (playSound) {
notification.soundName = UILocalNotificationDefaultSoundName;
}
notification.userInfo = userInfo;
//发送通知
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
UIApplication *application = [UIApplication sharedApplication];
application.applicationIconBadgeNumber += 1;
} else {//iOS10 以下
//发送本地推送
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate date]; //触发通知的时间
notification.alertBody = @"xxxx";
notification.alertAction = @"打开";
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
notification.userInfo = userInfo;
//发送通知
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
UIApplication *application = [UIApplication sharedApplication];
application.applicationIconBadgeNumber += 1;
}
}
以上是接到远程推送并发送本地推送的代码,很多童鞋会认为这是自定义推送,其实也可以这么理解,那么怎么接收到本地推送呢?
很简单,在AppDelegate里实现这个方法就OK:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
这个方法中你要放你接收到本地推送,用户点击后要处理的事情,比如跳转到某个指定页面,那么问题又来了,怎么跳转到指定页面呢?
这个问题就和你APP的架构密切相关了,我只说说我的思路
1.找到APP此时顶层的UIViewController
2.回到rootViewControlle
3.跳转至页面
当然,在APP杀死的状态下,你将只能收到远程推送,如果用户点击了通知,将进入下面的方法:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
注意,远程推送有一定的延迟。
最后说一个问题,希望有大神来指点迷津:
APP在绑定了推送之后,被用户卸载了,然后又重装了,也能收到推送,怎么破????目前发现微信也存在这个问题,真心求解!!!!