标签:
推送通知就是向用户推送一条信息来通知用户某件事件,可以在应用退到后台后,或者关闭后,能够通过推送一条消息通知用户某件事情,比如版本更新等等。
使用原则:谁确定通知时间和内容,谁就可以发生。
UILocalNotification
本地通知对象,并设置必要属性
- 第一种方法,延时推送,根据本地通知对象的
fireDate
设置进行本地推送通知
[[UIApplication shareApplication] scheduleLocalNotification:notification];
- 第二种方法,立刻推送,忽略本地通知对象的
fireDate
设置进行本地推送通知
[[UIApplication shareApplication] presentLocalNotificationNow:notification];
4- 监听用户点击通知:
- APP处于前台,此时不会弹框通知用户,但会调用对应的代理方法 :
-(void)application:(UIApplication *)application didReceiveLocalNotification;
- APP处于后台,屏幕上方会弹出横幅,用户点击横幅后,会进入前台,调用上面的代理方法。
- APP已关闭,屏幕上方会弹出横幅,用户点击横幅后,会启动APP,调用以下方法:
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
/* 通过参数launchOptions获取本地推送通知内容 */
UILocalNotification *local = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
5- 调用UIApplication
的对象方法,取消本地推送通知:
/* 取消指定的本地推送通知 */
-(void)cancelLocalNotification:(UILocalNotification *)notification;
/* 取消全部本地推送通知 */
-(void)cancelAllLocalNotification;
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//因为是storyboard启动,这里就没有其他启动代码了
//iOS8.0以后,如果需要使用推送通知,需要得到用户许可
if (application.currentUserNotificationSettings.types == UIUserNotificationTypeNone) {
//注册通知,有横幅通知、应用数字通知、应用声音通知
UIUserNotificationSettings * setting =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound
categories:nil];
[application registerUserNotificationSettings:setting];
} else {
//当APP关闭后接收到通知,在启动中获取本地推送通知对象
UILocalNotification *notification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
[self showLocalNotification:notification];
}
return YES;
}
/* 弹框UIAlertView显示本地通知的信息 */
- (void)showLocalNotification:(UILocalNotification *)notification
{
/* 显示本地通知 */
NSDictionary *userInfo = notification.userInfo;
NSString *title = @"本地通知";
NSString *msg = userInfo[@"msg"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:nil
cancelButtonTitle:@"取消"
otherButtonTitles:@"确定", nil];
[alert show];
//移除本地通知
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
/* 创建一个本地通知 */
- (UILocalNotification *)makeLocalNotification{
//创建本地推送通知对象
UILocalNotification *notification = [[UILocalNotification alloc] init];
//设置调用时间
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10.0];//通知触发的时间,10s以后
notification.repeatInterval = NSCalendarUnitMinute;//每隔多久重复发一次本地通知
//设置通知属性
notification.alertBody = @"最近添加了诸多有趣的特性,是否立即体验?";//通知主体
notification.applicationIconBadgeNumber = 1;//应用程序图标右上角显示的消息数
notification.alertAction = @"打开应用"; //待机界面的滑动动作提示
notification.alertLaunchImage = @"Default";//通过点击通知打开应用时的启动图片,这里使用程序启动图片
notification.soundName = UILocalNotificationDefaultSoundName;//收到通知时播放的声音,默认消息声音
//设置用户信息
notification.userInfo = @{ @"id":@1,
@"user":@"Kenshin Cui",
@"msg":@"我来了一发本地通知"};//绑定到通知上的其他附加信息
return notification;
}
如果需要每天的中午12点准时本地推送怎么办呢?
就像这么办,修改fireDate
和repeatInterval
属性
NSDateFormatter *formatter1 = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"yyyy-MM-dd HH-mm-sss"];
NSDate *resDate = [formatter dateFromString:@"2016-04-09 12-00-00"];
notification.fireDate = resDate;//设定为明天中午12点触发通知
//记得设置当前时区,没有设置的话,fireDate将不考虑时区,这样的通知会不准确
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.repeatInterval = NSCalendarUnitDay;//每隔一天触发一次
/* 注册本地通知完成会调用,即用户点击确定授权后调用 */
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//在这里我们尝试发送本地推送通知
if (notificationSettings.types != UIUserNotificationTypeNone) {
UILocalNotification *notification = [self makeLocalNotification];
//延迟调用通知
[application scheduleLocalNotification:notification];
//立刻发送通知
//[application presentLocalNotificationNow:notification];
}
}
/* 应用还在运行,无论前台还是后台,都会调用该方法处理通知 */
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
if( notification ) {
[self showLocalNotification:notification];
}
}
/* 应用进入前台,去除应用边角数字显示 */
- (void)applicationWillEnterForeground:(UIApplication *)application {
//去除应用边角数字
[application setApplicationIconBadgeNumber:0];
}
device token
)发送给苹果的消息推送服务器APNs。所有的苹果设备,在联网状态下,都会和苹果服务器APNs建立一个长连接
* 长连接:服务器可以向客户端发送消息,保证数据的即时性,但比较占用资源
* 短连接:服务器无法主动向客户端发消息,会话结束后,就立即释放资源,节省资源
远程推送通知就是借助苹果设备与APNs服务器之间的长连接,借助APNs服务器讲消息发送给客户端。
deviceToken
设备令牌证书的申请请参考:iOS学习笔记21-推送证书与秘钥申请
deviceToken
的生成算法只有Apple掌握,为了确保算法发生变化后仍然能够正常接收服务器端发送的通知,每次应用程序启动都重新获得deviceToken
deviceToken
设备令牌:-(void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
3- 把deviceToken
设备令牌发送给服务器,时刻保持deviceToken
是最新的
4- 监听远程推送通知:
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo;
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//iOS8.0以后,如果需要使用本地推送通知,需要得到用户许可
if (![application isRegisteredForRemoteNotifications]) {
UIUserNotificationSettings * setting =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound
categories:nil];
[application registerUserNotificationSettings:setting];
//注册远程推送通知
[application registerForRemoteNotifications];
}
return YES;
}
/* 注册远程推送通知成功会调用 ,在此接收设备令牌deviceToken */
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[self addDeviceToken:deviceToken];
}
/* 保存deviceToken,并同步服务器上保存的deviceToken,以便能正确推送通知 */
- (void)addDeviceToken:(NSData *)deviceToken
{
NSString *key = @"DeviceToken";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//取出原来的deviceToken,进行比较
NSData *oldToken = [defaults objectForKey:key];
if ([oldToken isEqualToData:deviceToken]) {
//存入新的deviceToken
[defaults setObject:deviceToken forKey:key];
[defaults synchronize];
//发送网络请求到服务器,说明deviceToken发生了改变
[self sendDeviceTokenWithOldDeviceToken:oldToken newDeviceToken:deviceToken];
}
}
/* 发送网络请求到服务器,说明deviceToken发生了改变,服务器那边也要同步改变 */
- (void)sendDeviceTokenWithOldDeviceToken:(NSData *)oldToken newDeviceToken:(NSData *)newToken
{
//发送到服务器,下面是服务器的一个接口
NSString *urlStr = @"http://192.168.1.101/RegisterDeviceToken.aspx";
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
//POST网络请求
NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];
requestM.HTTPMethod = @"POST";
//POST请求的请求体
NSString *bodyStr = [NSString stringWithFormat:@"oldToken=%@&newToken=%@",oldToken,newToken];
requestM.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
//使用会话来发送网络请求
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask =
[session dataTaskWithRequest:requestM
completionHandler:^(NSData *data,NSURLResponse *response,NSError *error){
if(!error){
NSLog(@"Send Success !");
} else {
NSLog(@"Send Failure, error = %@",error.localizedDescription);
}
}];
//网络请求任务启动
[dataTask resume];
}
/* 收到远程推送通知时会调用 */
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSString *title = @"远程推送通知";
NSString *msg = userInfo[@"msg"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:nil
cancelButtonTitle:@"取消"
otherButtonTitles:@"确定", nil];
[alert show];
}
上面的远程推送过程如果觉得实现比较麻烦,你可以使用第三方推送,例如:
- 极光推送( JPush ),我只用过这个,界面还不错,这不是在打广告!
- 个推
- 腾讯信鸽
具体的集成步骤及使用方法,请查看对应的官方文档,非常详细。
标签:
原文地址:http://blog.csdn.net/liuting5521826/article/details/51140058