Grab loaded webpage URL? WKWebView macOS - swift

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.urlText.stringValue = String(describing: webView.url!)
}
This does not work 100% of the time.
An example would be when I navigate to reddit. I click a thread and it changes URL which is fine, but if I click the reddit home button, it doesn't change URL to www.reddit.com even after it is 100% loaded.
Any help is appreciated.

What else is going on in your view controller? I'm not able to reproduce your problem with the code below. Have you tried this in an isolated project?
import Cocoa
import WebKit
class ViewController: NSViewController {
#IBOutlet weak var webView: WKWebView!
#IBOutlet weak var urlLabel: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
let req = URLRequest(url:
URL(string: "https://reddit.com")!)
webView.load(req)
}
#IBAction func getUrlClicked(_ sender: Any) {
guard let url = webView.url else { return }
urlLabel.stringValue = url.absoluteString
print("url: \(String(describing: webView.url!))")
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}

Related

Need help to reload WKWebView from tabbed navigation in Swift

I'm trying to make this reload when a user clicks on the tab. I tried a simple reload but didn't work.
#IBOutlet weak var TabOne: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://www.google.com")
let urlRequest = URLRequest(url:url!)
TabOne.load(urlRequest)
}
Move the reload code into the viewWillAppear(_:)
as viewDidLoad() will only be called once in the view controller life cycle, while viewWillAppear(_:) will be called every time the view is going to appear on the screen.
This is the code that ended up working.
import UIKit
import WebKit
class FirstViewController: UIViewController {
#IBOutlet weak var TabOne: WKWebView!
override func viewWillAppear(_ animated: Bool) {
let url = URL(string: "https://www.google.com")
let urlRequest = URLRequest(url:url!)
TabOne.load(urlRequest)
}
}

Issue with programmatically adding ActivityIndicator with WKWebView, not appearing

My code successfully loads the web page that I want it to; however, I'm having issues adding my activity indicator for while it is loading.
I am relatively new to swift, so I was reading other stackexchange examples. I created a UIActivityIndicator, set it in the override func, but it doesn't show up.
The webpage loads fine. Here is the runnable code.
import UIKit
import WebKit
class FeedbackWebViewController: UIViewController, WKNavigationDelegate {
let indicator = UIActivityIndicatorView(style: .gray)
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
indicator.center = webView.center
indicator.hidesWhenStopped = true
webView.addSubview(indicator)
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://www.apple.com")!
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
self.indicator.startAnimating()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
indicator.stopAnimating()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
indicator.stopAnimating()
}
}
DONT override loadView. bad things may happen.
move code in didLoad. it should work.
try to put the related 3 lines to viewDidAppear rather than viewDidLoad. It works for me.

How can i use open in new tab in swift ?(WEBKIT)

How can i use safari-open in new tab in my webkit app
I am creating a internet browser and i need that
Just like the photo
For example, I want to show the open in new tab option when I hold my finger on a link in Google
enter image description here
class ViewController: UIViewController, UITextFieldDelegate, WKNavigationDelegate {
#IBOutlet weak var backButton: UIButton!
#IBOutlet weak var forwardButton: UIButton!
#IBOutlet weak var webView: WKWebView!
#IBOutlet weak var urlTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
urlTextField.delegate = self
webView.navigationDelegate = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear( animated )
let urlString:String = "https://www.google.com"
let url:URL = URL(string: urlString)!
let urlRequest:URLRequest = URLRequest(url: url)
webView.load(urlRequest)
urlTextField.text = urlString
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let urlString:String = urlTextField.text!
let url:URL = URL(string: urlString)!
let urlRequest:URLRequest = URLRequest(url: url)
webView.load(urlRequest)
textField.resignFirstResponder()
return true
}
#IBAction func backButtonTapped(_ sender: Any) {
if webView.canGoBack {
webView.goBack()
}
}
#IBAction func forwardButtonTapped(_ sender: Any) {
if webView.canGoForward {
webView.goForward()
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
backButton.isEnabled = webView.canGoBack
forwardButton.isEnabled = webView.canGoForward
urlTextField.text = webView.url?.absoluteString
}
}
Use this delegate method in bellow you last medhod :
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.targetFrame == nil {
if let url = navigationAction.request.url {
let app = UIApplication.shared
if app.canOpenURL(url) {
app.open(url, options: [:], completionHandler: nil)
}
}
}
decisionHandler(.allow)
}
is It oky ?

