博客
关于我
iOS__推送通知
阅读量:113 次
发布时间:2019-02-26

本文共 5386 字,大约阅读时间需要 17 分钟。

推送通知

和本地通知不同,推送通知是由应用服务提供商发起的,通过苹果的APNs(Apple Push Notification Server)发送到应用客户端。下面是苹果官方关于推送通知的过程示意图:

推送通知的过程可以分为以下几步:

  1. 应用服务提供商从服务器端把要发送的消息和设备令牌(device token)发送给苹果的消息推送服务器APNs。 
  2. APNs根据设备令牌在已注册的设备(iPhone、iPad、iTouch、mac等)查找对应的设备,将消息发送给相应的设备。 
  3. 客户端设备接将接收到的消息传递给相应的应用程序,应用程序根据用户设置弹出通知消息。

当然,这只是一个简单的流程,有了这个流程我们还无从下手编写程序,将上面的流程细化可以得到如下流程图(图片来自互联网),在这个过程中会也会提到如何在程序中完成这些步骤:

1.应用程序注册APNs推送消息。

说明:

a.只有注册过的应用才有可能接收到消息,程序中通常通过UIApplication的registerUserNotificationSettings:方法注册,iOS8中通知注册的方法发生了改变,如果是iOS7及之前版本的iOS请参考其他代码。

b.注册之前有两个前提条件必须准备好:开发配置文件(provisioning profile,也就是.mobileprovision后缀的文件)的App ID不能使用通配ID必须使用指定APP ID并且生成配置文件中选择Push Notifications服务,一般的开发配置文件无法完成注册;应用程序的Bundle Identifier必须和生成配置文件使用的APP ID完全一致。

2.iOS从APNs接收device token,在应用程序获取device token。

说明:

a.在UIApplication的-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken代理方法中获取令牌,此方法发生在注册之后。

b.如果无法正确获得device token可以在UIApplication的-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error代理方法中查看详细错误信息,此方法发生在获取device token失败之后。

c.必须真机调试,模拟器无法获取device token。

3.iOS应用将device token发送给应用程序提供商,告诉服务器端当前设备允许接收消息。

说明:

a.device token的生成算法只有Apple掌握,为了确保算法发生变化后仍然能够正常接收服务器端发送的通知,每次应用程序启动都重新获得device token(注意:device token的获取不会造成性能问题,苹果官方已经做过优化)。

b.通常可以创建一个网络连接发送给应用程序提供商的服务器端, 在这个过程中最好将上一次获得的device token存储起来,避免重复发送,一旦发现device token发生了变化最好将原有的device token一块发送给服务器端,服务器端删除原有令牌存储新令牌避免服务器端发送无效消息。

4.应用程序提供商在服务器端根据前面发送过来的device token组织信息发送给APNs。

说明:

a.发送时指定device token和消息内容,并且完全按照苹果官方的消息格式组织消息内容,通常情况下可以借助其他第三方消息推送框架来完成。

5.APNs根据消息中的device token查找已注册的设备推送消息。

说明:

a.正常情况下可以根据device token将消息成功推送到客户端设备中,但是也不排除用户卸载程序的情况,此时推送消息失败,APNs会将这个错误消息通知服务器端以避免资源浪费(服务器端此时可以根据错误删除已经存储的device token,下次不再发送)。

下面将简单演示一下推送通知的简单流程:

首先,看一下iOS客户端代码:

