应用未运行时如何处理远程通知

Posted

技术标签:

【中文标题】应用未运行时如何处理远程通知【英文标题】:How to handle remote notifications when the app is not running 【发布时间】:2015-09-03 13:46:24 【问题描述】:

如果我的应用程序在前台或后台运行,这工作正常。我正在接收通知并将其保存在本地数据库中。但是,如果应用程序从后台终止,它会收到远程通知,但不会调用以下方法。问题是如果我点击任何一个通知,只有该通知会保存在本地数据库中。

- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler


    [PFPush handlePush:userInfo];
    NSLog(@"Received notification: %@", userInfo);
    NSString *alertString = [[userInfo objectForKey:@"aps"]valueForKey:@"alert"];


    NSLog(@"%@",alertString);
    NSString *msgType = [userInfo objectForKey:@"messageType"];
    NSString *senderId = [userInfo objectForKey:@"senderId"];
    NSString *receverId = [userInfo objectForKey:@"receverId"];
    NSString *msg = [userInfo objectForKey:@"message"];
    NSString *timeStr = [userInfo objectForKey:@"Time"];
    NSLog(@"msg type%@ senderId %@ receverId %@ message %@",msgType,senderId,receverId,msg);


    if ([AppDelegate isNetworkReachable])
        if ([msgType isEqualToString:@"CHAT"]) 
            Chatmessage *Cmsg=[[Chatmessage alloc]init];
            Cmsg.chat_date =timeStr;
            Cmsg.chat_image =@"";
            Cmsg.chat_message = msg;
            Cmsg.chat_Receiver_Id = receverId;
            Cmsg.chat_Sender_Id = senderId;
            NSLog(@"recid%@",Cmsg.chat_Receiver_Id);

            NSMutableArray *arryMsg = [[NSMutableArray alloc]init];
            arryMsg = [[DBModelNew database]getChatMessageBasedOnTime:receverId SenId:senderId time_stamp:timeStr message:msg];

            if (arryMsg.count == 0) 
                [[DBModelNew database]insertmsg:Cmsg];
            

            [[NSNotificationCenter defaultCenter]postNotificationName:@"receivedmessage" object:nil];

            chatHistory *chatObj = [[chatHistory alloc]init];
            chatObj.chat_meta_id = [NSString stringWithFormat:@"%@",senderId];
            chatObj.last_send_message = msg;
            NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
            dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
            NSString *str=[dateFormatter stringFromDate:[NSDate date]];
            chatObj.last_time_stamp = [self dateformat:str];
            PFQuery *query = [PFUser query];
            [query whereKey:@"objectId" equalTo:senderId];
            [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 
                if (!error) 
                    for (NSDictionary *dict in objects) 

                        [[dict objectForKey:@"ProfilePic"] getDataInBackgroundWithBlock:^(NSData *data, NSError *error) 

                            if (!error) 

                                if (data) 
                                    UIImage *image = [UIImage imageWithData:data];
                                    if (image) 
                                        chatObj.fndimage = image;
                                        chatObj.name = [dict objectForKey:@"name"];
                                        [[DBModelNew database]insertChat:chatObj];
                                        [[NSNotificationCenter defaultCenter]postNotificationName:@"receivedNewMessage" object:nil];                            
                                    
                                
                            

                        ];
                    
                
            ];

        
    

【问题讨论】:

首先,依赖于聊天应用程序的推送通知并不是一个好主意。用户可以从隐私设置中禁用推送通知,因此您的应用在这种情况下将毫无用处,并且您无法以编程方式对其进行处理。 第二件事,即使您的用户允许应用程序进行推送通知,您的推送通知也有一定的可能性会在发送过程中消失,并且永远不会发送到设备。我的意思是没有绝对保证推送通知会到达设备。 (虽然有效!)。 第三件事,如果您的应用程序被强制退出或在后台,并且收到 10 个通知,用户从 1 个通知启动应用程序,您无法从系统访问其余 9 个通知。你至少需要有一个更好的选择,比如 xmpp、sip 或 http。 @AdilSoomro 感谢您的回答。我需要回答第三种情况。如果您的应用程序被强制退出或在后台,并且收到 10 个通知,用户从 1 个通知启动应用程序,则您无法从系统访问其余 9 个通知。在这种情况下,我不知道该怎么办...如果您有想法请帮助我 我所有的 3 三个 cmets 都在建议您不要使用推送通知进行聊天。 【参考方案1】:

根据 Apple 文档,如果用户硬关闭应用程序,它不会调用该方法。

此外,如果您启用了远程通知后台模式, 系统启动您的应用程序(或将其从挂起状态唤醒) 并在收到远程通知时将其置于后台状态 到达。 但是,如果出现以下情况,系统不会自动启动您的应用 用户已强制退出。 在这种情况下,用户必须重新启动 您的应用程序或在系统尝试启动之前重新启动设备 您的应用会再次自动自动运行。

【讨论】:

【参考方案2】:

如果您想从viewDidLoad 启动特定的有效负载字典,那么您只需调用以下命令:

UILocalNotification *localNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];

这样你就可以得到userInfo

NSString *msgType = [localNotif objectForKey:@"messageType"];

现在你可以采取相应的行动了。这仅适用于您在标题中所述的情况。当应用程序未“运行”(终止)时

【讨论】:

如果我的应用程序被强制退出或在后台,并且收到 10 个通知,用户从 1 个通知启动应用程序,您无法从系统访问其余 9 个通知。我需要处理剩余的9个通知。他们有什么可能的方式来做到这一点.. @raminenisatish 这似乎是一个不同的问题。每个问题只问一个问题是很礼貌的。我建议发布有关该问题的另一个问题。我在回答标题和正文的问题

以上是关于应用未运行时如何处理远程通知的主要内容,如果未能解决你的问题,请参考以下文章

IOS,应用启动时如何处理多个本地通知?

如何处理不同语言的 iOS 推送通知

当 iOS 应用程序被暂停/杀死并且用户点击通知时如何处理 Firebase 推送通知?

当我的应用程序激活时如何处理推送通知?

用户关闭应用程序时如何处理用户在 Xamarin iOS 上单击本地通知?

如何处理视图控制器上的远程通知(而不是 AppDelegate)[关闭]