1、证书处理
测试证书是否正确:openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert apns-dev-cert.pem -key apns-dev-key.pem
2、APP处理
#pragma mark - 申请通知权限
// 申请通知权限
- (void)replyPushNotificationAuthorization:(UIApplication *)application{
if (IOS10_OR_LATER) {
//iOS 10 later
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
//必须写代理,不然无法监听通知的接收与点击事件
center.delegate =self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error && granted) {
//用户点击允许
NSLog(@"注册成功");
}else{
//用户点击不允许
NSLog(@"注册失败");
}
}];
// 可以通过 getNotificationSettingsWithCompletionHandler 获取权限设置
//之前注册推送服务,用户点击了同意还是不同意,以及用户之后又做了怎样的更改我们都无从得知,现在 apple 开放了这个 API,我们可以直接获取到用户的设定信息了。注意UNNotificationSettings是只读对象哦,不能直接修改!
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"========%@",settings);
}];
}else if (IOS8_OR_LATER){
//iOS 8 - iOS 10系统
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
}else{
//iOS 8.0系统以下
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
}
//注册远端消息通知获取device token
[application registerForRemoteNotifications];
}
#pragma mark - 获取device Token
//获取DeviceToken成功
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
//正确写法
NSString *deviceString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
deviceString = [deviceString stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"deviceToken===========%@",deviceString);
//将deviceToken发送给服务器
[self initNetworkState:[NSString stringWithFormat:@"%@",deviceToken]];
}
#pragma mark 获取DeviceToken失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(@"[DeviceToken Error]:%@\n",error.description);
}
#pragma mark 把deviceToken发送给服务器
-(void)initNetworkState:(NSString *)pToken{
//处理把deviceToken提交给服务器端
}
#pragma mark - 处理推送的消息内容
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSLog(@"%@", userInfo);
self.urlStr = [userInfo valueForKey:@"link"];
self.message = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber = [[[userInfo objectForKey:@"aps"] objectForKey:@"badge"] intValue];
//注意:在打开应用的时候,是需要一个弹框提醒的,不然用户看不到推送消息
if (application.applicationState == UIApplicationStateActive) {
if (self.urlStr.length > 0) {
// 处理推送消息
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"通知" message:@"我的信息" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
[alert show];
}else{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"通知" message:@"我的信息" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
[alert show];
}
}
}
3、后端推送
package com.szqws.crm.api.front;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import javapns.back.PushNotificationManager;
import javapns.back.SSLConnectionHelper;
import javapns.data.PayLoad;
@Controller
@CrossOrigin // 支跨域使用
@RequestMapping("/api")
public class pashAPI {
@RequestMapping(value = "push", method = RequestMethod.GET)
@ResponseBody
public JSONObject push() throws Exception {
try {
JSONObject jsonObject = new JSONObject();
// 从客户端获取的deviceToken,在此为了测试简单,写固定的一个测试设备标识。
String deviceToken = "063b6ed99282c6d737c92b41e483629e2df81c2b5e64de542655a7f25b6854e7";
System.out.println("Push Start deviceToken:" + deviceToken);
// 定义消息模式
PayLoad payLoad = new PayLoad();
payLoad.addAlert("this is test!");
payLoad.addBadge(1);// 消息推送标记数,小红圈中显示的数字。
payLoad.addSound("default");
// 注册deviceToken
PushNotificationManager pushManager = PushNotificationManager.getInstance();
pushManager.addDevice("iPhone", deviceToken);
// 连接APNS
String host = "gateway.sandbox.push.apple.com";
// String host = "gateway.push.apple.com";
int port = 2195;
String certificatePath = "/Users/luoxiaodong/Desktop/apns-dev-cert.p12";// 前面生成的用于JAVA后台连接APNS服务的*.p12文件位置
String certificatePassword = "szqws2019";// p12文件密码。
pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
// 发送推送
javapns.data.Device client = pushManager.getDevice("iPhone");
System.out.println("推送消息: " + client.getToken() + "\n" + payLoad.toString() + " ");
pushManager.sendNotification(client, payLoad);
// 停止连接APNS
pushManager.stopConnection();
// 删除deviceToken
pushManager.removeDevice("iPhone");
System.out.println("Push End");
return jsonObject;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}