Open a link using the button and textfield

Can I open a link using the button and textfield on which the link is listed on another page within the app itself and not with Safari?
I'm using Swift 4
You have to open webview in destination view controller and send url string from first view controller to destination like below:
class ViewController: UIViewController {
#IBOutlet weak var textField: UITextField!
#IBAction func action(_ sender: Any) {
if let mainVC = storyboard?.instantiateViewController(withIdentifier: "second") as? DestinationViewController {
mainVC.urlStr = textField.text
self.navigationController?.pushViewController(mainVC, animated: true)
}
}
}
Destination View controller:
class DestinationViewController: UIViewController {
var urlStr: String?
override func viewDidLoad() {
super.viewDidLoad()
let webView = UIWebView(frame: self.view.frame)
self.view.addSubview(webView)
if let urlString = urlStr, let url = URL(string: urlString) {
webView.loadRequest(URLRequest(url: url))
}
}
}
Just Use WKWebView to open the link on Button action using this
Import WebKit
import WebKit
In your FirstViewController pass the URL while pushing to
SecondViewController
FirstViewController
if let secondVC = (UIStoryboard.init(name: "Main", bundle: nil)).instantiateViewController(withIdentifier: "secondVCID") {
secondVC.url = textFiled.text // OR send the URL you want to send
self.navigationController?.pushViewController(secondVC, animated: true)
}
In SecondViewController
Import Webkit
declare the delegate
class SecondViewController: UIViewController,WKNavigationDelegate {
declare the URL var so that u cab access it n FirstVC
var url: String?
#IBOutlet weak var webView: WKWebView!
In ViewDidLoad Of SecondVC
let webUrl = NSURL(string: url!)
let request = NSURLRequest(URL: webUrl)
// load request in webview.
webView.navigationDelegate = self
webView.loadRequest(request)
and Implement all delegate methods of WKWebview
//MARK:- WKNavigationDelegate
func webView(webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
print(error.localizedDescription)
}
func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("Strat to load")
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
print("finish to load")
}

UIActivityIndicator doesn't hide after loading page in WKWebView

I am trying to create a WKWebView app with a UIActivityIndicator (in Xcode 9). Below is my code, but when I try to simulate it, the activity indicator doesn't stop, neither hide.
import UIKit
import WebKit
class ViewController: UIViewController {
#IBOutlet var loader: UIActivityIndicatorView!
#IBOutlet var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://www.amritvani.nl")
let request = URLRequest(url: url!)
webView.navigationDelegate = self as? WKNavigationDelegate
webView.load(request)
}
func webViewDidStartLoad(webView: WKWebView){
loader.startAnimating()
}
func webViewDidFinishLoad(webView: WKWebView){
loader.stopAnimating()
loader.hidesWhenStopped = true
}
}
Could someone help me with this problem?
Your delegate methods are wrong. Replace webViewDidStartLoad(webView:) with this:
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
loader.startAnimating()
}
...and webViewDidFinishLoad(webView:) with this:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
loader.stopAnimating()
}
Also, you should conform your class to WKNavigationDelegate:
class ViewController: UIViewController, WKNavigationDelegate
There are two more problems with your code. Firstly, you shouldn't cast your class to WKNavigationDelegate with as? if it already conforms to it:
webView.navigationDelegate = self
Secondly, you should set the hidesWhenStopped attribute of your activity indicator to true before stopping it, preferably in Interface Builder or in viewDidLoad. This is not crucial, but it makes much more sense if someone else reads your code and it's also superfluous if webView(_:didFinish:) executes multiple times.