将需要推送的信息提交到APNS(Apple Push Notification Service)
由APNS
找到对应的设备,并将信息推到终端上,终端上再推到客户端APP上
远程推送流程
(1)
创建证书(MAC证书)
(2)
导出秘钥(可以到处秘钥共享给其他MAC)
(3)
创建provision(APP
授权
)
远程推送原理
2.确定这时可以真机调试
3.将App IDs添加推送通知的服务
4.创建调试证书
5.选择请求文件
6.创建为MAC授权的推送证书 点确认,创建完成后 下载到本地 双击安装
7provision文件更新一下 下载到本地 双击安装.
8.设置plist文件
9.AppDelegate文件配置
#define IS_IOS8_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >=
8.0
)
- (
BOOL
)application:(
UIApplication
*)application didFinishLaunchingWithOptions:(
NSDictionary
*)launchOptions {
// 远程通知 注册 if ( IS_IOS8_LATER ) { UIUserNotificationSettings *settings = [ UIUserNotificationSettings settingsForTypes : UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories : nil ]; [application registerUserNotificationSettings :settings]; } else {
[application
registerForRemoteNotificationTypes:
UIRemoteNotificationTypeBadge
|
UIRemoteNotificationTypeAlert
|
UIRemoteNotificationTypeSound
];
}
//从未运行到运行时会有通知信息传递
//
程序在未启动或者后台的时候,用户点击通知才会调用
if
(launchOptions) {
/// 获取到推送相关的信息 NSDictionary *userInfo = [launchOptions objectForKey : UIApplicationLaunchOptionsRemoteNotificationKey ];
UIAlertView
*alert = [[
UIAlertView
alloc
]
initWithTitle
:
@"
温馨提示
"
message
:[
NSString
stringWithFormat
:
@"%@---taskID:%@"
, [[userInfo
objectForKey
:
@"aps"
]
objectForKey
:
@"alert"
], [userInfo
objectForKey
:
@"taskID"
]]
delegate
:
nil
cancelButtonTitle
:
@"
确认
"
otherButtonTitles
:
nil
];
[alert show];
NSLog
(
@"%@"
, userInfo);
}
return
YES
;
} // 这个方法在用户推送注册成功后调用,在此方法注册推送 - ( void )application:( UIApplication *)application didRegisterUserNotificationSettings:( UIUserNotificationSettings *)notificationSettings { [application registerForRemoteNotifications ];
}
//从后台切换到前台或者应用在前台时调用
//
接收到远程通知以后的处理
应用程序处在打开状态时调用,
如果你的程序正在后台运行,
用户点击通知,
会在你的程序进入前台后才会被调用,直接点APP进入不会触发
- (
void
)application:(
UIApplication
*)application didReceiveRemoteNotification:(
NSDictionary
*)userInfo{
// 将应用的 icon 上,未读推送 +1 application. applicationIconBadgeNumber ++; // 取出后台推送过来的信息(取值方法一般都一样,这里只需要改处理方法) if ([[userInfo objectForKey : @"aps" ] objectForKey : @"alert" ] != NULL ) { UIAlertView *alert = [[ UIAlertView alloc ] initWithTitle : @" 温馨提示 " message :[[userInfo objectForKey : @"aps" ] objectForKey : @"alert" ] delegate : nil cancelButtonTitle : @" 确认 " otherButtonTitles : nil ]; [alert show ];
}
}
//iOS7以后用来处理后台任务接收到的远程通知
//通知到达时 点击App图标触发的方法 需要服务端在消息JSON里面添加 一个key和value("
content-available":"1"
)但是当程序未运行时 此方法依然不会触发
//{"aps":{"content-available":1,"sound":"a","alert":"How are you?","badge":1},"para1":"1231dfasfwer"}
- (
void
)application:(
UIApplication
*)application didReceiveRemoteNotification:(
NSDictionary
*)userInfo
fetchCompletionHandler:( void (^)( UIBackgroundFetchResult ))completionHandler { NSLog ( @"Remote Notification userInfo is %@" , userInfo); NSNumber *contentID = userInfo[ @"content-id" ]; UIAlertView *alert = [[ UIAlertView alloc ] initWithTitle : @" 温馨提示 " message :[ NSString stringWithFormat : @"%@---taskID:%@" , [[userInfo objectForKey : @"aps" ] objectForKey : @"alert" ], [userInfo objectForKey : @"taskID" ]] delegate : nil cancelButtonTitle : @" 确认 " otherButtonTitles : nil ]; [alert show ]; completionHandler( UIBackgroundFetchResultNewData );
}
//
注册推送成功后调用该方法
-( void )application:( UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:( NSData *)deviceToken{
#if !TARGET_IPHONE_SIMULATOR
// 将 token 转换成 string ,一般会将 token 中的 <> 与空格去掉后传给后台 NSString *token = [ NSString stringWithFormat : @"%@" , deviceToken]; token = [token stringByReplacingOccurrencesOfString : @" " withString : @"" ]; token = [token stringByReplacingOccurrencesOfString : @"<" withString : @"" ]; token = [token stringByReplacingOccurrencesOfString : @">" withString : @"" ]; NSLog ( @"%@" , token); //app 名称 NSString *appName = [[[ NSBundle mainBundle ] infoDictionary ] objectForKey : @"CFBundleDisplayName" ]; //app 版本 NSString *appVersion = [[[ NSBundle mainBundle ] infoDictionary ] objectForKey : @"CFBundleVersion" ]; // 取得注册类型 NSUInteger rntypes = [[ UIApplication sharedApplication ] isRegisteredForRemoteNotifications ]; NSString *pushBadge = (rntypes & UIUserNotificationTypeBadge ) ? @"enabled" : @"disabled" ; NSString *pushAlert = (rntypes & UIUserNotificationTypeAlert ) ? @"enabled" : @"disabled" ; NSString *pushSound = (rntypes & UIUserNotificationTypeSound ) ? @"enabled" : @"disabled" ; UIDevice *dev = [ UIDevice currentDevice ]; NSString *deviceName = dev. name ; NSString *deviceModel = dev. model ; NSString *deviceSystemVersion = dev. systemVersion ; NSString *host = @"121.199.25.24/pushchat" ; NSString *urlString = [ NSString stringWithFormat : @"/apns.php?task=%@&appname=%@&appversion=%@&devicetoken=%@&devicename=%@&devicemodel=%@&deviceversion=%@&pushbadge=%@&pushalert=%@&pushsound=%@" , @"register" , appName,appVersion, token, deviceName, deviceModel, deviceSystemVersion, pushBadge, pushAlert, pushSound]; // NSURL *url = [[NSURL alloc] initWithScheme:@"http" host:host path:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; // NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; // [NSURLConnection sendAsynchronousRequest:request // queue:[NSOperationQueue mainQueue] // completionHandler:^(NSURLResponse *urlR, NSData *returnData, NSError *e) { // NSLog(@"Return Data: %@", returnData); // }];
#endif
}
// 注册推送失败后调用该方法 - ( void )application:( UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:( NSError *) error { NSLog ( @"Registfail%@" ,error);
}
- (
void
)applicationWillEnterForeground:(
UIApplication
*)application {
application. applicationIconBadgeNumber = 0 ;
}
//远程推送转本地通知
- (
void
)sendNotification:(
NSString
*)message {
NSDateFormatter *formatter = [[ NSDateFormatter alloc ] init ]; [formatter setDateFormat : @"yyyy-MM-dd HH:mm:ss" ]; NSString *dateString = [formatter stringFromDate :[ NSDate date ]]; UIApplication *application = [ UIApplication sharedApplication ]; UILocalNotification *notification = [ UILocalNotification new ]; notification. repeatInterval = 0; [notification setAlertBody :[ NSString stringWithFormat : @"%@: %@" , dateString, message]]; [notification setFireDate :[ NSDate dateWithTimeIntervalSinceNow :1]]; [notification setTimeZone :[ NSTimeZone defaultTimeZone ]]; [notification setSoundName : UILocalNotificationDefaultSoundName ]; [application scheduleLocalNotification :notification];
}
|
其实我们只需要在任何时候设置 UIApplication.applicationIconBadgeNumber 属性为0,就可以让这个数字消失掉。
一般我们会选择在应用启动的时候(application:didFinishLaunchingWithOptions:方法中),或者干脆一点,在应用每次被切换到前台的时候(applicationWillEnterForeground:方法中),调用这一行代码,即可立刻清除掉Badge数字了。
通过OPENSSL文件合并
Java用.p12
1.在钥匙串->开发者证书 找到刚才所添加进去的证书私钥 右键导出p12
2.进入终端 ,将APNS证书
aps_development.cer转成PushChatCert.pem
openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem
3.
openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12
生成p12私钥 .pem文件(需设置密码,服务端推送时要用)
4.利用PushChatCert.pem和新生成的PushChatKey.pem合成一个新的p12文件(这个p12是提供给服务器推送用的)
openssl pkcs12 -export -in PushChatCert.pem -inkey PushChatKey.pem -certfile CertificateSigningRequest.certSigningRequest -name "aps_developer_identity" -out aps_developer_identity.p12
合成PHP所用的PEM文件
- openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem
- openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12
- cat PushChatCert.pem PushChatKey.pem > newck.pem
远程推送测试