[SWIFT 3] Comment connaitre la vue courante dans AppDelegate ?

InsouInsou Membre
mai 2017 modifié dans API UIKit #1

Bonjour,


 


J'ai un petit soucis sur comment savoir sur quelle vue je me trouve dans AppDelegate..


 


En gros, je reçois des notifications push silencieuse, si je suis sur tel ou tel interface, mon action est différente..


 


Par contre, je n'arrive pas à  savoir sur quelle vue je suis quand je reçois la notification..


 


Comment-vous vous y prenez pour savoir sur quelle view l'utilisateur est (dans AppDelegate) ?


Mots clés:

Réponses

  • DrakenDraken Membre

    Là  comme ça, sans réfléchir, j'utiliserais le tag de chaque vue pour l'identifier.

  • InsouInsou Membre
    mai 2017 modifié #3

    T'as un petit exemple rapide sous la main ? ^^


    J't'avoue que j'utilise jamais les tag des vues..


     


    // Edit


    En fait, j'viens de me débrouiller autrement, il reste un petit soucis, je corriger et je post ma solution après, si ça peut en aider certains ^^


  • LarmeLarme Membre
    mai 2017 modifié #4

    self.windows.rootViewController devrait fonctionner (codé sans tester).


    Après, en fonction de l'architecture, rootViewController peut être un UINavigationController, UITabBarController, etc. et ils doivent avoir un truc comme presentedViewController, etc.


     


    Maintenant, tu peux poster toi-même un NSNotification au sein de ton application, et même avec différents noms en fonction des push notifications, et chaque ViewController peut écouter des NSNotification et agir en fonction.


  • InsouInsou Membre
    mai 2017 modifié #5

    Alors voilà  où j'en suis : 


     


    Dans AppDelegate, j'ai rajouté : 



    extension UIWindow {
        
        func visibleViewController() -> UIViewController? {
            if let rootViewController: UIViewController = self.rootViewController {
                return UIWindow.getVisibleViewControllerFrom(vc: rootViewController)
            }
            return nil
        }
        
        class func getVisibleViewControllerFrom(vc:UIViewController) -> UIViewController {
            
            switch(vc){
                case is UINavigationController:
                    let navigationController = vc as! UINavigationController
                    return UIWindow.getVisibleViewControllerFrom( vc: navigationController.visibleViewController!)
                break;
                
                case is UITabBarController:
                    let tabBarController = vc as! UITabBarController
                    return UIWindow.getVisibleViewControllerFrom(vc: tabBarController.selectedViewController!)
                break;

                default:
                    if let presentedViewController = vc.presentedViewController {
                        //print(presentedViewController)
                        if let presentedViewController2 = presentedViewController.presentedViewController {
                            return UIWindow.getVisibleViewControllerFrom(vc: presentedViewController2)
                        }
                        else{
                            return vc;
                        }
                    }
                    else{
                        return vc;
                    }
                break;
            }
            
        }

    }

    et je l'utilise comme ça : 



    if let topController = window?.visibleViewController() {

    switch(topController){
    case is DiscussionsCollectionViewController:
    print("sur Discussions")
    break;

    case is GroupeDeDiscussionsCollectionViewController:
    print("sur Groupe de discussions")
    break;

    default:
    print("Pas sur une page importante")
    break;
    }
    }

    Du coup, ça fonctionne bien..


     


    Maintenant, deuxième soucis, comment déclencher une fonction quand je suis dans un cas qui m'intéresse ?


     


    Par exemple, dans DiscussionsCollectionViewController, j'ai une fonction chargeDiscussion..


    Je pensais juste faire : 



    case is DiscussionsCollectionViewController:
    print("sur Discussions")
    DiscussionsCollectionViewController().chargeDiscussion()
    break;

    Mais ça ne fonctionne pas.. une idée ?


  • LarmeLarme Membre

    case is DiscussionsCollectionViewController:
         print("sur Discussions")
         DiscussionsCollectionViewController().chargeDiscussion()
    break;

    Euh, j'suis pas fort en Swift, mais tu fais un alloc/init d'un nouveau DiscussionsCollectionViewController et tu appelles chargeDiscussion(), non ?


    Pourquoi ne pas faire (topController as DiscussionsCollectionViewController).chargeDiscussion()

  • InsouInsou Membre

    Parce que mon cerveau embrouillé ne trouvait plus la syntaxe.. mais maintenant que j'le vois écrit, c'était tout con et logique ^^


    ça fonctionne nickel, merci ^^


  • Joanna CarterJoanna Carter Membre, Modérateur


    Bonjour,


     


    J'ai un petit soucis sur comment savoir sur quelle vue je me trouve dans AppDelegate..


     


    En gros, je reçois des notifications push silencieuse, si je suis sur tel ou tel interface, mon action est différente..


     


    Par contre, je n'arrive pas à  savoir sur quelle vue je suis quand je reçois la notification..


     


    Comment-vous vous y prenez pour savoir sur quelle view l'utilisateur est (dans AppDelegate) ?




     


    Je demanderais, pourquoi ? Surtout dans l'AppDelegate ???

  • InsouInsou Membre

    C'est dans appDelegate que je gère la réception de mes notifications silencieuses..


     


    Si j'en reçois une de type "Message", je veux faire une action différente suivant là  où je me trouve..


    Par exemple :


    - Je suis sur la liste des conversation : je refresh la liste


    - Je suis dans la bonne conversation : je refresh la conversation


    - Je suis ailleurs : j'envois une notification locale pour avertir qu'il y a un nouveau message


     


    etc, etc ^^


  • Joanna CarterJoanna Carter Membre, Modérateur

    Bah non. Tu devrais recevoir les notifications dans l'AppDelegate mais, de là , tu pourrais utiliser NotificationCenter.default pour poster tes propres notifications, que tu puisses recevoir dans les ViewControllers.


  • HorusHorus Membre

    Je pense à  une solution comme celle de Larme :



    let nav = UIApplication.shared.keyWindow?.rootViewController

    Comme ça tu peux la caster avec as? UINavigationController (si ça correspond à  ton type de navigation) et si besoin :



    nav?.viewControllers.first

    Pour récupérer la viewController 


  • Joanna CarterJoanna Carter Membre, Modérateur

    C'est pas nécessaire de toucher les ViewControllers depuis l'AppDelegate. ça confond le logique de l'UI avec la logique de l'appli.


     


    Les notifications locaux, envoyées aux ViewControllers marchent très bien et résolvent le problème sans besoin de fouiller parmi tous les fenêtres ou ViewControllers.


  • CéroceCéroce Membre, Modérateur

    C'est pas nécessaire de toucher les ViewControllers depuis l'AppDelegate. ça confond le logique de l'UI avec la logique de l'appli.


    Il y a au moins un cas où c'est nécessaire: quand c'est l'AppDelegate qui instancie le Modèle. Il doit connaà®tre le premier ViewController pour pouvoir lui passer le Modèle. Certes, tout le monde ne passe pas le modèle, mais ce que je dis est clairement décrit dans le guide des Storyboards.
  • Joanna CarterJoanna Carter Membre, Modérateur


    Il y a au moins un cas où c'est nécessaire: quand c'est l'AppDelegate qui instancie le Modèle. Il doit connaà®tre le premier ViewController pour pouvoir lui passer le Modèle. Certes, tout le monde ne passe pas le modèle, mais ce que je dis est clairement décrit dans le guide des Storyboards.




     


     


    Tu as raison. Mais, pour ce que Insou voulait, c'est pas conseillé 

  • CéroceCéroce Membre, Modérateur

    Certes, tout le monde ne passe pas le modèle, mais ce que je dis est clairement décrit dans le guide des Storyboards.

    Joanna m'a demandé où ça se trouvait dans le guide, mais je suis bien en peine de le faire, il n'y a même pas de Storyboard Programming Guide.
Connectez-vous ou Inscrivez-vous pour répondre.