ios didReceiveRemoteNotification:fetchCompletionHandler:从图标打开 vs 推送通知
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22085234/
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
didReceiveRemoteNotification: fetchCompletionHandler: open from icon vs push notification
提问by Mike V
I'm trying to implement background push notification handling, but I'm having issues with determining whether the user opened the app from the push notification that was sent as opposed to opening it from the icon.
我正在尝试实现后台推送通知处理,但我在确定用户是否从发送的推送通知打开应用程序而不是从图标打开它时遇到问题。
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
//************************************************************
// I only want this called if the user opened from swiping the push notification.
// Otherwise I just want to update the local model
//************************************************************
if(applicationState != UIApplicationStateActive) {
MPOOpenViewController *openVc = [[MPOOpenViewController alloc] init];
[self.navigationController pushViewController:openVc animated:NO];
} else {
///Update local model
}
completionHandler(UIBackgroundFetchResultNewData);
}
With this code, the app is opening to the MPOOpenViewController regardless of how the user opens the app. How can I make it so that the view controller is only pushed if they open the app from swiping the notification?
使用此代码,无论用户如何打开应用程序,应用程序都会打开 MPOOpenViewController。我怎样才能做到只有在他们通过滑动通知打开应用程序时才会推送视图控制器?
With the same code, this worked on iOS 6, but with the new iOS 7 method, it doesn't behave how I want it to.
使用相同的代码,这适用于 iOS 6,但使用新的 iOS 7 方法,它的行为不像我想要的那样。
Edit:I'm trying to run the app on iOS 7 now, and we are not supporting any version prior to iOS 7. I used this same exact code in the iOS 6 version of the method (without the completion handler) and it behaved the way I'd expect it to. You'd swipe the notification and this would get called. If you opened from the icon, the method would never be called.
编辑:我现在正在尝试在 iOS 7 上运行该应用程序,我们不支持 iOS 7 之前的任何版本。我在该方法的 iOS 6 版本(没有完成处理程序)中使用了完全相同的代码,并且它的行为我期望的方式。你会滑动通知,这会被调用。如果您从图标打开,则永远不会调用该方法。
回答by Mike V
Ok I figured it out. The method is actually called twice (once when it receives the push, and once when the user interacts with the icon or the notification).
好吧,我想通了。该方法实际上被调用了两次(一次是在接收推送时,一次是在用户与图标或通知交互时)。
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
if(application.applicationState == UIApplicationStateInactive) {
NSLog(@"Inactive");
//Show the view with the content of the push
completionHandler(UIBackgroundFetchResultNewData);
} else if (application.applicationState == UIApplicationStateBackground) {
NSLog(@"Background");
//Refresh the local model
completionHandler(UIBackgroundFetchResultNewData);
} else {
NSLog(@"Active");
//Show an in-app banner
completionHandler(UIBackgroundFetchResultNewData);
}
}
Thanks Tim Castelijns for the following addition:
感谢 Tim Castelijns 添加以下内容:
Note: the reason it's called twice is due to the Payload having
content_available : 1
. If you removethe key and its value, then it will only run upon tapping. This will not solve everyone's problem since some people need that key to be true
注意:它被调用两次的原因是由于 Payload 有
content_available : 1
. 如果您删除键及其值,则它只会在点击时运行。这不会解决每个人的问题,因为有些人需要那个关键是真的
回答by SuperGlenn
@MikeV's solution in Swift 3 (but with switch statement):
@MikeV 在 Swift 3 中的解决方案(但带有 switch 语句):
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
switch application.applicationState {
case .inactive:
print("Inactive")
//Show the view with the content of the push
completionHandler(.newData)
case .background:
print("Background")
//Refresh the local model
completionHandler(.newData)
case .active:
print("Active")
//Show an in-app banner
completionHandler(.newData)
}
}
回答by Marie Amida
@MikeV's solution in Swift 2:
@MikeV 在 Swift 2 中的解决方案:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
if(application.applicationState == UIApplicationState.Inactive)
{
print("Inactive")
//Show the view with the content of the push
completionHandler(.NewData)
}else if (application.applicationState == UIApplicationState.Background){
print("Background")
//Refresh the local model
completionHandler(.NewData)
}else{
print("Active")
//Show an in-app banner
completionHandler(.NewData)
}
}