Ios 如何使推送通知打开某个视图控制器?
我查看了,但在收到推送通知时,我找不到讨论的任何问题,然后如何打开特定的视图控制器。 例如,如果您正在创建一个类似WhatsApp的应用程序,并且收到来自两个不同用户的两个不同推送通知(即消息),您将如何从应用程序代理指向相应的viewController 据我在userinfo字典中所知,appDelegate为您提供了一个ID,您可以为特定的viewController提供ID,但我不知道如何向特定的view controller提供任何赞扬,以便您可以再次指向该viewController。 请在回答时附上代码片段Ios 如何使推送通知打开某个视图控制器?,ios,objective-c,swift,apple-push-notifications,ios-universal-links,Ios,Objective C,Swift,Apple Push Notifications,Ios Universal Links,我查看了,但在收到推送通知时,我找不到讨论的任何问题,然后如何打开特定的视图控制器。 例如,如果您正在创建一个类似WhatsApp的应用程序,并且收到来自两个不同用户的两个不同推送通知(即消息),您将如何从应用程序代理指向相应的viewController 据我在userinfo字典中所知,appDelegate为您提供了一个ID,您可以为特定的viewController提供ID,但我不知道如何向特定的view controller提供任何赞扬,以便您可以再次指向该viewController
****Swift或Objective-C答案都是可以接受的****您可以检测应用程序是否在应用程序代理中使用此代码从通知中打开。在应用程序变为活动状态之前,当应用程序状态为
UIApplicationStateInactive
时,您需要设置初始视图控制器。您可以在那里执行任何逻辑来决定应该打开哪个视图控制器以及应该在该视图控制器中显示哪些内容
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
if(application.applicationState == UIApplicationStateActive) {
//app is currently active, can update badges count here
} else if(application.applicationState == UIApplicationStateBackground){
//app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
} else if(application.applicationState == UIApplicationStateInactive){
//app is transitioning from background to foreground (user taps notification), do what you need when user taps here
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *viewController = // determine the initial view controller here and instantiate it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
}
}
-(void)application:(UIApplication*)application didReceiveMemoteNotification:(NSDictionary*)userInfo fetchCompletionHandler:(void(^)(UIBackgroundFetchResult))completionHandler{
if(application.applicationState==UIApplicationStateActive){
//应用程序当前处于活动状态,可以在此更新徽章计数
}else if(application.applicationState==UIApplicationStateBackground){
//应用程序在后台,若通知的内容可用键设置为1,则轮询到后端以检索数据并在此处更新界面
}else if(application.applicationState==UIApplicationStateInactive){
//应用程序正在从后台过渡到前台(用户点击通知),当用户点击此处时,执行您需要的操作
self.window=[[UIWindow alloc]initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard*情节提要=[UIStoryboard情节提要,名称:@“MainstryBoard”捆绑包:nil];
UIViewController*viewController=//在此处确定初始视图控制器,并使用[storyboard InstanceEviewController WithiIdentifier:]对其进行实例化;
self.window.rootViewController=viewController;
[self.window makeKeyAndVisible];
}
}
这是Swift 3版本,带有开关/外壳,而不是if/else
open func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
switch application.applicationState {
case .active:
print("do stuff in case App is active")
case .background:
print("do stuff in case App is in background")
case .inactive:
print("do stuff in case App is inactive")
}
}
当用户点击通知时调用此方法。在appdelegate中实现
var navigationC: UINavigationController?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if USERDEFAULT.value(forKey: "isLogin") != nil {
let tabbarvc = MainStoryboard.instantiateViewController(withIdentifier: "TabBarVC") as! TabBarVC
self.navigationC = UINavigationController(rootViewController: tabbarvc)
}else {
let loginvc = MainStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
self.navigationC = UINavigationController(rootViewController: loginvc)
}
self.navigationC?.setNavigationBarHidden(true, animated: false)
self.window?.clipsToBounds = true
self.window?.rootViewController = navigationC
self.window?.makeKeyAndVisible()
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
print("-------------\nUser info in notification -> \(userInfo)\n-------------")
let dict = userInfo["aps"] as? NSDictionary ?? [:]
if USERDEFAULT.value(forKey:"isLogin") != nil{
let type = dict["type"] as? Int ?? 0
switch type {
case 0:
break
case 1:
for vc in self.navigationC!.viewControllers {
if vc is TabBarVc {
let exam = dict["exam"] as? String ?? ""
if exam == ""{
let TestVC = MainStoryboard.instantiateViewController(withIdentifier: "TestVC") as! TestVC
TestVC.chapterId = dict["chapter_id"] as? String ?? ""
TestVC.strSubTitle = dict["chapter"] as? String ?? ""
self.navigationC?.isNavigationBarHidden = true
self.navigationC?.pushViewController(TestVC, animated: true)
}else if exam != ""{
let ExamTestVC = MainStoryboard.instantiateViewController(withIdentifier: "ExamTestVC") as! ExamTestVC
ExamTestVC.examId = dict["exam_id"] as? String ?? ""
ExamTestVC.strSubTitle = dict["exam"] as? String ?? ""
self.navigationC?.isNavigationBarHidden = true
self.navigationC?.pushViewController(ExamTestVC, animated: true)
}
return;
}
}
break
case 2:
for vc in self.navigationC!.viewControllers {
if vc is TabBarVc {
let VideoListVC = MainStoryboard.instantiateViewController(withIdentifier: "VideoListVC") as! VideoListVC
VideoListVC.chapterId = dict["chapter_id"] as? String ?? ""
VideoListVC.video_id = dict["video_id"] as? String ?? ""
VideoListVC.strSubTitle = dict["chapter"] as? String ?? ""
VideoListVC.questionsCount = dict["question_count"] as? Int ?? 0
VideoListVC.testCount = dict["test_count"] as? Int ?? 0
self.navigationC?.isNavigationBarHidden = true
self.navigationC?.pushViewController(VideoListVC, animated: true)
return;
}
}
break
case 3:
break
default: break
}
}else{
let loginVC = SignupiPadStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
SignupStoryboard = SignupiPadStoryboard
self.navigationC = UINavigationController(rootViewController: loginVC)
}
}
或者你可以直接打开视图控制器,比如whatsapp聊天等等
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
let userInfo = notification.request.content.userInfo
let dictAps = userInfo["aps"] as! NSDictionary
print(dictAps)
let notification_type = dictAps["notification_type"] as? Int ?? 0
if notification_type == 6{
if isChatActive == false{
completionHandler([.alert, .badge, .sound])
}else{
if USERDEFAULT.value(forKey:"isLogin") != nil{
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ReloadChatMessages"), object: nil, userInfo: (dictAps as! [AnyHashable : Any]))
}else{
completionHandler([.alert, .badge, .sound])
}
}
}else{
completionHandler([.alert, .badge, .sound])
}
}
非常感谢你。第三个id语句是实际从后台到前台的位置……前两个语句只更新模型,没有任何UI交互。正确的?。那么基本上你通过viewController的标识符进行了链接,对吗?对不起,我花了几天的时间来评论,这是正确的。重新分配你的
self.window.rootViewController
是个好主意吗?只需查看tabBar,然后指定正确的selectedIndex,不是更好吗?我的意思是,如果你有一个内存泄漏,然后重新分配你的选项卡栏,整个对象可能会留在内存中…@亲爱的,是的,你是对的,但我认为即使你确实有内存泄漏,并导航到正确的selectedIndex,你仍然需要在某个时候解决内存泄漏问题。p、 我喜欢两年后你的评论:)
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
let userInfo = notification.request.content.userInfo
let dictAps = userInfo["aps"] as! NSDictionary
print(dictAps)
let notification_type = dictAps["notification_type"] as? Int ?? 0
if notification_type == 6{
if isChatActive == false{
completionHandler([.alert, .badge, .sound])
}else{
if USERDEFAULT.value(forKey:"isLogin") != nil{
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ReloadChatMessages"), object: nil, userInfo: (dictAps as! [AnyHashable : Any]))
}else{
completionHandler([.alert, .badge, .sound])
}
}
}else{
completionHandler([.alert, .badge, .sound])
}
}