iOS 13是否具有获取设备通知令牌的新方法?

Alf*_*lfi 14 apple-push-notifications ios13 xcode11

所以我的朋友从OneSignal收到了这封电子邮件

由于即将到来的iOS 13版本可能会发生更改,因此在使用Xcode 11构建应用程序之前,必须先更新到最新版本的iOSSDK。OneSignal的所有包装SDK(包括React Native,Unity和Flutter)都已经过也更新了。原因是与iOS 13一起发布的Xcode 11打破了OneSignal之类的应用程序和库用于获取设备推送令牌的通用技术。如果您不使用我们的新SDK,那么新用户将无法从您的应用订阅通知。

我对此感到好奇。

这是我们在iOS 12上获取设备通知令牌的方式

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    var token = ""
    for i in 0..<deviceToken.count {
        token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])
    }
    print("Notification token = \(token)")
}
Run Code Online (Sandbox Code Playgroud)

在iOS 13上获取它的正确方法是什么?我应该为当前开发的应用程序采用新方法还是旧方法仍然可行?

atu*_*tri 19

您可以使用此方法从iOS 13开始获取设备令牌:

目标C:

+ (NSString *)stringFromDeviceToken:(NSData *)deviceToken {
    NSUInteger length = deviceToken.length;
    if (length == 0) {
        return nil;
    }
    const unsigned char *buffer = deviceToken.bytes;
    NSMutableString *hexString  = [NSMutableString stringWithCapacity:(length * 2)];
    for (int i = 0; i < length; ++i) {
        [hexString appendFormat:@"%02x", buffer[i]];
    }
    return [hexString copy];
}
Run Code Online (Sandbox Code Playgroud)

Swift 5.0(未经测试)

class func string(fromDeviceToken deviceToken: Data?) -> String? {
    let length = deviceToken?.count ?? 0
    if length == 0 {
        return nil
    }
    let buffer = UInt8(deviceToken?.bytes ?? 0)
    var hexString = String(repeating: "\0", count: length * 2)
    for i in 0..<length {
        hexString += String(format: "%02x", buffer[i])
    }
    return hexString
}
Run Code Online (Sandbox Code Playgroud)

取自OneSignal博客


Eug*_*kov 12

这样做的方式很好,它应该可以继续在iOS 13上运行。但是有些开发人员是这样做的。要转换Data为基数为16的字符串,它们会调用description,返回类似

<124686a5 556a72ca d808f572 00c323b9 3eff9285 92445590 3225757d b83997ba>
Run Code Online (Sandbox Code Playgroud)

然后他们修剪<>和删除空格。

在iOS 13上,description被调用的令牌数据返回类似

{ length = 32, bytes = 0xd3d997af 967d1f43 b405374a 13394d2f ... 28f10282 14af515f }
Run Code Online (Sandbox Code Playgroud)

这显然使这种方式被打破了。

错误实现的另一个示例(已经编辑以包括正确的实现)。

该线程中可能还会找到更多示例。

  • 任何使用`description`将令牌转换为字符串的人都做错了。这从来不是正确的方法。 (2认同)