2014-09-08 7 views
13

Sto costruendo un'app per iOS utilizzando la nuova lingua Swift. Ora è un'app HTML5, che visualizza il contenuto HTML utilizzando UIWebView. L'app ha notifiche locali e ciò che voglio fare è attivare un metodo javascript specifico in UIWebView quando l'applicazione passa in primo piano facendo clic su (toccando) la notifica locale.Attivare un'azione specifica quando l'app passa in foreground da una notifica locale in iOS? (usando swift)

Ho dato un'occhiata a questo question, ma non sembra risolvere il mio problema. Ho anche trovato questo question che mi dice di usare UIApplicationState, il che è buono in quanto mi aiuterebbe a sapere che l'app passa in primo piano da una notifica. Ma quando l'app riprende e come faccio a richiamare un metodo nel viewController della vista che viene visualizzata quando l'app riprende?

Quello che mi piacerebbe fare è ottenere un'istanza del mio ViewController e impostare una proprietà su true. Qualcosa come segue

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

E nella mia AppDelegate ho il metodo

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; 


} 

così che cosa vorrei fare è quando l'applicazione entra in primo piano ancora una volta, voglio guardare l'esecuzione variabile e corsa il metodo come segue,

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

Dove dovrei inserire il codice per la logica per attivare il javascript dalla visualizzazione Web? sarebbe sul metodo viewDidLoad o su uno dei metodi delegate di WebView? Ho provato a inserire quel codice nel metodo viewDidLoad ma il valore dell'esecuzione booleana è impostato sul suo valore iniziale e non sul valore impostato nel delegato quando l'app passa in foreground.

+0

Quindi ho scritto un post sul blog su ciò che volevo veramente e su come ho risolto il problema, ne ho letto. http://captaindanko.blogspot.com.au/2014/12/knowing-which-notification-brought-my.html – cptdanko

risposta

32

Se voglio un controller di vista di essere avvisato quando l'applicazione viene riportato in primo piano, potrei registrare per il .UIApplicationWillEnterForeground notifica (bypassando il metodo delegato app del tutto):

class ViewController: UIViewController { 

    private var notification: NSObjectProtocol? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     notification = NotificationCenter.default.addObserver(forName: .UIApplicationWillEnterForeground, object: nil, queue: .main) { 
      [unowned self] notification in 

      // do whatever you want when the app is brought back to the foreground 
     } 
    } 

    deinit { 
     // make sure to remove the observer when this view controller is dismissed/deallocated 

     if let notification = notification { 
      NotificationCenter.default.removeObserver(notification) 
     } 
    } 
} 

nota, in la chiusura di completamento, includo [unowned self] per evitare un ciclo di riferimento forte che impedisca la disconnessione del controller di visualizzazione se si fa riferimento allo self all'interno del blocco (che presumibilmente sarà necessario fare se si sta aggiornando una variabile di classe o praticamente niente di interessante).

In alternativa, se non si desidera utilizzare la notifica di block-based, è possibile utilizzare il vecchio approccio basato selettore:

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground(_:)), name: .UIApplicationWillEnterForeground, object: nil) 

    } 

    func willEnterForeground(_ notification: NSNotification!) { 
     // do whatever you want when the app is brought back to the foreground 
    } 

    deinit { 
     // make sure to remove the observer when this view controller is dismissed/deallocated 

     NotificationCenter.default.removeObserver(self) 
    } 
} 
+0

Apprezzo il dettaglio nella risposta. Ora come avrete intuito, sono molto nuovo alla programmazione di ios e non ho esperienza di pubblicazione sull'app store. Quindi, se ignoro il metodo di delega dell'app per le notifiche, aumenterà le possibilità che la mia app non cancelli il processo di approvazione dell'invio dello store app? – cptdanko

+2

No, questa notifica è un'interfaccia pubblica documentata e ben stabilita, quindi è un meccanismo approvato. Va bene. – Rob

+0

Cosa succede se hai registrato più di un osservatore e vuoi che tutti vengano rimossi al deinit? – confile

-1

In Swift 3, sostituisce e genera i seguenti.

override func viewDidLoad() { 
     super.viewDidLoad() 

     foregroundNotification = NotificationCenter.default.addObserver(forName: 
     NSNotification.Name.UIApplicationWillEnterForeground, object: nil, queue: OperationQueue.main) { 
      [unowned self] notification in 

     // do whatever you want when the app is brought back to the foreground 
    }