在App未运行时处理推送通知

sir*_*333 43 iphone push-notification apple-push-notifications

当我的应用程序没有运行并收到推送通知时,如果我点击该通知,则启动应用程序 - 但是它不会提示用户设置的警报视图,询问他们是否要查看通知的内容与否.它只是发射,并坐在那里.

该推送通知做的工作完美的应用程序时运行-无论是作为活跃APP或者在后台-但没有正常工作时,该应用程序是不能运行的.

我尝试注销launchOptionsNSDictionary,application: didFinishLaunchingWithOptions:看看它带来了什么负载 - 但它出现了"(null)".所以它基本上什么都没有 - 这是没有意义的,因为它不应该包含Notification的负载?

任何人都有任何想法如何在应用程序未运行时如何使Push Notifications工作?

编辑:这是我正在使用的代码,application: didReceiveRemoteNotification只是为了看看是什么:

if (UIApplicationStateBackground) {

    NSLog(@"===========================");
    NSLog(@"App was in BACKGROUND...");
}
else if (UIApplicationStateActive == TRUE) {
    NSLog(@"===========================");
    NSLog(@"App was ACTIVE");
}
else {
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 99]; 
    UIAlertView *BOOM = [[UIAlertView alloc] initWithTitle:@"BOOM"
                                                   message:@"app was INACTIVE"
                                                  delegate:self
                                         cancelButtonTitle:@"a-ha!"
                                         otherButtonTitles:nil];
    [BOOM show];
    NSLog(@"App was NOT ACTIVE");
}
Run Code Online (Sandbox Code Playgroud)

所以这应该照顾所有应用程序的状态 - 但事实并非如此.推送通知仅在应用程序运行时有效 - 无论是在后台还是在前台......

================================================

更新/编辑#2:根据"@dianz"建议(下面),我修改了我的代码application: didFinishLaunchingWithOptions以包含以下内容:

UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (localNotif) {
    NSString *json = [localNotif valueForKey:@"data"]; 

    UIAlertView *bam = [[UIAlertView alloc] initWithTitle:@"appDidFinishWithOptions"
                                                  message:json   
                                                 delegate:self
                                        cancelButtonTitle:@"cool"
                                        otherButtonTitles:nil];
    [bam show];

}
Run Code Online (Sandbox Code Playgroud)

这确实使AlertView框出现,但似乎没有有效负载:AlertView的标题显示("appDidFinishWithOptions"),但json NSString出现EMPTY ...将继续调整...

======================

编辑#3 - 它现在几乎 100%工作
所以,在didFinishLaunchingWithOptions:

UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
    if (localNotif) {
        // Grab the pushKey:
        pushKey = [localNotif valueForKey:@"pushKey"];
        // "pushKey" is an NSString declared globally
        // The "pushKey" in the "valueForKey" statement is part of my custom JSON Push Notification pay-load.
        // The value of pushKey will always be a String, which will be the name of the 
        // screen I want the App to navigate to. So when a Notification arrives, I go
        // through an IF statement and say "if pushKey='specials' then push the                                      
        // specialsViewController on, etc.

        // Here, I parse the "alert" portion of my JSON Push-Notification:
        NSDictionary *tempDict = [localNotif valueForKey:@"aps"];
        NSString *pushMessage = [tempDict valueForKey:@"alert"];


        // Finally, ask user if they wanna see the Push Notification or Cancel it:
        UIAlertView *bam = [[UIAlertView alloc] initWithTitle:@"(from appDidFinishWithOptions)"
                                                      message:pushMessage  
                                                     delegate:self
                                            cancelButtonTitle:@"Cancel"
                                            otherButtonTitles:@"View Info", nil];
        [bam show];

    }
Run Code Online (Sandbox Code Playgroud)

我接下来实现该alertView: clickedButtonAtIndex方法以查看用户在AlertView上选择的内容并相应地继续.

这与didReceiveRemoteNotification逻辑完美结合.

但是......当应用程序没有运行时,我发送推送通知,如果我没有在它到达时立即点击推送通知警报而是等待它淡出(这发生在像3-之后4秒),然后我点击应用程序的图标 - 它现在有一个BADGE为1 - 应用程序启动,但是当它启动时我根本没有得到推送通知警报.它只是坐在那里.

我想我需要弄清楚的是下一个排列...

DLe*_*nde 36

当您的应用未运行或被杀时,您点击推送通知此功能将触发;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Run Code Online (Sandbox Code Playgroud)

所以你应该像这样处理它,

UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (localNotif) {
    NSString *json = [localNotif valueForKey:@"data"];
    // Parse your string to dictionary
}
Run Code Online (Sandbox Code Playgroud)


Vai*_*ran 11

最好是如果你覆盖didReceiveRemoteNotification 在这里你去

NSDictionary * pushNotificationPayload = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(pushNotificationPayload) {
    [self application:application didReceiveRemoteNotification:pushNotificationPayload];
}
Run Code Online (Sandbox Code Playgroud)

这将再次触发该didReceiveRemoteNotification方法,您的push notification代码将在应用程序运行时运行时执行.

  • 你有这个工作吗??我的意思是当应用程序处于未运行状态时如何处理推送通知?如果您收到许多通知并且未打开应用程序,那么您也没有点击系统的通知面板.你是如何保留这些推动以便以后检索的. (2认同)

小智 7

我试过@dianz的答案,这对我没有用,但我从答案中得到了帮助.

就我而言;

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

NSDictionary *apnsBody = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (apnsBody) {
    // Do your code with apnsBody
}
Run Code Online (Sandbox Code Playgroud)


Kyl*_*man 5

尽管已经回答了这个问题,但所提供的答案实际上没有一个可以正常工作。这是我能够开始工作的实现。

这段代码进去 application:didFinishLaunchingWithOptions:

迅速:

if let options = launchOptions, notification = options[UIApplicationLaunchOptionsRemoteNotificationKey] as? [NSObject : AnyObject] {
    // NOTE: (Kyle Begeman) May 19, 2016 - There is an issue with iOS instantiating the UIWindow object. Making this call without
    // a delay will cause window to be nil, thus preventing us from constructing the application and assigning it to the window.
    Quark.runAfterDelay(seconds: 0.001, after: {
        self.application(application, didReceiveRemoteNotification: notification)
    })
}
Run Code Online (Sandbox Code Playgroud)

目标-C:

if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
    [self application:application didReceiveRemoteNotification:launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]];
}
Run Code Online (Sandbox Code Playgroud)

一些注意事项:

  • 可能是由于 iOS 排队分配的方式,根UIApplication.sharedApplication().window对象在被杀死后启动应用程序时为 nil。添加 1 毫秒延迟修复了此问题。没有在 Objective-C 中测试这个

  • 强制转换为 [NSObject: AnyObject] 是为了避免类型冲突,但我没有进行太多实验;在您自己的项目中实施时,请牢记这一点。Objective-C 不需要这个。

  • Quark 只是我在所有项目中使用的一个有趣的小库,其中包含有用且常用的扩展和方法。只需使用适合您的应用程序需求的任何形式的延迟。