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.



参考:

一、
二、
三、
四、
官方 英文版
相关文章
相关标签/搜索