iOS:如何在 AppDelegate 之外调用“应用程序 didRegisterForRemoteNotificationsWithDeviceToken”?
Posted
技术标签:
【中文标题】iOS:如何在 AppDelegate 之外调用“应用程序 didRegisterForRemoteNotificationsWithDeviceToken”?【英文标题】:iOS: How do I call "application didRegisterForRemoteNotificationsWithDeviceToken" outside of AppDelegate? 【发布时间】:2014-07-23 05:51:11 【问题描述】:使用 解析
场景 = 我有一个发送消息的应用程序。当消息发送给用户时,它也会发送推送通知。
困难 = 应用启动时调用
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
if ([PFUser currentUser])
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation setObject:[PFUser currentUser][@"userID"] forKey:@"userID"];
[currentInstallation saveInBackground];
NSLog(@"INSTALLATION REGISTERED");
当用户第一次下载应用程序时,还没有创建 currentUser。因此,如果 currentUser 存在,应用程序会检查 didRegisterForRemoteNotificationsWithDeviceToken
方法内部。由于第一次启动应用程序时 currentUser 不存在(他们必须先创建一个帐户),我希望能够再次致电 didRegisterForRemoteNotificationsWithDeviceToken
在 currentUser 之后已创建。
问题 = 我如何在AppDelegate
类之外调用didRegisterForRemoteNotificationsWithDeviceToken
?
我的尝试 = 我注册用户时的代码
UIApplication *app = [[UIApplication alloc]init];
[app registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
这会引发错误
*** Assertion failure in -[UIApplication init]
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'There can only be one UIApplication instance.'
【问题讨论】:
【参考方案1】:使用这个
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|
UIRemoteNotificationTypeAlert|
UIRemoteNotificationTypeSound];
【讨论】:
【参考方案2】:您不应直接调用 didRegisterForRemoteNotificationsWithDeviceToken,因为它是委托协议的一部分。您应该保存您的 deviceToken 并稍后将其传递给 PFInstallation,例如:
AppDelegate.m
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
self.token = deviceToken;
[self saveInstallation];
-(void)saveInstallation
if ([PFUser currentUser])
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:self.token];
[currentInstallation setObject:[PFUser currentUser][@"userID"] forKey:@"userID"];
[currentInstallation saveInBackground];
NSLog(@"INSTALLATION REGISTERED");
AppDelegate.h
@property(strong) NSData* token;
-(void)saveInstallation;
RegistrationScreen.m
#import "AppDelegate.h"
-(void)yourSaveAction
// Call this after having a valid PFUser.
[(AppDelegate*)[[UIApplication sharedApplication] delegate] saveInstallation];
【讨论】:
嘿布鲁诺感谢您的回复。我喜欢这样做的方式。不过有几个问题。 1) 将设备令牌作为属性存储在 AppDelegate 上是否存在安全风险? 2) 在您的代码中,“(YourAppDelegate*)”为什么是“Your”?我不明白。在我用 Xcode 制作的每一个应用程序中,它总是被简单地称为“AppDelegate”。你把“你的”放在那里,就像我应该把我的应用程序的名称放在单词的“...AppDelegate”部分之前一样。这让我很困惑。 1) 我认为这不会带来安全风险,因为您会将其存储在 RAM 内存中。但是,如果您对此感到担心,可以在保存 PFInstallation 后执行self.token = nil;
。 2) 抱歉,我仍然习惯于调用应用代理的旧方式。在 Xcode 5 之前(如果我没记错的话),应用程序委托有另一个名称,例如“FacebookAppDelegate”。我正在编辑我的回复,以便更轻松地完成像您这样的新项目。【参考方案3】:
UIApplication 是一个单例,您应该使用sharedApplication
调用它。
UIApplication * app = [UIApplication sharedApplication];
[app registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
[编辑] 我弄错了 registerForRemote is an UIApplication 方法
【讨论】:
嗨,安德里亚,谢谢您的回复。澄清一下,我可能在我的代码中也写错了——但是“registerForRemoteNotificationTypes”与“didRegisterForRemoteNotificationsWithDeviceToken”一样吗? 你不应该自己调用didRegister..这是你成功注册推送通知时系统调用的。该过程是您在需要的地方调用 registerForRemoteNotification,应用程序向苹果服务器请求其推送令牌,一旦它成功接收到它调用 didRegisterForRemoteNotification。要获得有效的令牌,您必须要求它。【参考方案4】:你为什么这样做
UIApplication *app = [[UIApplication alloc]init];
[app registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
相反,您应该知道 UIApplication 是一个单例类,因此您可以这样做
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
在你想要的地方使用上面的代码
希望这会对您有所帮助。快乐编码:)
【讨论】:
以上是关于iOS:如何在 AppDelegate 之外调用“应用程序 didRegisterForRemoteNotificationsWithDeviceToken”?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 中从 AppDelegate 调用视图控制器
来自 appDelegate 的 javascript 调用:phonegap iOS
在 AppDelegate 之外,我如何在 UINavigationController 中包含一个 UIViewController,然后再对它执行基本的 `performSegueWIthIden