从AppDelegate更改WebView URL

时间:2017-04-14 09:07:50

标签: swift webview appdelegate

我在AppDelegate类中接收来自Firebase的通知 此通知包含名为" notif_url"的字符串。我已将此值放在名为" desired_url"的var中。现在我需要使用" desired_url"更改我的WebView网址。值。

但我无法访问网页视图来更改网址:

@IBOutlet weak var my_web_view: UIWebView!

func load_url(server_url: String){
    let url = URL(string: server_url);
    let request = URLRequest(url: url!);
    my_web_view.loadRequest(request);
}

load_url(server_url: desired_url);

你知道我是否可以这样做,如果是,怎么做?

图像:
enter image description here enter image description here

编辑1:
添加breakPoint以了解错误的行之后,看起来该行就是这一行:

my_web_view.loadRequest(request)

编辑2:
如果需要,这是我的AppDelegate类代码的一部分。

import UIKit
import UserNotifications

import Firebase

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let gcmMessageIDKey = "gcm.message_id"
    @IBOutlet weak var my_web_view: UIWebView!

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        return true
    }
}

// [START ios_10_message_handling]
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate{

    // Receive displayed notifications for iOS 10 devices.
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void){
        print("Step : 12");
        let userInfo = notification.request.content.userInfo
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey]{
            print("Message ID: \(messageID)")
        }

        // Print full message.
        print(userInfo)
        var url: String = userInfo[AnyHashable("url")] as! String;
        load_url(server_url: url);

        // Change this to your preferred presentation option
        completionHandler([])
    }

    func load_url(server_url: String){
        /*
        let url = URL(string: server_url);
        let request = URLRequest(url: url!);
        my_web_view.loadRequest(request);
         */

        guard let url = URL(string: server_url) else {
            print("Invalid URL")
            return
        }

        print("TRY : "+server_url);

        let request = URLRequest(url: url)
        my_web_view.loadRequest(request)
    }
}

编辑3:
如果需要,那就是我的ViewController类代码。

import Foundation
import UIKit
import SafariServices
import UserNotifications

class ViewController: UIViewController, UIWebViewDelegate{

    @IBOutlet weak var my_web_view: UIWebView!
    @IBOutlet weak var my_loading_view: UIView!
    @IBOutlet weak var spinner : UIActivityIndicatorView!
    @IBOutlet weak var app_logo : UIImageView!

    @IBOutlet weak var deadlinePicker: UIDatePicker!
    @IBOutlet weak var titleField: UITextField!

    var new_url: String = "";

    override func viewDidLoad(){
        super.viewDidLoad()

        let server_url = "https://www.sortirauhavre.com/";

        NotificationCenter.default.addObserver(self, selector: #selector(self.rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
        rotated();

        spinner.startAnimating();


        my_web_view.scrollView.bounces = false;
        my_web_view.scrollView.isScrollEnabled = true;

        let url = URL(string: server_url);
        let request = URLRequest(url: url!);
        my_web_view.loadRequest(request);
    }

    // CETTE FONCITON SE LANCE A LA ROTATION DE L'APPAREIL
    func rotated(){
        app_logo.center = my_loading_view.center;
        let y = app_logo.frame.origin.y;
        let h = app_logo.frame.size.height
        app_logo.frame.origin.y = y-(h/2);

        spinner.center = my_loading_view.center;
    }

    // CETTE FONCTION MET EN ARRIERE PLAN L'ANNIMATION DE CHARGEMENT
    func removeLoader(){
        self.view.addSubview(my_web_view);
    }

    // CETTE FONCTION MET EN PREMIER PLAN L'ANNIMATION DE CHARGEMENT
    func addLoader(){
        self.view.addSubview(my_loading_view);
    }

    // CETTE FONCTION SE DECLANCHE QUAND LES PAGES DE LA WEBVIEW COMMENCE A CHANGER
    func webViewDidStartLoad(_ webView: UIWebView){
        addLoader();
        let server_url = "https://www.sortirauhavre.com/";
        _ = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.removeLoader), userInfo: nil, repeats: false);
        if let text = webView.request?.url?.absoluteString{
            if text.hasPrefix(server_url){
            }
            else if text != ""{
                UIApplication.shared.openURL(URL(string: text)!)
                my_web_view.goBack()
            }
        }
    }

    // CETTE FONCTION SE DECLANCHE QUAND LES PAGES DE LA WEBVIEW FINI DE CHANGER
    func webViewDidFinishLoad(_ webView: UIWebView){
        let server_url = "https://www.sortirauhavre.com/";
        _ = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.removeLoader), userInfo: nil, repeats: false);
        if let text = webView.request?.url?.absoluteString{
            if text.hasPrefix(server_url){
            }
            else if text != ""{
                UIApplication.shared.openURL(URL(string: text)!)
                my_web_view.goBack()
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

您强制解包url这不是有效的网址。如果创建了无效的URL,我建议添加guard语句以防止崩溃:

func load_url(server_url: String) {
    guard let url = URL(string: server_url) else {
        print("Invalid URL")
        return
    }

    let request = URLRequest(url: url)
    my_web_view.loadRequest(request)
}

当您在AppDelegate中获取网址时,您无法简单地更新此类中的UIWebView。您需要在my_web_view的父类中调用一个更新URL的函数。

// App Delegate

var serverURL: String?

func load_url(server_url: String) {
    serverURL = server_url
    let notificationName = Notification.Name("updateWebView")
    NotificationCenter.default.post(name: notificationName, object: nil)
}


// View Controller

override func viewDidLoad() {
    let notificationName = Notification.Name("updateWebView")
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.updateWebView), name: notificationName, object: nil)

    updateWebView()
}

func updateWebView() {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let serverURL = appDelegate.serverURL

    guard let url = URL(string: serverURL) else {
        print("Invalid URL")
        return
    }

    let request = URLRequest(url: URL)
    my_web_view.loadRequest(request)
}

答案 1 :(得分:2)

您只需要访问视图控制器的当前实例,而不是创建视图控制器的新实例或尝试复制插座。您可以使用:

  1. 视图控制器的全局值,或
  2. 类似单身的模式。
  3. 然后,您可以通过调用myGlobalViewController.webViewViewController.instance.webView来启动应用代理中的实例。

    所以,这是一个例子:

    import UIKit
    
    private var thisViewController: ViewController? // Will hold the instance.
    
    class ViewController: UIViewController {
    
        static var instance: ViewController {
            guard let thisViewController = thisViewController else { fatalError() } // Don't do this unless you're 100% sure that you'll never access this before the instance is loaded.
            return thisViewController
        }
    
        @IBOutlet weak var webView: UIWebView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            thisViewController = self // Set the property to self.
        }
    ...
    }
    

    在此之后,您可以从应用代表访问网络视图:

    func load_url(server_url: String){
        guard let url = URL(string: server_url) else {
            return
        }
    
        let request = URLRequest(url: url)
        ViewController.instance.webView.loadRequest(request)
    }