////  AppDelegate.m//  pushnotification////  Created by Kenshin Cui on 14/03/27.//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#import "AppDelegate.h"#import "KCMainViewController.h"@interface AppDelegate ()@end@implementation AppDelegate#pragma mark - 应用程序代理方法#pragma mark 应用程序启动之后- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {        _window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];        _window.backgroundColor =[UIColor colorWithRed:249/255.0 green:249/255.0 blue:249/255.0 alpha:1];        //设置全局导航条风格和颜色    [[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:23/255.0 green:180/255.0 blue:237/255.0 alpha:1]];    [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];        KCMainViewController *mainController=[[KCMainViewController alloc]init];    _window.rootViewController=mainController;        [_window makeKeyAndVisible];        //注册推送通知(注意iOS8注册方法发生了变化)    [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];    [application registerForRemoteNotifications];        return YES;}#pragma mark 注册推送通知之后//在此接收设备令牌-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{    [self addDeviceToken:deviceToken];    NSLog(@"device token:%@",deviceToken);}#pragma mark 获取device token失败后-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{    NSLog(@"didFailToRegisterForRemoteNotificationsWithError:%@",error.localizedDescription);    [self addDeviceToken:nil];}#pragma mark 接收到推送通知之后-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{    NSLog(@"receiveRemoteNotification,userInfo is %@",userInfo);}#pragma mark - 私有方法/** *  添加设备令牌到服务器端 * *  @param deviceToken 设备令牌 */-(void)addDeviceToken:(NSData *)deviceToken{    NSString *key=@"DeviceToken";    NSData *oldToken= [[NSUserDefaults standardUserDefaults]objectForKey:key];    //如果偏好设置中的已存储设备令牌和新获取的令牌不同则存储新令牌并且发送给服务器端    if (![oldToken isEqualToData:deviceToken]) {        [[NSUserDefaults standardUserDefaults] setObject:deviceToken forKey:key];        [self sendDeviceTokenWidthOldDeviceToken:oldToken newDeviceToken:deviceToken];    }}-(void)sendDeviceTokenWidthOldDeviceToken:(NSData *)oldToken newDeviceToken:(NSData *)newToken{    //注意一定确保真机可以正常访问下面的地址    NSString *urlStr=@"http://192.168.1.101/RegisterDeviceToken.aspx";    urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];    NSURL *url=[NSURL URLWithString:urlStr];    NSMutableURLRequest *requestM=[NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:10.0];    [requestM setHTTPMethod:@"POST"];    NSString *bodyStr=[NSString stringWithFormat:@"oldToken=%@&newToken=%@",oldToken,newToken];    NSData *body=[bodyStr dataUsingEncoding:NSUTF8StringEncoding];    [requestM setHTTPBody:body];    NSURLSession *session=[NSURLSession sharedSession];    NSURLSessionDataTask *dataTask= [session dataTaskWithRequest:requestM completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {        if (error) {            NSLog(@"Send failure,error is :%@",error.localizedDescription);        }else{            NSLog(@"Send Success!");        }            }];    [dataTask resume];}@end

iOS客户端代码的代码比较简单,注册推送通知,获取device token存储到偏好设置中,并且如果新获取的device token不同于偏好设置中存储的数据则发送给服务器端,更新服务器端device token列表。

转载地址:http://eyru.baihongyu.com/

你可能感兴趣的文章
NIFI分页获取Mysql数据_导入到Hbase中_并可通过phoenix客户端查询_含金量很高的一篇_搞了好久_实际操作05---大数据之Nifi工作笔记0045
查看>>
NIFI分页获取Postgresql数据到Hbase中_实际操作---大数据之Nifi工作笔记0049
查看>>
NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
查看>>
NIFI同步MySql数据源数据_到原始库hbase_同时对数据进行实时分析处理_同步到清洗库_实际操作06---大数据之Nifi工作笔记0046
查看>>
Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
查看>>
NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
查看>>
NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_处理器介绍_处理过程说明---大数据之Nifi工作笔记0019
查看>>
NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_实际操作---大数据之Nifi工作笔记0020
查看>>
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_实际操作_02---大数据之Nifi工作笔记0032
查看>>
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_操作方法说明_01_EvaluteJsonPath处理器---大数据之Nifi工作笔记0031
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka消费者处理器_来消费kafka数据---大数据之Nifi工作笔记0037
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka生产者---大数据之Nifi工作笔记0036
查看>>
NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
查看>>
NIFI大数据进阶_NIFI监控功能实际操作_Summary查看系统和处理器运行情况_viewDataProvenance查看_---大数据之Nifi工作笔记0026
查看>>
NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
查看>>
NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>
NIFI大数据进阶_使用NIFI表达式语言_来获取自定义属性中的数据_NIFI表达式使用体验---大数据之Nifi工作笔记0024
查看>>
NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
查看>>
NIFI大数据进阶_内嵌ZK模式集群2_实际操作搭建NIFI内嵌模式集群---大数据之Nifi工作笔记0016
查看>>