provider是指iPhone的push服务器
apple push notification service(apple push服务器)的缩写,是苹果的服务器
三个步骤:
第一阶段:.net应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。
第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。
第三阶段:iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。
5步
1、首先是应用程序注册消息推送。
2、 IOS跟APNS Server要deviceToken。应用程序接受deviceToken。
3、应用程序将deviceToken发送给PUSH服务端程序。
4、 服务端程序向APNS服务发送消息。
5、APNS服务将消息发送给iPhone应用程序。
无论是iPhone客户端跟APNS,还是Provider和APNS都需要通过证书进行连接的。
几种证书:一:*.certSigningRequest文件
keychain Access-----------Certificate Assistant--------------request a Certificate from a certificate authority
填写邮箱,在本地生成一个pushchat.certSigningRequest文件
二:*.p12文件
导出密钥,并输入你的密码--------生成一个pushchatkey.p12文件
三:新建一个App ID和SSL certificate文件
用付过费的apple账号登录到ios provisioning portal。新建一个app ID。
description:中输入pushchat
bundle seed ID:默认选择generate new
bundle identifier:输入com.mysoft.pushchat
点击提交
点击配置
选择前面生成好的pushchat.certsigningrequest文件
生成.cer。命名为aps_developer_identity.cer
四:现在我们创建一个简单的iPhone应用程序
1,打开xcode,选择创建一个view-based application。命名如图
product name:pushchat
company identifier:com.Mysoft
2,在pushchatappdelegate中的didfinishlaunchingwithoptions方法中加入下面代码:
通过registerforremotenotificationtype方法,告诉应用程序,能接受push来的通知
3,在xcode中运行。
在pushchatappdelegate.m代码中添加下面方法获取devicetoken
(void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{
(NSData*)deviceToken{NSLog(@My token is:%@,deviceToken);}
}
(void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError)error{
NSLog(@Fail to get tolem,erroe:%@,error);
}
====================================================================
获取到的devicetoken,我们可以通过webservice服务提交给.net应用程序
发送通知的.net应用程序出来需要知道devicetoken之外,还需要一个与APNS连接的证书
这个证书可以通过我们前面生成的两个文件中得到
使用openssl
1,将aps_developer_identity.cer转换成aps_developer_identity.pem格式
openssl x509 -in aps_developer_identity.cer -inform DER -out aps_developer_identity.pem -outform PEM
2,将p12格式的私钥转换成pem,需要设置4次密码,密码都设置成:abc123
openssl pkcs12 -nocerts -out PushChat_Noenc.pem -in PushChat.p12
3,用certificate和the key创建PKCS#12格式的文件
openssl pkcs12 -export -in aps_developer_identity.pem -inkey PushChat_Noenc.pem -certfile PushChat.certSigningRequest -name aps_developer_identity -out aps_developer_identity.p12
这样我们就得到了在.net应用程序中使用的证书文件:aps_developer_identity.p12
在.net应用程序中发送通知
有个开源的类库:apns-sharp
地址是:http://code.google.com/p/apns-sharp/。
我们下载源代码,对里面的JdSoft.Apple.Apns.Notifications做相应的调整就能用了。
我们根据DeviceToken和p12File对JdSoft.Apple.Apns.Notifications.Test做相应的调整
string p12File = "aps_developer_identity.p12"
string p12FilePassword = "abc123"
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
========================================
调试阶段的证书
- aps_development.cer 电脑可以调试有推送功能的app的证书
- iOS_development.cer 电脑可以真机调试的证书
- xxx.mobileprovision 描述文件,其中确定了哪台手机和电脑可以进行调试
推送通知的5种界面形式
1,顶部通知,中间提醒,锁屏提醒,图标数字,通知中心
android实现推送方式解决方案
========================================
/*
1.有一种打开,叫做点击图标后的打开
2.还有一种打开,叫做 点击了 通知 之后的打开
当通过 点击通知 这种方法打开应用程序,执行didFinishLaunching方法时,launchOptions
参数中,就存着通知发来的消息,也就是 类似于
didReceiveRemote方法中的那个userInfo
*/
//通过registerforremotenotificationtype方法,告诉应用程序,能接受push来的通知
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([UIDevice currentDevice].systemVersion.doubleValue <= 8.0) {
//向服务器发请求,要注册推送功能,以此获取到服务器返回的deviceToken
//type 用来说明 支持的通知形式
//如 横幅 声音 角标
推送消息的类型
UIRemoteNotificationTypeNone 不接收推送消息
UIRemoteNotificationTypeBadge 接收图标数字
UIRemoteNotificationTypeSound 接收音频
UIRemoteNotificationTypeAlert 接收消息文字
UIRemoteNotificationTypeNewsstandContentAvailability 接收订阅消息
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert];
}else{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge| UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:settings];
//申请使用通知
[application registerForRemoteNotifications];
}
NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
UILabel *label = [[UILabel alloc]init];
label.frame = CGRectMake(0, 40, 300, 200);
label.numberOfLines = 0;
label.textColor = [UIColor whiteColor];
label.font = [UIFont systemFontOfSize:24];
label.backgroundColor = [UIColor blueColor];
label.text =[NSString stringWithFormat:@"%@",userInfo];
[self.window.rootViewController.view addSubview:label];
return YES;
}
//在AppDelegate中,发请求,询问是否要开通push功能,如果用户点击允许,则接收从服务器端发回的deviceToken(需要真机联网)
//只要获取到用户同意,则服务器端返 回deviceToken
//会自动执行下面的方法
//1417f54c c7f0adb0 48e3558f 2b8a8bad 0a6a5152 54af017e 32137cda 8cbdb9d0
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"%@",deviceToken);
}
/*
用户点击了通知,进入到应用程序中,需要捕获到这个时机
从而决定这一次的进入应用程序,到底要显示或执行什么动作,下面的方法就会在点击通知时自动调用
*/
/*
1.应用程序在前台时:通知到,该方法自动执行
2.应用程序在后台且没有退出时:通知到,只有点击了通知查看时,该方法自动执行
3.应用程序退出:通知到,点击查看通知,不会执行下面的didReceive方法,而是只执行didFinishLauncing方法
*/
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//NSLog(@"%@",userInfo);
//为了测试在应用程序退出后,该方法是否执行
//所以往第一个界面上添加一个label,看标签是否会显示一些内容
UILabel *label = [[UILabel alloc]init];
label.frame = CGRectMake(0, 250, 300, 200);
label.numberOfLines = 0;
label.textColor = [UIColor whiteColor];
label.font = [UIFont systemFontOfSize:24];
label.backgroundColor = [UIColor grayColor];
label.text =[NSString stringWithFormat:@"%@",userInfo];
[self.window.rootViewController.view addSubview:label];
}
/*
此方法是新的用于响应远程推送通知的方法
1.如果应用程序在后台,则通知到,点击查看,该方法自动执行
2.如果应用程序在前台,则通知到,该方法自动执行
3.如果应用程序被关闭,则通知到,点击查看,先执行didFinish方法,再执行该方法
4.可以开启后台刷新数据的功能
step1:点击target-->Capabilities-->Background Modes-->Remote Notification勾上
step2:在给APNs服务器发送的要推送的信息中,添加一组字符串如:
{"aps":{"content-available":"999","alert":"bbbbb.","badge":1}}
其中content-availabel就是为了配合后台刷新而添加的内容,999可以随意定义
*/
//配置通过点击了通知打开应用程序后要做的事情,可以在appdelegate中通过实现didReceiveRemoteNotification方法,就可以获取到用户点击了通知这个动作
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
UILabel *label = [[UILabel alloc]init];
label.frame = CGRectMake(0, 250, 300, 200);
label.numberOfLines = 0;
label.textColor = [UIColor whiteColor];
label.font = [UIFont systemFontOfSize:24];
label.backgroundColor = [UIColor grayColor];
label.text =[NSString stringWithFormat:@"%@",userInfo];
[self.window.rootViewController.view addSubview:label];
//NewData就是使用新的数据 更新界面,响应点击通知这个动作
completionHandler(UIBackgroundFetchResultNewData);
}
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ios玩转推送通知
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[self registerLocalNotification];
return YES;
}
-(void)registerLocalNotification
{
//创建消息上面要添加的动作
UIMutableUserNotificationAction *action1=[[UIMutableUserNotification alloc] init];
action1.identifier=kNotificationActionIdentifileStar;
action1.title=@“赞”;
//当点击的时候不启动程序,在后台处理
action1.activationMode=UIUserNotificationActivationModeBackground;
//需要解锁才能处理(意思就是如果在锁屏界面收到通知,并且用户设置了屏幕锁,用户点击了
赞不会直接进入我们的回调进行处理,而是需要用户输入屏幕锁之后才进入我们的回调),如果
action.activationMode=UIUserNotificationActionModeForeground;则这个属性被忽略
action1.authenticationRequired = YES;
}
该动作按钮创建完之后,我们需要的就是创建动作集合,并进行注册,代码如下
UIUserNotificationActionContextDefault 通知操作的默认Context,在这种情况下,你可以指定4个自定义操作。(还未验证)
UIUserNotificationActionContextMinimal 通知操作的最小Context,在这种情况下,你可以指定2个自定义操作。(还未验证)
当一个通知的所有动作被配置好了之后,他们可以被包进一个类目(categories)里。如果你的通知支持动作,那么你就必须创建一个类目 (categories)。通常情况下一个类目(category)配对一个通知,假设一个App中得所有通知都支持动作,那么这个App也会有和通知一 样多的类目(categories)。
我们只会在这个示例App中创建一个通知,所以这里也只会有一个类目(category)。从编程的角度来说,类目(category)就是一个 UIMutableUserNotificationCategory类的对象,这也是iOS8新引入的类。这个类只有一个属性和一个方法。标示符属性用 来表示一个唯一的类目(category),方法用来将多个动作包含进来。
//创建动作(按钮)的类别集合
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
//这组动作的唯一标示(kNotificationCategoryIdentifile为我定义的一个宏,可自行定义)
category.identifier = kNotificationCategoryIdentifile;
//最多支持两个,如果添加更多的话,后面的将被忽略
[category setActions:@[action1, action2] forContext:(UIUserNotificationActionContextMinimal)];
//创建UIUserNotificationSettings,并设置消息的显示类类型
UIUserNotificationSettings *uns = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound) categories:[NSSet setWithObject:category]];
[[UIApplication sharedApplication] registerUserNotificationSettings:uns];
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
1
2
3
4
5
6
7
8
|
//第二个动作
UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
action2.identifier = kNotificationActionIdentifileComment;
action2.title = @
"评论"
;
//当点击的时候不启动程序,在后台处理
action2.activationMode = UIUserNotificationActivationModeBackground;
//设置了behavior属性为 UIUserNotificationActionBehaviorTextInput 的话,则点击了该按钮会出现输入框供输入
action2.behavior = UIUserNotificationActionBehaviorTextInput;
|
1
2
|
//这个字典定义了当点击了评论按钮后,输入框右侧的按钮名称,如果不设置该字典,则右侧按钮名称默认为 “发送”
action2.parameters = @{UIUserNotificationTextInputActionButtonTitleKey: @
"评论"
};
|
// 本地通知回调函数,当应用程序在前台时调用
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
//在非本App界面时收到本地消息,下拉消息会有快捷回复的按钮,点击按钮后调用的方法,根据identifier来判断点击的哪个按钮,notification为消息内容
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler;
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~