web-dev-qa-db-fra.com

Déclencher une action spécifique lorsque l'application passe au premier plan à partir d'une notification locale dans iOS? (en utilisant Swift)

Je crée une application iOS en utilisant la nouvelle langue Swift. Maintenant, c'est une application HTML5, qui affiche du contenu HTML à l'aide de l'UIWebView. L'application a des notifications locales, et ce que je veux faire, c'est déclencher une méthode javascript spécifique dans l'UIWebView lorsque l'application passe au premier plan en cliquant (touchant) la notification locale.

J'ai jeté un œil à cela question , mais cela ne semble pas résoudre mon problème. J'ai également rencontré ce question qui me dit d'utiliser UIApplicationState, ce qui est bien car cela m'aiderait à savoir que l'application entre au premier plan à partir d'une notification. Mais lorsque l'application reprend et comment puis-je appeler une méthode dans le viewController de la vue qui s'affiche lorsque l'application reprend?

Ce que je voudrais faire, c'est obtenir une instance de mon ViewController et lui attribuer la valeur true. Quelque chose comme suit

class FirstViewController: UIViewController,UIWebViewDelegate { 
  var execute:Bool = false;
  @IBOutlet var tasksView: UIWebView!
}

Et dans mon AppDelegate j'ai la méthode

func applicationWillEnterForeground(application: UIApplication!) {
    let viewController = self.window!.rootViewController;
    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

    var setViewController = mainStoryboard.instantiateViewControllerWithIdentifier("FirstView") as FirstViewController
    setViewController.execute = true;


}

donc ce que je voudrais faire, c'est quand l'application passe à nouveau au premier plan, je veux regarder la variable d'exécution et exécuter la méthode comme suit,

if execute{
 tasksView.stringByEvaluatingJavaScriptFromString("document.getElementById('sample').click()");
}

Où dois-je mettre le code de la logique pour déclencher le javascript à partir de la vue Web? serait-ce sur la méthode viewDidLoad, ou l'une des méthodes déléguées webView? J'ai essayé de mettre ce code dans la méthode viewDidLoad, mais la valeur de l'exécution booléenne est définie sur sa valeur initiale et non sur la valeur définie dans le délégué lorsque l'application entre au premier plan.

21
cptdanko

Si je veux qu'un contrôleur de vue soit averti lorsque l'application est ramenée au premier plan, je pourrais simplement m'inscrire à la notification UIApplication.willEnterForegroundNotification (En contournant complètement la méthode déléguée de l'application):

class ViewController: UIViewController {

    private var observer: NSObjectProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()

        observer = NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: .main) { [unowned self] notification in
            // do whatever you want when the app is brought back to the foreground
        }
    }

    deinit {
        if let observer = observer {
            NotificationCenter.default.removeObserver(observer)
        }
    }
}

Remarque, dans la fermeture de l'achèvement, j'inclus [unowned self] Pour éviter un cycle de référence fort qui empêche le contrôleur de vue d'être désalloué si vous faites référence à self à l'intérieur du bloc (ce que vous devrez probablement faire) si vous allez mettre à jour une variable de classe ou faire pratiquement n'importe quoi d'intéressant).

Notez également que je supprime l'observateur même si une lecture occasionnelle du removeObserverdocumentation pourrait conduire à conclure qu'il n'est pas nécessaire:

Si votre application cible iOS 9.0 et versions ultérieures ou macOS 10.11 et versions ultérieures, vous n'avez pas besoin de désinscrire un observateur dans sa méthode de désallocation.

Mais, lorsque vous utilisez ce rendu basé sur des blocs, vous devez vraiment supprimer l'observateur du centre de notification. Comme la documentation pour addObserver(forName:object:queue:using:) dit:

Pour annuler l'enregistrement des observations, vous passez l'objet renvoyé par cette méthode à removeObserver(_:) . Vous devez appeler removeObserver(_:) ou removeObserver(_:name:object:) avant que tout objet spécifié par addObserver(forName:object:queue:using:) soit désalloué.

58
Rob

Ajouter du code ci-dessous dans ViewController

override func viewDidLoad() {
super.viewDidLoad()
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector:#selector(appMovedToForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
   }

  @objc func appMovedToForeground() {
  print("App moved to foreground!")
  }
0
ShigaSuresh