是啥导致此 BadDeviceToken 响应?
Posted
技术标签:
【中文标题】是啥导致此 BadDeviceToken 响应?【英文标题】:What is causing this BadDeviceToken response?是什么导致此 BadDeviceToken 响应? 【发布时间】:2021-09-13 16:09:40 【问题描述】:这是我注册推送通知的方式:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
//-- Set Notification
if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
// ios 8 Notifications: Registering for notifications and types
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[application registerForRemoteNotifications];
else
// iOS < 8 Notifications
_storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
_storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)];
if (launchOptions != nil)
NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
NSLog(@"Launched from push notification: %@", dictionary);
/*[self addMessageFromRemoteNotification:dictionary updateUI:NO];*/
return YES;
在上周,我一直在使用命令行工具发送推送通知中的以下终端命令成功地将测试推送通知发送到测试设备。
curl -v --header 'apns-topic: com.domain.appname' --header apns-push-type: alert --cert aps.cer --cert-type DER --key PushChatKey.pem --key-type PEM --data '"aps":"alert":"Hello From Faunna"' --http2 https://api.sandbox.push.apple.com/3/device/258ecf658e25256c8f06ddb1138d5d536ba0e760a96ebd12d3b1dbe112857c58
最近在创建配置文件并将其添加到 Xcode 后,该应用不再在调试窗口中打印设备令牌。 从配置文件下的 Apple Developer 帐户中删除配置文件后,我尝试使用该应用程序的备份版本,该版本仍将设备令牌打印到调试器窗口。 当我复制设备令牌并将其输入到终端命令中以发送另一个测试推送通知时,终端输出为 400 状态码:
"reason":"BadDeviceToken"* Closing connection 1
curl -v --header 'apns-topic: com.domain.appname' --header apns-push-type: alert --cert aps.cer --cert-type DER --key PushChatKey.pem --key-type PEM --data '"aps":"alert":"Test"' --http2 https://api.sandbox.push.apple.com/3/device/a146d82d4acea02c9ef6de5838174292d0e2cd18a40be17fb79334c5003a0058
* Could not resolve host: alert
* Closing connection 0
curl: (6) Could not resolve host: alert
* Trying 17.188.138.73...
* TCP_NODELAY set
* Connected to api.sandbox.push.apple.com (17.188.138.73) port 443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
Enter PEM pass phrase:
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=api.development.push.apple.com; OU=management:idms.group.533599; O=Apple Inc.; ST=California; C=US
* start date: Feb 8 21:41:22 2021 GMT
* expire date: Mar 10 21:41:22 2022 GMT
* subjectAltName: host "api.sandbox.push.apple.com" matched cert's "api.sandbox.push.apple.com"
* issuer: CN=Apple Public Server RSA CA 12 - G1; O=Apple Inc.; ST=California; C=US
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fbd4700aa00)
> POST /3/device/a146d82d4acea02c9ef6de5838174292d0e2cd18a40be17fb79334c5003a0058 HTTP/2
> Host: api.sandbox.push.apple.com
> User-Agent: curl/7.64.1
> Accept: */*
> apns-topic: com.faunna.PushChat
> Content-Length: 37
> Content-Type: application/x-www-form-urlencoded
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 1000)!
* We are completely uploaded and fine
< HTTP/2 400
< apns-id: 8DE6AA75-8E41-E95E-1FAF-51D93A8B3200
<
* Connection #1 to host api.sandbox.push.apple.com left intact
"reason":"BadDeviceToken"* Closing connection 1
是什么导致此设置中的BadDeviceToken
输出?从现在开始,我应该如何注册远程通知?
更新:
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
UINavigationController *navigationController = (UINavigationController*)_window.rootViewController;
ChatViewController *chatViewController = (ChatViewController*)[navigationController.viewControllers objectAtIndex:0];
DataModel *dataModel = chatViewController.dataModel;
NSString* oldToken = [dataModel deviceToken];
NSString* newToken = [deviceToken description];
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"My token is: %@", newToken);
[dataModel setDeviceToken:newToken];
if ([dataModel joinedChat] && ![newToken isEqualToString:oldToken])
[self postUpdateRequest];
【问题讨论】:
您能出示您的didRegisterForRemoteNotifications
代码吗?是否调用了该方法? didFailToRegisterForRemoteNotifications
被调用了吗?
我更新了问题。重新启动我的 MacBook 并再次运行应用程序后,调试器窗口根本不再打印设备令牌。它只是说registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later.
【参考方案1】:
在你提到的 cmets 中,你得到了
registerForRemoteNotificationTypes:iOS 8.0 及更高版本不支持
在您运行应用程序时在控制台中。
您的代码似乎遵循 registerForRemoteNotifications 并且您没有最新的令牌。
检查特定选择器并不是检查 iOS 版本的正确方法。
您应该使用 if (@available(iOS 8, *))
检查 iOS 版本并将您的 iOS 8+ 代码放入该块中。 (尽管此时您可能会放弃对 iOS 7 的支持)。
if (@available(iOS 8, *))
// iOS 8 Notifications: Registering for notifications and types
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[application registerForRemoteNotifications];
else
// iOS < 8 Notifications
_storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
你真的不应该在生产代码中使用description
;它真的只是为了调试,它的输出可以在没有通知的情况下改变。
您应该使用 dedicated code 将令牌转换为十六进制字符串
【讨论】:
在 if 语句的参数中,Xcode 给出了一个解析问题:Expected a version of the form 'major[.minor[.subminor]]'
。你知道如何解决这个问题吗?
抱歉,我打错了 - 8 不见了
我尝试使用更新的代码,但调试器仍然没有打印设备令牌?
应用程序正在接收带有更新代码的... Would Like to Send You Notifications
警报,但尚未将设备令牌打印到调试器窗口。
您是否在didRegisterForRemoteNotifications
和didFailToRegisterForRemoteNotifications
方法中设置了断点?是否调用了这些方法中的任何一个?【参考方案2】:
事实证明,我正在尝试使用 APS 权利设置为 development
的生产令牌。
【讨论】:
以上是关于是啥导致此 BadDeviceToken 响应?的主要内容,如果未能解决你的问题,请参考以下文章
Testflight - 通用推送通知客户端 SSL 证书 - BadDeviceToken