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

Posted

技术标签:

【中文标题】使用 Java 和 REST 发送 Apple 推送通知时出现问题【英文标题】:Problem sending Apple Push Notification using Java and REST 【发布时间】:2009-09-03 10:07:17 【问题描述】:

这是我之前在 *** 上的posting 的后续。

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

我正在使用 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 ");
          
    

RESTful 网络服务

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

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

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 新手)?

如果有人能帮我解决这个问题,我将不胜感激......

感谢您抽出宝贵时间阅读本文...

【问题讨论】:

令牌字符串包含一个空格。是你复制代码的时候引入的吗?尝试删除它。 嗨 Saeed... 是的,在我复制代码时引入了令牌字符串的空格(并重新格式化了代码以使其在此处更直观)。在我的实际代码中没有空格。我仍然被困住,所以如果有人可以帮助我,我将不胜感激。我运行的小飞贼,当我运行 Web 服务时,它会询问我是否希望连接到端口 2195 并发送推送通知。它只是没有出现在我的 iPhone 应用程序上。有什么我做错了吗?是 REST 代码吗? 您还应该包含您已实现的 UIApplicationDelegate 的“处理远程通知”方法的代码。 bpapa,感谢您的建议...感谢您的回复! 【参考方案1】:

找到解决方案!生成的设备令牌字符串似乎太长了。

我的 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];

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

祝大家编程愉快!

【讨论】:

以上是关于使用 Java 和 REST 发送 Apple 推送通知时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

Apple 健康数据的 REST API [关闭]

如何在 Spring Rest Call 中使用 GridFS 从 Mongodb 发送和检索图像?

从本机 Java Rest 客户端发送 Http Post [重复]

如何使用 REST 将 Json 字符串发送到 android 参数中的 java webservice?

Java Rest 发送双精度值

使用 Swift(使用 SwiftJWT)和 REST API 连接到 Apple Store Connect - 失败并出现 401