6

这是我之前在 StackOverflow上的帖子的后续。

认为最好开始一个新帖子(因为我比以前取得了更多的进步),而不是在以前的线程上附加一个新问题。

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

以下是我已完成的步骤:

iPhone 开发者计划门户 (IDPP)

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

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

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

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

代码

当我在我的设备上构建和部署我的应用程序时能够获取我的设备令牌。

一旦我的 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 ");
       }   
    }
}

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();
     }
}

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

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...

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];
} 

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

在这一点上我真的很难过......

我可能做错了什么?:(

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

如果有人可以帮助我,我将不胜感激...

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

4

1 回答 1

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];
}

现在,我正在我的设备上接收通知!:)

祝大家编程愉快!

于 2009-09-04T21:50:42.297 回答