当应用程序从 iOS 中的本地通知进入前台时触发特定操作?(使用快速)

人气:345 发布:2022-10-16 标签: ios swift uiwebview uilocalnotification

问题描述

我正在使用新语言 Swift 构建一个 iOS 应用程序.现在它是一个 HTML5 应用程序,使用 UIWebView 显示 HTML 内容.该应用程序具有本地通知,我想要做的是当应用程序通过单击(触摸)本地通知进入前台时触发 UIWebView 中的特定 javascript 方法.

I am building an iOS app using the new language Swift. Now it is an HTML5 app, that displays HTML content using the UIWebView. The app has local notifications, and what i want to do is trigger a specific javascript method in the UIWebView when the app enters foreground by clicking (touching) the local notification.

我看过这个问题,但它似乎并没有解决我的问题.我也遇到过这个 ​​question 告诉我有关使用 UIApplicationState 的信息,这很好,因为这可以帮助我了解应用程序从通知中进入前台.但是当应用程序恢复时,我如何在应用程序恢复时显示的视图的 viewController 中调用方法?

I have had a look at this question, but it does not seem to solve my problem. I have also come across this question which tells me about using UIApplicationState, which is good as that would help me know the the app enters foreground from a notification. But when the app resumes and how do i invoke a method in the viewController of the view that gets displayed when the app resumes?

我想做的是获取我的 ViewController 的一个实例并将其中的一个属性设置为 true.内容如下

What i would like to do is get an instance of my ViewController and set a property in it to true. Something as follows

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

在我的 AppDelegate 中我有方法

And in my AppDelegate i have the method

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;


}

所以我想做的是当应用程序再次进入前台时,我想查看执行变量并运行如下方法,

so what i would like to do is when the app enters foreground again, i want to look at the execute variable and run the method as follows,

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

我应该将用于从 webview 触发 javascript 的逻辑代码放在哪里?是在 viewDidLoad 方法上,还是在 webView 委托方法之一上?我试图将该代码放在 viewDidLoad 方法中,但布尔执行的值设置为其初始值,而不是应用程序进入前台时在委托中设置的值.

Where should i put the code for the logic to trigger the javascript from the webview? would it be on viewDidLoad method, or one of the webView delegate methods? i have tried to put that code in the viewDidLoad method but the value of the boolean execute is set to its initial value and not the value set in the delegate when the app enters foreground.

推荐答案

如果我希望在应用程序回到前台时通知视图控制器,我可能只注册 UIApplication.willEnterForegroundNotificationcode> 通知(完全绕过应用委托方法):

If I want a view controller to be notified when the app is brought back to the foreground, I might just register for the UIApplication.willEnterForegroundNotification notification (bypassing the app delegate method entirely):

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)
        }
    }
}

注意,在完成闭包中,我包含了 [unowned self] 以避免强引用循环,如果你碰巧在里面引用 self 会阻止视图控制器被释放块(如果你要更新一个类变量或做任何有趣的事情,你可能需要这样做).

Note, in the completion closure, I include [unowned self] to avoid strong reference cycle that prevents the view controller from being deallocated if you happen to reference self inside the block (which you presumably will need to do if you're going to be updating a class variable or do practically anything interesting).

另请注意,即使偶然阅读 removeObserver 文档 可能会让人断定没有必要:

Also note that I remove the observer even though a casual reading of the removeObserver documentation might lead one to conclude is unnecessary:

如果您的应用面向 iOS 9.0 及更高版本或 macOS 10.11 及更高版本,则无需在其 dealloc 方法中取消注册观察者.

If your app targets iOS 9.0 and later or macOS 10.11 and later, you don't need to unregister an observer in its dealloc method.

但是,当使用这种基于块的再现时,您确实需要删除通知中心观察者.作为 addObserver(forName:object:queue:使用:) 说:

But, when using this block-based rendition, you really do need to remove the notification center observer. As the documentation for addObserver(forName:object:queue:using:) says:

要取消注册观察,请将此方法返回的对象传递给 removeObserver(_:).您必须调用 removeObserver(_:)removeObserver(_:name:object:)addObserver(forName:object:queue:using:) 指定的任何对象被释放之前.

To unregister observations, you pass the object returned by this method to removeObserver(_:). You must invoke removeObserver(_:) or removeObserver(_:name:object:) before any object specified by addObserver(forName:object:queue:using:) is deallocated.

672