为 RubyMotion 中的推送通知获取 iOS 设备令牌

Getting the iOS device token for push notifciations in RubyMotion

我需要用户的设备令牌作为十六进制字符串来发送推送通知。我曾经使用 deviceToken 'description' 来做到这一点,但这在 iOS13 中不再起作用。我在 Objective-C 和 Swift.

中找到了几个解决方案

How can I convert my device token (NSData) into an NSString?

然而,问题是 RubyMotion 中的 deviceToken.bytes returns 和 Pointer。与 Objective-C 相比,调用 bytes[index] 会得到不同的结果。我尝试了很多不同的东西,但我似乎无法让它发挥作用。关于指针的 RubyMotion 文档也确实是准系统,因此这无济于事。我在 SO 上发现了以下关于指针的信息:

Pointer handling with RubyMotion

它说我必须做 bytes + index 而不是 bytes[index]。我目前有以下代码:

def application(application, didRegisterForRemoteNotificationsWithDeviceToken: device_token)
  string = token_to_string(device_token)
end

def token_to_string(device_token)
  data_length = device_token.length
  if data_length == 0
    nil
  else
    data_buffer = device_token.bytes
    token = NSMutableString.stringWithCapacity(data_length * 2)

    index = 0
    begin
      buffer = data_buffer + index
      token.appendFormat('%02.2hhx', buffer)
      index += 1
    end while index < data_length

    token.copy
  end
end

它没有给出任何错误,但生成的设备令牌似乎不正确。任何建议将不胜感激!

您好,我使用以下方法将 NSData 转换为 NSString,然后可以在 ruby 中对其进行操作。

class NSData
  def to_s
    NSString.alloc.initWithBytes(bytes, length: length, encoding: NSUTF8StringEncoding)
  end
end

我一直在想一个纯粹的 RubyMotion 解决方案,但我对 'Pointers' 的理解还不足以让它发挥作用。所以我采用了不同的方式:扩展 NSData class.

1) 在项目中创建文件夹 vendor/NSData+Hex。

2) 在文件夹中创建文件 NSData+Hex.h 并将其放入:

#import <Foundation/Foundation.h>

@interface NSData (Hex)

@property (nonatomic, copy, readonly) NSString *hexString;

@end

3) 现在在同一文件夹中创建 NSData+Hex.m 并将其放入文件中:

#import "NSData+Hex.h"

@implementation NSData (Hex)

- (NSString *) hexString
{
  NSUInteger len = self.length;
  if (len == 0) {
    return nil;
  }
  const unsigned char *buffer = self.bytes;
  NSMutableString *hexString  = [NSMutableString stringWithCapacity:(len * 2)];
  for (int i = 0; i < len; ++i) {
    [hexString appendFormat:@"%02x", buffer[i]];
  }
  return [hexString copy];
}

@end

4) 将此添加到您的 Rakefile 中:

app.vendor_project('vendor/NSData+Hex', :static)

5) 现在您只需在 def application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken).

内调用 deviceToken.hexString

如果有人能想到纯 RubyMotion 解决方案,请随时回答。目前,它至少在起作用。 :)

我执行以下操作:

    token = deviceToken.description.gsub(/[<> ]/, '')