什麼是遠程消息推送功能
-
APP向系統註冊推送服務。
-
設備從APNs請求deviceToken。
-
通過代理方法將deviceToken返回給APP。
-
APP將deviceToken發送給應用後臺服務器(Provider)。
-
應用後臺服務器保存deviceToken,然後在需要推送通知的時候,給APNs發送信息,使用deviceToken標識所要送達的客戶端。
-
APNs將後臺服務器發過來的數據推送到設備。
-
設備將消息分發給應用程序。
環境配置
-
開發者賬號。
-
iOS真機(iPhone、iPad、iPod)。
-
後臺服務器。
-
網絡。
到現在爲止,我們已經生成了三個文件:
1、Push.certSigningRequest
2、Push.p12
3、aps_development.cer
接下來就是進行推送測試階段:
下面先試一試第一種方法,使用PushMeBaby。這是一個開源的Mac小程序,將ApplicationDelegate.m中添上deviceToken和證書的位置。
- (id)init {
self = [super init];
if(self != nil) {
//55e231f0 86257e00 eed93ac6 47b52c78 12abe79f 9c9d1c67 4c770589 36c9a235 ---- 保留空格
self.deviceToken = @"";
//推送內容,JSON格式
self.payload = @"{\"aps\":{\"alert\":\"喬幫主喬幫主喬幫主\",\"badge\":1}}";
//獲取證書路徑
self.certificate = [[NSBundle mainBundle] pathForResource:@"aps_development" ofType:@"cer"];
}
return self;}
發送通知的後臺應用程序如果用php, java 實現,除了需要知道deviceToken之外,還需要一個與APNS連接的證書。
這個證書可以通過我們前面生成的文件中得到。
$ cd ~/Desktop$ls aps_development.cer CertificateSigningRequest.certSigningRequest PushKey.p12
$ openssl x509 -in aps_development.cer -inform der -out PushCert.pem$ ls aps_development.cer CertificateSigningRequest.certSigningRequest PushCert.pem PushKey.p12
$ openssl pkcs12 -nocerts -out PushKey.pem -in PushKey.p12 Enter Import Password: MAC verified OK Enter PEM pass phrase: Verifying - Enter PEM pass phrase:
$ cat PushCert.pem PushKey.pem > ck.pem$ ls aps_development.cer CertificateSigningRequest.certSigningRequest ck.pem PushCert.pem PushKey.pem PushKey.p12
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushCert.pem -key PushKey.pem
$ php simplepush.php Connected to APNS Message successfully delivered2)JAVA來發送通知
1、將aps_development.cer轉換成aps_development.pem格式
- openssl x509 -in aps_development.cer -inform DER -out aps_development.pem -outform PEM
2、將p12格式的私鑰轉換成pem
- openssl pkcs12 -nocerts -out Push_Noenc.pem -in Push.p12
3、創建p12文件
- openssl pkcs12 -export -in aps_development.pem -inkey Push_Noenc.pem -certfile Push.certSigningRequest -name "aps_development" -out aps_development.p12
這樣我們就得到了在.net或java等後臺應用程序中使用的證書文件:aps_development.p12
核心代碼
import javapns.back.PushNotificationManager;
import javapns.back.SSLConnectionHelper;
import javapns.data.Device;
import javapns.data.PayLoad;
public class MainSend
{
public static void main(String[] args) throws Exception
{
try
{
//從客戶端獲取的deviceToken
String deviceToken = "3a20764942e9cb4c4f6249274f12891946bed26131b686b8aa95322faff0ad46";
System.out.println("Push Start deviceToken:" + deviceToken);
//定義消息模式
PayLoad payLoad = new PayLoad();
payLoad.addAlert("消息推送測試!");
payLoad.addBadge(4);
payLoad.addSound("default");
//註冊deviceToken
PushNotificationManager pushManager = PushNotificationManager.getInstance();
pushManager.addDevice("iPhone", deviceToken);
//連接APNS
String host = "gateway.sandbox.push.apple.com";
int port = 2195;
String path = "/Users/iMilo/Work.localized/iShop/project/service/iPush/";
String certificatePath = (path + "src/ipush/iPush.p12");
//certificatePath 步驟一中生成的*.p12文件位置
String certificatePassword = "Love24mm";
pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
//發送推送
Device client = pushManager.getDevice("iPhone");
pushManager.sendNotification(client, payLoad);
//停止連接APNS
pushManager.stopConnection();
//刪除deviceToken
pushManager.removeDevice("iPhone");
System.out.println("Push End");
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
iOS端代碼實現
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//判斷是否註冊了遠程通知
if (![application isRegisteredForRemoteNotifications]) {
UIUserNotificationSettings *uns = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:uns];
//註冊遠程通知
[application registerForRemoteNotifications];
}
return YES;}
//獲取DeviceToken成功
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"DeviceToken: {%@}",deviceToken);
//這裏進行的操作,是將Device Token發送到服務端
}
//註冊消息推送失敗
- (void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"Register Remote Notifications error:{%@}",[errorlocalizedDescription]);
}
//處理收到的消息推送
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(@"Receive remote notification : %@",userInfo);
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:@"溫馨提示"
message:@"推送成功!"
delegate:nil
cancelButtonTitle:@"確定"
otherButtonTitles:nil];
[alert show];
[alert release];
}
下面附上另外一份比較詳細的文章,感謝這位博友分享http://blog.csdn.net/showhilllee/article/details/8631734
另一位博友的三篇文章:(
http://blog.sina.com.cn/s/blog_6afb7d800101fa29.html
http://blog.sina.com.cn/s/blog_6afb7d800101fafl.html
http://blog.sina.com.cn/s/blog_6afb7d800101faiz.html
)
以及另一位博友摘錄的國外的文檔:http://blog.csdn.net/kepoon/article/details/22384375
另附上對Certificate、App Id、Identifiers 和 Provisioning Profile理解的文章:http://www.th7.cn/Program/IOS/201406/218729.shtml