繁体   English   中英

在 iOS 8 中获取设备令牌

[英]Get Device Token in iOS 8

我需要设备令牌来在我的应用程序中实现推送通知。
由于didRegisterForRemoteNotificationsWithDeviceToken方法在 iOS 8 上didRegisterForRemoteNotificationsWithDeviceToken我如何获取设备令牌。我在应用程序委托中尝试了此代码,但它没有给我设备令牌。

    [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
    [[UIApplication sharedApplication] registerForRemoteNotifications];

阅读 UIApplication.h 中的代码。

你会知道如何做到这一点。

第一的:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

添加这样的代码

#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

如果您没有同时使用 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];
}

(感谢@zeiteisen @dmur 的提醒)


第二:

添加此功能

#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

你可以得到 deviceToken

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

如果它仍然不起作用,请使用此功能并 NSLog错误

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error

为@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];

__IPHONE_8_0宏的作用只是允许您在旧版本的 xCode/iOS 中进行编译,您不会收到编译错误或警告,但在 iOS 7 或更低版本的设备上运行代码会导致崩溃。

在 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);
}

2020解决方案

六个步骤,

1. 图书馆

在此处输入图片说明

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", $0) }.joined()
}

func application(_ application: UIApplication,
      didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print(">> error getting APNs token  >>\(error)<<")
}

3. 在你的应用中

例如,用户登录后

import UserNotifications

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()
        }
    }
}

4. 能力选项卡

件事

在此处输入图片说明

当心旧文章:那里不再有“开关”。

5. 绑定手机,没有模拟器

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

在此处输入图片说明

系留电话很好,控制台可以正常工作

6.最后...... WIFI DANCE

凭借 100% 的可重复性,截至 2020 年,您必须执行以下操作:

  1. 从系留手机中完全擦除应用程序
  2. 构建到手机并从 Xcode 运行(它绝对行不通)
  3. 强制退出应用
  4. 从系留手机中完全擦除应用程序
  5. 关闭两个wifi/手机
  6. 构建到手机并从 Xcode 运行(显然它不起作用)
  7. 强制退出应用

然后完全按照这个顺序:

  1. 从系留手机中完全擦除应用程序
  2. 打开连接(wifi 或手机都可以 - 没问题)
  3. 构建到手机并从 Xcode 运行

它现在可以工作了。 (并且将从这里开始工作。)

WIFI DANCE 只是 Apple 那些奇怪的东西之一。 他们还没有修复它(Xcode 11.3)。 事实上,它已经变得“100% 可重复”:你必须做 WIFI DANCE。

除了对这个问题的其他居高临下的回答之外,对于已经实现了所有必需委托方法的知情开发人员来说,发生此问题的最可能原因是他们使用了通配符配置文件(为什么不呢?它使创建和测试开发应用程序变得如此容易!)

在这种情况下,您可能会看到错误Error Domain=NSCocoaErrorDomain Code=3000 "no valid 'aps-environment' entitlement string found for application"

为了测试通知,您实际上必须回到 2000 年或更晚,登录 developer.apple.com,并在启用推送通知的情况下设置特定于应用程序的配置文件。

  1. 创建与您的应用程序包标识符对应的应用程序 ID。 请务必勾选“推送通知”(目前是底部的第二个选项)。
  2. 为该 App ID 创建配置文件。
  3. 完成我们都想忘记的其余可怕的配置步骤。
  4. ?
  5. 利润!

在您的开发者帐户中,确保您在应用 ID 中正确设置了推送通知,然后您需要重新生成并下载您的配置文件。 我的问题是我已经下载了配置文件,但 xcode 运行的是不正确的配置文件。 要解决此问题,请转到您的目标构建设置,向下滚动到代码签名,在配置文件部分下确保您使用的是与您生成的名称匹配的正确配置文件(如果您安装了不止一个)。

@madoa 答案绝对正确。 请注意,它在模拟器中不起作用

在这种情况下

-(void)application:(UIApplication *)application
     didFailToRegisterForRemoteNotificationsWithError:(NSError *)error

调用时出现错误 REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR

这是解决方案。

在 applicationDidFinishLaunchingWithOptions 中:

{

 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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM