在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:06:33  来源:igfitidea点击:

Get Device Token in iOS 8

iosios8

提问by Pankaj

I need device token to implement push notification in my app.
How can I get device token since didRegisterForRemoteNotificationsWithDeviceTokenmethod 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_0macro 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. 图书馆

enter image description here

在此处输入图片说明

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

enter image description here

在此处输入图片说明

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

它会不会在模拟器工作。必须是电话

enter image description here

在此处输入图片说明

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 年,您必须执行以下操作:

  1. completely eraseapp from tethered phone
  2. buildto the phone and run from Xcode (it definitelywon't work)
  3. force quit the app
  4. completely eraseapp from tethered phone
  5. turn off both wifi/cell
  6. buildto the phone and run from Xcode (obviously it won't work)
  7. force quit the app
  1. 从系留手机中完全擦除应用程序
  2. 构建到手机并从 Xcode 运行(它绝对行不通)
  3. 强制退出应用
  4. 从系留手机中完全擦除应用程序
  5. 关闭两个wifi/手机
  6. 构建到手机并从 Xcode 运行(显然它不起作用)
  7. 强制退出应用

then in exactly this order:

然后完全按照这个顺序:

  1. completely eraseapp from tethered phone
  2. turn on connectivity (either wifi or cell is fine - no problem)
  3. build to the phone and run from Xcode
  1. 从系留手机中完全擦除应用程序
  2. 打开连接(wifi 或手机都可以 - 没问题)
  3. 构建到手机并从 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,并在启用推送通知的情况下设置特定于应用程序的配置文件。

  1. Create an App ID corresponding to your app's bundle identifier. Be sure to check off "push notifications" (currently 2nd option from the bottom).
  2. Create a provisioning profile for that App ID.
  3. Go through the rest of the horrible provisioning steps we'd all love to forget.
  4. ?
  5. Profit!
  1. 创建与您的应用程序包标识符对应的应用程序 ID。请务必勾选“推送通知”(目前是底部的第二个选项)。
  2. 为该 App ID 创建一个配置文件。
  3. 完成我们都想忘记的其余可怕的配置步骤。
  4. ?
  5. 利润!

回答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 中:

##代码##