在 iOS 8 中获取设备令牌
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24426090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get Device Token in iOS 8
提问by Pankaj
I need device token to implement push notification in my app.
How can I get device token since didRegisterForRemoteNotificationsWithDeviceToken
method is not working on iOS 8.
I tried this code in app delegate but it is not giving me device token.
我需要设备令牌来在我的应用程序中实现推送通知。
由于didRegisterForRemoteNotificationsWithDeviceToken
方法在 iOS 8 上不起作用,我如何获取设备令牌。我在应用程序委托中尝试了此代码,但它没有给我设备令牌。
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
回答by Madao
Read the code in UIApplication.h.
阅读 UIApplication.h 中的代码。
You will know how to do that.
你会知道如何做到这一点。
First:
第一的:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
add Code like this
添加这样的代码
#ifdef __IPHONE_8_0
//Right, that is the point
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
#else
//register to receive notifications
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
#endif
if you not using both Xcode 5 and Xcode 6,try this code
如果您没有同时使用 Xcode 5 和 Xcode 6,请尝试此代码
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[application registerUserNotificationSettings:settings];
} else {
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
(Thanks for @zeiteisen @dmur 's remind)
(感谢@zeiteisen @dmur 的提醒)
Second:
第二:
Add this Function
添加此功能
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:@"declineAction"]){
}
else if ([identifier isEqualToString:@"answerAction"]){
}
}
#endif
And your can get the deviceToken in
你可以得到 deviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
if it still not work , use this function and NSLog the error
如果它仍然不起作用,请使用此功能并 NSLog错误
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
回答by Juan de la Torre
Appending a small validation to @Madao's response in case you are having crashes on older iOS versions:
为@Madao 的响应附加一个小的验证,以防您在较旧的 iOS 版本上崩溃:
#ifdef __IPHONE_8_0
if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
#endif
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeNewsstandContentAvailability;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
What the __IPHONE_8_0
macro does is just allowing you to compile in older versions of xCode/iOS, you don't get compilation errors or warnings, but running the code on devices with iOS 7 or lower will cause a crash.
该__IPHONE_8_0
宏的作用只是允许您在旧版本的 xCode/iOS 中进行编译,您不会收到编译错误或警告,但在 iOS 7 或更低版本的设备上运行代码会导致崩溃。
回答by ChenSmile
To get Device token in iOS8 +
在 iOS8 + 中获取设备令牌
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//This code will work in iOS 8.0 xcode 6.0 or later
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeNewsstandContentAvailability| UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
return YES;
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString* deviceToken = [[[[deviceToken description]
stringByReplacingOccurrencesOfString: @"<" withString: @""]
stringByReplacingOccurrencesOfString: @">" withString: @""]
stringByReplacingOccurrencesOfString: @" " withString: @""] ;
NSLog(@"Device_Token -----> %@\n",deviceToken);
}
回答by Fattie
2020 solution
2020解决方案
Six steps,
六个步骤,
1. library
1. 图书馆
2. add to AppDelegate
2.添加到AppDelegate
// APNs:
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print(">> getting an APNs token works >>\(deviceToken)<<")
let tokenAsText = deviceToken.map { String(format: "%02.2hhx", import UserNotifications
) }.joined()
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print(">> error getting APNs token >>\(error)<<")
}
3. in your app
3. 在你的应用中
For example, after user logon
例如,用户登录后
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
askNotifications()
}
func askNotifications() {
let n = UNUserNotificationCenter.current()
n.requestAuthorization(options: [.alert, .sound, .badge]) {
granted, error in
print("result \(granted) \(String(describing: error))")
guard granted else {
print("not granted!")
return
}
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
and
和
-(void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
4. capabilities tab
4. 能力选项卡
do threeitems
做3项
beware of old articles:there is no longer an "on switch" there.
当心旧文章:那里不再有“开关”。
5. tethered phone, no simulator
5. 绑定手机,没有模拟器
it will notwork in simulator. must be a phone
它会不会在模拟器工作。必须是电话
tethered phone is fine, console will work fine
系留电话很好,控制台可以正常工作
6. and finally ... WIFI DANCE
6.最后...... WIFI DANCE
With 100% repeatability, as of 2020 you MUSTdo the following:
凭借 100% 的可重复性,截至 2020 年,您必须执行以下操作:
- completely eraseapp from tethered phone
- buildto the phone and run from Xcode (it definitelywon't work)
- force quit the app
- completely eraseapp from tethered phone
- turn off both wifi/cell
- buildto the phone and run from Xcode (obviously it won't work)
- force quit the app
- 从系留手机中完全擦除应用程序
- 构建到手机并从 Xcode 运行(它绝对行不通)
- 强制退出应用
- 从系留手机中完全擦除应用程序
- 关闭两个wifi/手机
- 构建到手机并从 Xcode 运行(显然它不起作用)
- 强制退出应用
then in exactly this order:
然后完全按照这个顺序:
- completely eraseapp from tethered phone
- turn on connectivity (either wifi or cell is fine - no problem)
- build to the phone and run from Xcode
- 从系留手机中完全擦除应用程序
- 打开连接(wifi 或手机都可以 - 没问题)
- 构建到手机并从 Xcode 运行
It now works. (And will work from here onwards.)
它现在可以工作了。(并且将从这里开始工作。)
The WIFI DANCE is just one of those weird Apple things. They have not fixed it yet (Xcode 11.3). In fact it has become "100% repeatable": you have to do the WIFI DANCE.
WIFI DANCE 只是 Apple 那些奇怪的东西之一。他们还没有修复它(Xcode 11.3)。事实上,它已经变得“100% 可重复”:你必须做 WIFI DANCE。
回答by dave
Aside from the rest of the condescending answers to this question, the most likely reason that this issue might occur for an informed developer who has implemented all the required delegate methods is that they are using a wild card provisioning profile(why wouldn't you? It makes it so easy to create and test development apps!)
除了对这个问题的其他居高临下的回答之外,对于已经实现了所有必需委托方法的知情开发人员来说,发生此问题的最可能原因是他们使用了通配符配置文件(为什么不呢?它使创建和测试开发应用程序变得如此容易!)
In this case, you'll probably see the error Error Domain=NSCocoaErrorDomain Code=3000 "no valid 'aps-environment' entitlement string found for application"
在这种情况下,您可能会看到错误 Error Domain=NSCocoaErrorDomain Code=3000 "no valid 'aps-environment' entitlement string found for application"
In order to test notifications, you actually have to go back to 2000 and late, log into developer.apple.com, and set up your application-specific provisioning profile with push notifications enabled.
为了测试通知,您实际上必须回到 2000 年或更晚,登录 developer.apple.com,并在启用推送通知的情况下设置特定于应用程序的配置文件。
- Create an App ID corresponding to your app's bundle identifier. Be sure to check off "push notifications" (currently 2nd option from the bottom).
- Create a provisioning profile for that App ID.
- Go through the rest of the horrible provisioning steps we'd all love to forget.
- ?
- Profit!
- 创建与您的应用程序包标识符对应的应用程序 ID。请务必勾选“推送通知”(目前是底部的第二个选项)。
- 为该 App ID 创建一个配置文件。
- 完成我们都想忘记的其余可怕的配置步骤。
- ?
- 利润!
回答by Trianna Brannon
On your developer account make sure you have your push notifications setup properly in your app ID and then you need to regenerate and download your provisioning profile. My problem was that I had downloaded the provisioning profile but xcode was running the incorrect one. To fix this go to your Target Build Settings, scroll down to Code Signing, under the provisioning profile section make sure that you are using the correct provisioning profile that matches the name of the one you generated (there should be a dropdown with options if you have installed more than one).
在您的开发者帐户中,确保您在应用 ID 中正确设置了推送通知,然后您需要重新生成并下载您的配置文件。我的问题是我已经下载了配置文件,但 xcode 运行的是不正确的配置文件。要解决此问题,请转到您的目标构建设置,向下滚动到代码签名,在配置文件部分下确保您使用的是与您生成的名称匹配的正确配置文件(如果您安装了不止一个)。
回答by CedricSoubrie
@madoa answer is absolutely correct. Just note that it is not working in the simulator.
@madoa 答案绝对正确。请注意,它在模拟器中不起作用。
In this case
在这种情况下
{
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
}
- (void)application:(UIApplication*)application didRegisterUserNotificationSettings:(nonnull UIUserNotificationSettings *)notificationSettings
{
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(nonnull NSError *)error
{
NSLog(@" Error while registering for remote notifications: %@", error);
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken
{
NSLog(@"Device Token is : %@", deviceToken);
}
is called with a error REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR
调用时出现错误 REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR
回答by YSR fan
Here is the solution.
这是解决方案。
in applicationDidFinishLaunchingWithOptions:
在 applicationDidFinishLaunchingWithOptions 中:
##代码##