iPhone Push消息全攻略.1

要作一個iPhone Push消息的需求,從簡單test的開始。html

一、先添加一個app IDjava


二、點擊Edit來配置push服務。

三、生成兩個證書,一個用於開發,一個用於發佈。

四、按下圖操做建立一個csr文件而後continue。

4.1 打開應用程序->實用工具->鑰匙串訪問。按以下菜單請求一個證書。

4.2 以下圖


五、選擇剛纔建立好的csr文件生成證書

六、下載後雙擊cer文件導入系統。接着建立Provisioning Profile。

選擇咱們剛建立的app id。
一步步continue,最後generate。

七、Download以後導入profile到Xcode。
八、將SSL證書和key安裝到推送服務器上。先找到個人證書,以下:

8.1 選中兩項,右鍵「導出兩項」


8.2 會提示生成一個文件密碼,密碼能夠爲空,不輸入直接點好。

tips:
也能夠經過以下方式生成profile,在Organizer裏new一個Profile。


而後到member center裏下載profile,導入到真實iphone設備。據 這篇文章說只能保留一個。


九、開始開發前,先了解下DeviceToken

device token,即設備令牌,不是系統惟一標識(見獲取iOS設備的基本信息),須要在應用啓動時發起到apple服務器請求,註冊本身的設備和應用,並得到這個device token。ios

device token有什麼用?若是應用須要push notification給手機,那麼它要有個服務器端(provider),可是它發出的信息不是直接給手機的,而是必須統一交給apple的服務器,這個服務器就是apple push notification server(apns)。apple服務器經過這個token,知道應用要發的消息是給哪一個手機設備的,並轉發該消息給手機,手機再通知應用程序。

十、建立一個Single View Application應用來獲取DeviceToken
修改Delegate文件,要在頭文件裏定義變量: @property  ( strong ,  nonatomic )  UIViewController  *viewController;

//
//  com_sencloud_testAppDelegate.m
//  test
//
//  Created by chen minglei on 13-7-11.
//  Copyright (c) 2013   chen minglei. All rights reserved.
//

#import   "com_sencloud_testAppDelegate.h"

@implementation   com_sencloud_testAppDelegate

@synthesize   window;
@synthesize   viewController;

- (
void )applicationDidFinishLaunching:( UIApplication   *)application {
    [
window addSubview:viewController.view];
    [windowmakeKeyAndVisible];
   
    NSLog(@"Registering for push notifications...");
    [[UIApplicationsharedApplication]
     registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeAlert |
      UIRemoteNotificationTypeBadge |
      UIRemoteNotificationTypeSound)];
   
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
   
    NSString *str = [NSString
                     stringWithFormat:@"Device Token=%@",deviceToken];
    NSLog(str);
   
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
   
    NSString *str = [NSStringstringWithFormat@"Error: %@", err];
    NSLog(str);
   
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
   
    for (id key in userInfo) {
        NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]);
    }
   
}

@end
git


tips:
遇到這個問題:
Error in registration. Error: Error Domain=NSCocoaErrorDomain Code=3000 "未找到應用程序的「aps-environment」的權利字符串" UserInfo=0x123290 {NSLocalizedDescription=未找到應用程序的「aps-environment」的權利字符串}
緣由是Code Signing Identity不對,而這個不對的緣由是profile doesn't match bundle identifier,

必須在建立工程的時候設置正確,才能正常運行。以下圖:

十一、運行後debug view窗口獲得:

2013-07-11 21:18:36.139 test[6386:907] Registering for push notifications...
2013-07-11 21:19:05.988 test[6386:907] Device Token=<c8cd88d5 9c0d7407 fc697357 3d3778e5 5e83b92e d40c7588 a595be18 119c6f92>
github


十二、寫provider端代碼。
import javapns.back.PushNotificationManager;
import javapns.back.SSLConnectionHelper;
import javapns.data.Device;
import javapns.data.PayLoad;

public class ApnsAct {
	public static void main(String[] args) throws Exception {
		try {
			String deviceToken = "c8cd88d59c0d7407fc6973573d3778e55e83b92ed40c7588a595be18119c6f92";

			PayLoad payLoad = new PayLoad();
			payLoad.addAlert("Test");
			payLoad.addBadge(4);
			payLoad.addSound("default");

			PushNotificationManager pushManager = PushNotificationManager
					.getInstance();
			pushManager.addDevice("iPhone", deviceToken);

			// Connect to APNs
			String host = "gateway.sandbox.push.apple.com";
			int port = 2195;
			String certificatePath = "/Users/plan9x/Desktop/test.p12";
			String certificatePassword = "test";
			pushManager.initializeConnection(host, port, certificatePath,
					certificatePassword,
					SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);

			// Send Push
			Device client = pushManager.getDevice("iPhone");
			pushManager.sendNotification(client, payLoad);
			pushManager.stopConnection();

			pushManager.removeDevice("iPhone");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


tips:
調試過程報了錯以下,網上查是空密碼致使,加上密碼test從新生成p12文件:

java.io.IOException : failed to decrypt safe contents entry:   java.lang.ArithmeticException : / by zero
at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1277)
at java.security.KeyStore.load(KeyStore.java:1183)
at javapns.back.SSLConnectionHelper.<init>(Unknown Source)
at javapns.back.PushNotificationManager.initializeConnection(Unknown Source)
服務器

at com.moco.cms.action.front.ApnsAct.main( ApnsAct.java:27 )
pfonseka opened this issue 2 years ago

Problem with empty or null password in 'APNS.newService().withCert(certificate.p12, password)'

No milestone
No one is assigned

When a password was not defined on keyStore generation I have the following situations:app

1 - Using a null password in APNS.newService().withCert(certificate.p12, password) returns a "NullPointerException";iphone

2 - Using an empty password in APNS.newService().withCert(certificate.p12, password) returns "java.io.IOException: failed to decrypt safe contents entry: java.lang.ArithmeticException: / by zero"ide


This is a known Java library bug with p12 certificates with no passwords,  reported as bug 6415637, and affects any Java library basically.
This will not be fixed in the library, but will have  withCert  throw an  IllegalArgumentException  instead.



參考:

一、
二、
三、
四、
官方 英文版
相關文章
相關標籤/搜索