美文网首页ios 知识点恩美第二个APP项目iOS学习
ios 收到远程通知,点击跳转到对应的消息界面

ios 收到远程通知,点击跳转到对应的消息界面

作者: fulen | 来源:发表于2016-11-07 16:59 被阅读3524次
    立冬

    现在有一个需求,有通知过来,app处于前台时,弹出一个alert,点击确定跳转到对应的界面,在这里我设了一个定时器,模拟接收到通知弹出alert,通知的集成代码这边就不多做介绍了,想了解集成我的上篇文章中有简单的介绍,下面开始分两种情况

    1. self.window.rootViewController是导航控制器

    appdelegate.m

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // MainTabbarVC为tabbarController
        MainTabbarVC *main = [[MainTabbarVC alloc] init];
        UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:main];
        self.window.rootViewController = nvc;
        [self.window makeKeyAndVisible];
    // 设定一个弹出alert的定时器
        time = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(showAlert) userInfo:nil repeats:NO];
        return YES;
    }
    
    - (void)showAlert
    {
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"是否去消息界面" message:@"请选择" preferredStyle:UIAlertControllerStyleAlert];    
        UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"跳转" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            //  点击确定,处理页面跳转
            ViewController *viewC = [[ViewController alloc] init];
            NSLog(@"点击了确定,push");
        }];
        
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];  
        [alertController addAction:alertAction];
        [alertController addAction:cancelAction];    
    //    MainTabbarVC *main = [[MainTabbarVC alloc] init];
    //    [main presentViewController:alertController animated:YES completion:nil];
    //    HomeViewController *home = [[HomeViewController alloc] init];
    //    [home presentViewController:alertController animated:YES completion:nil];  // 主页
    // 以上两种方法无法弹出alert
    
    // 用rootViewController弹出laert
    [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
    
        [time invalidate]; // 取消定时器
    }
    
    弹出alert

    接下来着重说一下跳转的方法

    1.用self.window.rootViewController去push

    ViewController *viewC = [[ViewController alloc] init];
    [(UINavigationController *)self.window.rootViewController pushViewController:viewC animated:YES]; // 这里需要强制转化一下,这个方法不推荐,当项目中业务逻辑比较复杂的时候,此方法可能会导致很多bug,待会会介绍另外一种写法
    
    

    self.window.rootViewController实际上是MainTabbarVC

    打断点,用po命令查看

    下面看一下MainTabbarVC里面的代码

    #import "MainTabbarVC.h"
    #import "HomeViewController.h"
    #import "SettingViewController.h"
    
    @interface MainTabbarVC ()
    
    @end
    
    @implementation MainTabbarVC
    
    // 程序进入隐藏appdelegate里面创建的navigation ,这一步很关键,不然进入主页面,看到的navigation将是在appdelegate里面创建的,不利于管理
    - (void)viewWillAppear:(BOOL)animated{    
        [super viewWillAppear:animated];
        self.navigationController.navigationBarHidden = YES;
    }
    - (void)viewDidLoad {
        [super viewDidLoad];    
        [self creatControllers];
    }
    
    - (void)creatControllers
    {
        HomeViewController *home = [[HomeViewController alloc] init];
        UINavigationController *homeNAV = [[UINavigationController alloc] initWithRootViewController:home];
        home.title = @"主页";
        
        SettingViewController *setting = [[SettingViewController alloc] init];
        UINavigationController *settingNAV = [[UINavigationController alloc] initWithRootViewController:setting];
        setting.title = @"设置";
        
        self.viewControllers = @[homeNAV,settingNAV];
        
    }
    

    跳转后的页面效果


    跳转后的viewController

    1.2 刚才说了上面的push方法不推荐,下面推荐一个比较合理的方法在Appdelegate.m中

    #import "AppDelegate.h"
    #import "MainTabbarVC.h"
    #import "ViewController.h"
    @interface AppDelegate ()
    {
         NSTimer *time;
    }
    @end
    static AppDelegate *__delegate = nil;
    @implementation AppDelegate
    AppDelegate *myDelegate(void){
        return __delegate;
    }
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
        MainTabbarVC *main = [[MainTabbarVC alloc] init];
        self.window.rootViewController = main;
        __delegate = self;
        _masterTabbarController = main;    
        [self.window makeKeyAndVisible];  
        time = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(showAlert) userInfo:nil repeats:NO];
        return YES;
    }
    
    // alert中push
     UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"跳转" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            // 跳转页面 跳转到消息列表页面
            ViewController *viewC = [[ViewController alloc] init];
            [AppDelegate mastePushViewController:viewC];
        }];
    
    
    // push方法
    + (void)mastePushViewController:(UIViewController *)controller
    {
        UINavigationController *nvc = myDelegate().masterTabbarController.selectedViewController;
        [nvc pushViewController:controller animated:YES];
    }
    

    push之后的效果如下


    直接拿到tabbarController的navigation

    viewController.m

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    // 显示隐藏的导航栏
    - (void)viewWillAppear:(BOOL)animated{
        [super viewWillAppear:animated];
        self.navigationController.navigationBarHidden = NO;   
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor cyanColor];
        self.title = @"viewController";
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    @end
    

    2. self.window.rootViewController不是导航控制器

    appdelegate.m

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   
        MainTabbarVC *main = [[MainTabbarVC alloc] init];
        self.window.rootViewController = main;
        [self.window makeKeyAndVisible];
        time = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(showAlert) userInfo:nil repeats:NO];
        return YES;
    }
    

    这种情况下,利用以上跳转方法,程序会crash,下面是奔溃信息


    奔溃信息

    主要是说MainTabbarVC没有push方法,我们知道没有导航控制器是不可能用push,所以这里我们建一个navigationController,然后在跳转的时候隐藏创建的这个

    AppDelegate.h

    AppDelegate.h加一个navigation

    AppDelegate.m

    
    #import "AppDelegate.h"
    #import "MainTabbarVC.h"
    #import "ViewController.h"
    
    @interface AppDelegate ()
    {
        NSTimer *time;
    }
    
    @end
    
    static AppDelegate *__delegate = nil;
    
    @implementation AppDelegate
    
    AppDelegate *myDelegate(void){
        return __delegate;
    }
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
        MainTabbarVC *main = [[MainTabbarVC alloc] init];
        self.myNavigationController = [[UINavigationController alloc] initWithRootViewController:main];
        __delegate = self;
    // push的时候隐藏navigationBarHidden
        self.myNavigationController.navigationBarHidden = YES;
        self.window.rootViewController = main;
        
        [self.window makeKeyAndVisible];
        
        time = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(showAlert) userInfo:nil repeats:NO];
        return YES;
    }
    
    + (void)myPushViewController:(UIViewController *)controller
    {
        UINavigationController *nvc = myDelegate().myNavigationController;
        [nvc pushViewController:controller animated:YES];
    }
    

    弹出的alert

    - (void)showAlert
    {
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"是否去消息界面" message:@"请选择" preferredStyle:UIAlertControllerStyleAlert];    
        UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"跳转" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            // 跳转页面 跳转到消息列表页面
            ViewController *viewC = [[ViewController alloc] init];
           [AppDelegate myPushViewController:viewC];
            NSLog(@"点击了确定,准备push");
        }];    
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];    
        [alertController addAction:alertAction];
        [alertController addAction:cancelAction];    
        [self.myNavigationController presentViewController:alertAction animated:YES completion:nil];
    //    [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];  // 因为self.window.rootViewController = self.myNavigationController,所以这两个方法是一样的    
        [time invalidate];
    }
    

    核心代码:


    创建navigation

    弹框的代码

    弹出alert

    这里遇到接收推送后跳转消息界面,可以重新封装一个类,将下面这个方法放到封装的类中,可以全局调用此方法处理消息跳转

    + (void)myPushViewController:(UIViewController *)controller
    {
        UINavigationController *nvc = myDelegate().myNavigationController;
        [nvc pushViewController:controller animated:YES];
    }
    // 当然,你也可以不用那么繁琐,直接用[self .myNavigationController pushViewController:controller animated:YES];  // push到想要跳转的控制器即可
    

    3、不管是不是导航控制器,我么都可以使用通知,然后通知首页进行跳转,在appdelegate里面,发送通知,代码如下

    // 这里是接收到远程推送,点击通知之后,在需要做特定跳转的方法里面的
    HomeTBVC *home = [[HomeTBVC alloc] init];  // 初始化一下首页试图控制器
                //是推送打开
                NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
                [center postNotificationName:@"appdelegatePushMessage" object:nil userInfo:userInfo];  // userInfo为通知内容
    

    4、在首页试图控制器下添加代码

    // 添加监听
    [center addObserver:self selector:@selector(pushToWebView:) name:@"appdelegatePushMessage" object:nil];
    
    // 跳转到相应的页面,这里的notificaiton.userInfo为远程通知内容
    - (void)pushToWebView:(NSNotification *)notification{
        WebViewVC *webVC = [WebViewVC new];
        webVC.messageDic = notification.userInfo;
        webVC.strUrl = notification.userInfo[@"webUrl"];
        [self.navigationController pushViewController:webVC animated:YES];
    }
    

    至此:

    可以看出appdelegate里面没有导航控制器(navigation)的时候,可以选择创建一个临时的navigation,在进入tabbarController的时候隐藏;或者直接拿到tabbarcontroller里面创建的navigation,这种方法在跳转之后底部tabbar不会消失,如果不想要tabbar,可以再push的页面中隐藏tabbar

    现实有很多拘束,但是代码的世界里,你可以尽情遨游,加油everyone

    相关文章

      网友评论

      • 微小的沙土:不推荐的原因是什么,为什么那种方式比较合理?求解释
        微小的沙土:@fulen 噢
        fulen:牵涉到强制类型转换,不是很安全
      • b0fa7bbe2894:服务器推送的消息 收不到是什么原因。。极光后台推送都可以收到
        fulen:@叁壹捌_384e 应该是服务器没有配置好,你和后台的人在联调一下
      • 独爱ii:我的根视图rootView是UITabBarController,我们的需求是点击推送,跳转一个单独页面,再点击此页面的确定按钮才跳转对应的界面。有个问题问问你,你QQ多少
        fulen:@独爱ii 刚看到1162719523
      • lovelychick:关注走一走,活到99,Mark。
      • Dely:加油学习
        fulen:@Dely 必须

      本文标题:ios 收到远程通知,点击跳转到对应的消息界面

      本文链接:https://www.haomeiwen.com/subject/itdouttx.html