【问题标题】:Saving the DeviceToken for Later Use in Apple Push Notification Services保存 DeviceToken 以供以后在 Apple 推送通知服务中使用
【发布时间】:2011-11-27 21:32:44
【问题描述】:

在我的 iPhone 应用程序中,我从 Apple 获取设备令牌,我在 Delegate 文件中分配了一个公共属性,如下所示:

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
   self.dToken = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding]; 
}

dToken 属性声明如下:

NSString *dToken;

@property (nonatomic,retain) NSString *dToken;

但是当我尝试从另一个文件中检索设备令牌时,我得到了 null 值。

+(NSString *) getDeviceToken
{
  NSString *deviceToken = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] dToken];

    NSLog(@" getDeviceToken = %@",deviceToken);  // This prints NULL

    return deviceToken; 

}

我做错了什么?

【问题讨论】:

    标签: ios push-notification devicetoken


    【解决方案1】:

    我建议你用这种方式将token转换为字符串:

    self.dToken = [[[deviceToken description]
                        stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] 
                        stringByReplacingOccurrencesOfString:@" " 
                        withString:@""];
    

    更新: 正如许多人提到的,最好使用下一种方法将NSData * 转换为NSString *

    @implementation NSData (Conversion)
    - (NSString *)hexadecimalString
    {
      const unsigned char *dataBuffer = (const unsigned char *)[self bytes];
    
      if (!dataBuffer) {
        return [NSString string];
      }
    
      NSUInteger          dataLength  = [self length];
      NSMutableString     *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
    
      for (int i = 0; i < dataLength; ++i) {
        [hexString appendFormat:@"%02lx", (unsigned long)dataBuffer[i]];
      }
    
      return hexString;
    }
    @end
    

    【讨论】:

    • 其实是getDeviceToken方法获取不到dToken的值。
    • 你确定didRegisterForRemoteNotificationsWithDeviceToken 被调用并且dToken被初始化了吗?
    • 实际上,您的 deviceToken 描述代码起到了作用。非常感谢!
    • 上面的代码可以工作(至少现在是这样),但不是很好的形式。读取 description 属性不应被视为对字符串进行 HEX 编码的可接受机制,因为它是用于调试描述,而不是用于编码!请参阅stackoverflow.com/questions/1305225/… 了解更正确的令牌序列化方法
    • @Nekto 感谢您的回答。正如签名所暗示的那样,一种改进是返回 NSString 的非可变副本。
    【解决方案2】:

    根据Best way to serialize an NSData into a hexadeximal string 的讨论,这里有一个更好的方法。更长,但如果 Apple 更改 NSData 发出调试器描述的方式,您的代码将是面向未来的。

    扩展 NSData 如下:

    @implementation NSData (Hex)
    - (NSString*)hexString {
        unichar* hexChars = (unichar*)malloc(sizeof(unichar) * (self.length*2));
        unsigned char* bytes = (unsigned char*)self.bytes;
        for (NSUInteger i = 0; i < self.length; i++) {
            unichar c = bytes[i] / 16;
            if (c < 10) c += '0';
            else c += 'A' - 10;
            hexChars[i*2] = c;
            c = bytes[i] % 16;
            if (c < 10) c += '0';
            else c += 'A' - 10;
            hexChars[i*2+1] = c;
        }
        NSString* retVal = [[NSString alloc] initWithCharactersNoCopy:hexChars
                                                               length:self.length*2 
                                                         freeWhenDone:YES];
        return [retVal autorelease];
    }
    @end
    

    【讨论】:

      【解决方案3】:

      我知道这是一个老问题,而且这可能是从那时起出现的新信息,但我想向所有声称使用描述方法的人指出一些事情真是个坏主意。在大多数情况下,你是完全正确的。 description 属性通常仅用于调试,但对于 NSData 类,它被明确定义为返回接收者内容的十六进制表示,这正是这里所需要的。由于 Apple 已将其放入他们的文档中,我认为只要他们更改它,您就很安全。

      这可以在此处的 NSData 类参考中找到:https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html

      【讨论】:

      • “既然 Apple 已经将它放在他们的文档中,我认为只要他们改变它,你就很安全”......一厢情愿的想法。
      猜你喜欢
      • 2010-12-10
      • 1970-01-01
      • 2017-11-18
      • 2010-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多