使用Java和REST发送Apple推送通知时出现问题

mw_*_*guy 6 java iphone rest push-notification apple-push-notifications

这是我之前在StackOverflow 上发布的内容的后续内容.

想更好地开始一个新帖子(因为我比以前取得了更多进展)而不是在前一个帖子上添加新问题.

使用Google Code上的Javapns库通过基于REST的Web服务发送Apple推送通知...

以下是我完成的步骤:

iPhone开发人员计划门户网站(IDPP):

(1)创建基于App ID和APNS的SSL证书和密钥.

(2)创建并安装了配置文件.

(3)在服务器上安装SSL证书和密钥.

(4)设置我的iPhone应用程序以注册远程通知.

XCode:

我在构建应用程序并将其部署到设备上时能够获取设备令牌.

一旦我的iPhone应用程序部署,我的iPhone上就出现了一个对话框,表明我的应用程序想要发送推送通知,并且还要求允许它们.

当我通过我的Log4J语句调用我的Web服务时,我能够看到我的基于REST的Web服务确实已被调用,但我从未在我的iPhone应用程序上收到推送通知!

ApnsManager类:

public class ApnsManager {

    /** APNs Server Host **/
    private static final String HOST = "gateway.sandbox.push.apple.com";

    /** APNs Port */
    private static final int PORT = 2195;

    public void sendNotification(String deviceToken) 
    throws Exception {
       try {
           PayLoad payLoad = new PayLoad();
           payLoad.addAlert("My alert message");
           payLoad.addBadge(45);
           payLoad.addSound("default");

           PushNotificationManager pushManager = 
              PushNotificationManager.getInstance();

           pushManager.addDevice("iPhone", deviceToken);

           log.warn("Initializing connectiong with APNS...");

           // Connect to APNs
           pushManager.initializeConnection(HOST, PORT,
           "/etc/Certificates.p12", "password", 
           SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);

           Device client = pushManager.getDevice("iPhone");

           // Send Push
           log.warn("Sending push notification...");
           pushManager.sendNotification(client, payLoad);
           pushManager.stopConnection();
       } 
       catch (Exception e) {
           e.printStackTrace("Unable to send push ");
       }   
    }
}
Run Code Online (Sandbox Code Playgroud)

RESTful Web服务:

 @Path(ApnService.URL)
 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
 public class ApnService {
    public static final String URL = "/apns";

    @GET
    @Path("send")
    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public String send() throws JSONException, IOException {
        String msg = "";

        try {
            log.debug("Inside ApnService.send() method.");
            log.debug("Sending notification to device");
            ApnManager.sendNotification("32b3bf28520b977ab8eec50b482
            25e14d07cd78 adb69949379609e40401d2d1de00000000738518e5c
            000000003850978c38509778000000000000000000398fe12800398f
            e2e0398fe1040000");
         } catch(Exception e ) {
               e.printStackTrace();
               msg = "fail";
         }
         msg = "success";

         StringWriter sw = new StringWriter();
         JsonFactory f = new JsonFactory();
         JsonGenerator g = f.createJsonGenerator(sw);

         g.writeStartObject();
         g.writeStringField("status", msg);
         g.writeEndObject();
         g.close();

         return sw.toString();
     }
}
Run Code Online (Sandbox Code Playgroud)

现在,当我将我的应用程序部署到我的应用服务器并打开一个休息客户端并输入时:

http:// localhost:8080/myapp/apns/send

其余客户端返回:

HTTP/1.1 200好的

以下日志消息输出到我的控制台:

01:47:51,985 WARN  [ApnsManager] Initializing connectiong with APNS...
01:47:52,318 WARN  [ApnsManager] Sending push notification...
Run Code Online (Sandbox Code Playgroud)

MyAppDelegate.m

- (void) applicationDidFinishLaunching : 
  (UIApplication*) application 
{   
  NSLog( @"LAUNCH" );

  // Configure REST engine
  RESTAPI* api = [RESTAPI getInstance];
  [api setNetworkAddress:kLocalAddress port:kDefaultPort];

  UIRemoteNotificationType notificationTypes 
     = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound;
  if ([[UIApplication sharedApplication] enabledRemoteNotificationTypes] 
      != notificationTypes) {
       NSLog(@"Registering for remote notifications...");
       [[UIApplication sharedApplication]
       registerForRemoteNotificationTypes:notificationTypes];
   } else {
       NSLog(@"Already registered for remote notifications...");
       // Uncomment this if you want to unregister
       // NSLog(@"Unregistering for remote notifications...");
       // [[UIApplication sharedApplication] unregisterForRemoteNotifications];
   }

 mainWindow = [[[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds] retain];
 toolsNav = [[[ToolsNav alloc] init] retain];

 [mainWindow addSubview:toolsNav.view];
 [mainWindow makeKeyAndVisible];
} 
Run Code Online (Sandbox Code Playgroud)

但是,我没有在我的应用程序上收到推送通知(驻留在我的iPhone上)!

我真的很难过......

我怎么可能做错了?:(

这是我设置RESTful Web服务的方式的问题(对不起,我是REST的新手)?

如果有人能帮助我,我会非常感激...

感谢您抽出时间来阅读...

mw_*_*guy 5

发现了解决方案!生成的设备令牌字符串似乎太长了.

我的NSData到十六进制代码是打印错误的令牌(它应该是64个字符,在它是155个字符之前).

方案:

- (NSString *)hexadecimalDescription 
{
    NSMutableString *string = [NSMutableString stringWithCapacity:[self length] * 2];
    const uint8_t *bytes = [self bytes];

    for (int i = 0; i < [self length]; i++)
        [string appendFormat:@"%02x", (uint32_t)bytes[i]];

    return [[string copy] autorelease];
}
Run Code Online (Sandbox Code Playgroud)

现在,我收到了我的设备上的通知!:)

祝大家愉快!