开发者社区 问答 正文

如何在App不运行(即完全被杀死)的情况下,当用户点击推送通知时打开特定的控制器目标C

我可以发送推送通知到我的iOS设备。但当我点击那个通知时,它只会打开应用程序。当我的应用程序处于后台或前台时,它工作得非常完美,我希望应用程序打开并导航到特定的视图控制器,具体取决于所收到的推送通知。

(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    // Print message ID.
    NSLog(@"Message ID: %@", userInfo[@"gcm.message_id"]);
    [[FIRMessaging messaging] appDidReceiveMessage:userInfo];
    NSDictionary *apsDict = [userInfo objectForKey:@"aps"];
    NSString *alertForegroundMessage = [NSString stringWithFormat:@"%@", [apsDict objectForKey:@"alert"]];

    // Pring full message.
    NSLog(@"%@", userInfo);

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC),
                   dispatch_get_main_queue(), ^{
                       // Check result of your operation and call completion block with the result
                       completionHandler(UIBackgroundFetchResultNewData);

                       NSMutableArray *arrnotification;

                       arrnotification = [userInfo valueForKey:@"aps"];

                   });

    if (application.applicationState == UIApplicationStateActive)
    {

        NSDictionary *userInfo = [[NSDictionary alloc] init];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"downloadDataFromServer" object:self userInfo:userInfo];
          NSLog(@"User Info : %@",userInfo);
         completionHandler(UIBackgroundFetchResultNewData);
    }

    else
    {
        NSLog(@"userInfo->%@", [userInfo objectForKey:@"aps"]);
        NSDictionary *sentObject = [NSDictionary dictionaryWithObjectsAndKeys:noteDict,@"data", nil];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"downloadDataFromServer" object:sentObject];
        completionHandler(UIBackgroundFetchResultNewData);
    }
    completionHandler(UIBackgroundFetchResultNewData);
}

展开
收起
游客5akardh5cojhg 2019-12-11 22:07:19 454 分享
分享
版权
举报
阿里云 AI 助理回答

在您的代码中,您已经正确地处理了接收到远程推送通知的情况,并且根据应用的状态(前台、后台)执行不同的逻辑。为了在点击通知后导航到特定的视图控制器,您需要在AppDelegate中实现另一个方法来处理用户从通知直接进入应用时的情景。这个方法是application:openURL:options:或在iOS 13及以后版本中的scene(_:openURLContexts:)

首先,确保您的推送通知中包含了决定视图控制器导航的信息,比如一个标识符。然后,在以下示例中,我将展示如何基于这些信息进行导航:

如果您的项目使用 SceneDelegate (iOS 13+):

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    if let url = URLContexts.first?.url {
        handleNotificationUrl(url)
    }
}

对于没有 SceneDelegate 的老版本 iOS:

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    handleNotificationUrl(url)
    return true
}

接下来,定义 handleNotificationUrl(_ url: URL) 方法来解析URL并导航到相应的视图控制器:

func handleNotificationUrl(_ url: URL) {
    // 解析URL以获取所需的信息,例如导航目标的标识符
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
          let identifier = components.queryItems?.first(where: { $0.name == "viewIdentifier" })?.value else {
        // 处理无法解析URL或找不到标识符的情况
        print("Invalid notification URL or missing view identifier.")
        return
    }

    // 根据identifier导航到相应的视图控制器
    // 假设您有一个navigationController作为根视图控制器
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    guard let viewController = storyboard.instantiateViewController(withIdentifier: identifier) as? YourViewControllerClass else {
        print("Unable to instantiate view controller with identifier: \(identifier)")
        return
    }
    
    // 确保应用已启动时导航到指定的视图控制器
    if let window = UIApplication.shared.windows.first,
       let rootViewController = window.rootViewController as? UINavigationController {
        rootViewController.pushViewController(viewController, animated: true)
    }
}

请替换 "YourViewControllerClass" 为您的实际视图控制器类名,并确保在Storyboard中设置了正确的Storyboard ID(即上述代码中的 identifier)。

这样,当用户点击通知时,应用会打开并自动导航到与推送通知中指定的视图控制器相对应的页面。记得在发送推送通知时包含必要的信息(如viewIdentifier),以便在客户端正确解析和处理。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答