Detect when the WebView finishes loading in Swift4? - ios

I want to display progress while the WebView is loading and dismiss it when the WebView finishes loading.
I tried this code:
import UIKit
import WebKit
import SVProgressHUD
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var WebView1: WKWebView!
#IBOutlet var WebView2: WKWebView!
let YouTubeURL = URL (string: "https://www.youtube.com/")
#IBAction func YTButtonAction(_ sender: Any) {
let YTRequest = URLRequest(url: YouTubeURL!)
WebView1.load(YTRequest)
if WebView1.isLoading {
SVProgressHUD.show()
}
func webViewDidFinishLoad(WebView1 : UIWebView) {
SVProgressHUD.dismiss()
}
}
}
But it doesn't work.
The progress continue rotating.
Anybody knows how to solve this problem?

Three fatal issues:
You have to set the delegate
WebView1.delegate = self
The signature of the delegate method is wrong
func webViewDidFinishLoad(_ webView: UIWebView)
The delegate method must be on the top level of the class.
I think there is a fourth fatal issue: I doubt that WKWebView conforms to UIWebViewDelegate at all. I suppose you have to adopt WKNavigationDelegate and implement webView(:didFinish:) instead.
And please conform to the Swift naming convention that variable and function / method names start with a lowercase letter.

The answer :
I changed
UIWebViewDelegate to WKNavigationDelegate
WebView1.delegate = self to WebView1. navigationDelegate = self
The name of the WKWebView property is navigationDelegat
func webViewDidFinishLoad(WebView1 : UIWebView) to
func webView(_ webView: WKWebView,
didFinish navigation: WKNavigation!)

Related

How to use didFinish navigation on an WKWebView passed to another class

I'm setting up an app, where the WKWebView object is created in one class, and then passed to another class for handling, but when I use didFinish navigation in the second class, it never gets called.
I have added the WKNavigationDelegate protocol, and set navigationDelegate = self
class one: UIViewController {
var webView: WKWebView = WKWebView();
override func viewDidLoad(){
var second = Second()
second.web = webView;
second.test()
}
}
class second: NSObject, WKNavigationDelegate {
var web: WKWebView? = nil;
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Test")
}
func test(){
self.web!.load(URLRequest(url: URL(string: "https://google.com")!))
}
}
I never see the "Test" message.
Make it an instance var to retain the object so delegate to be called
var second = Second() /// << here
override func viewDidLoad(){
super.viewDidLoad()
......
}
func test(){
self.web!.navigationDelegate = self
self.web!.load(URLRequest(url: URL(string: "https://google.com")!))
}
import UIKit
import WebKit
class WKWebViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var webWK: WKWebView!
#IBOutlet weak var activityIndi: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
webWK.navigationDelegate = self
let appStoreURL = URL(string: "https://google.com")
webWK.load(URLRequest(url: appStoreURL!))
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
activityIndi.startAnimating()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
activityIndi.stopAnimating()
}
}

How can i add multiple HTML files to WebKit View?

Introduction
I'm designing a historical application.I want to add multiple HTML files into
WebKit View. I don't have any idea how to do this.
Example
When I click to "Button 1" webkit loads "file1.html". I didn't write anything about code I am quite confused. Any help would be appreciated.
Well, there is a lot of ways to do it but I'm gonna give an example for easiest one. Just create a method for loading .html file and invoke or call it under action button.
For example :
import UIKit
import WebKit
class ExampleController: UIViewController {
#IBOutlet weak var myButton: UIButton!
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
}
#IBAction func firstButtonPressed(_ sender: UIButton) {
// Here you can call your method to load html page.
loadPage(pageName: "privacy_policy")
}
#IBAction func secondButtonPressed(_ sender: UIButton) {
// Here you can call different html page.
loadPage(pageName: "terms")
}
// With this method you can call html page by it name (as parameter)
fileprivate func loadPage(pageName: String) {
let url = Bundle.main.url(forResource: pageName, withExtension: "html")
// file url is ready lets to add it as parameter for webView.
webView.loadFileURL(url!, allowingReadAccessTo: url!)
}
}
extension AboutAppController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
// Here you can add start your animations (like activity indicator)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// And here finish your animations.
}
}

Retrieve WebVie URL Swift || Cannot assign value of type 'ViewController' to type 'UIWebViewDelegate?'

I would like to load a web page then be able to retrieve the current web page after the user has logged in and been redirected. I have achieved the loading of a webpage but am unable to retrieve the URL after the user has moved to a new page. The current code that I have is:
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
needlogin()
}
func needlogin(){
let url = URL(string: "https://www.instagram.com/oauth/authorize/?client_id="+clientid+"&redirect_uri="+redirecturl+"&response_type=token&scope=likes+comments+public_content+follower_list+relationships")
let urlrequest = URLRequest(url: url!)
webView.loadRequest(urlrequest)
self.webView.delegate = self
}
func webViewDidFinishLoad(_ webView: UIWebView){
}
The problem I have is with self.webView.delegate = self . I get the error message :
Cannot assign value of type 'ViewController' to type
'UIWebViewDelegate?'
Furthermore I have no clue how to retrieve the URL at all and would appreciate your help.
You would need to conform to UIWebviewDelegate protocol. So you would need to do something like
class ViewController: UIViewController, UIWebViewDelegate {
}
at the top of your class definition.
To retrieve the URL after the webview has finished loading, within your webViewDidFinishLoad method, you would need to do something like webView.request.URL.
Disclaimer: You should be using WKWebview rather than UIWebview for iOS + applications. The way to do it would be something like this for your example:
import UIKit
import WebKit
class WebviewController: UIViewController, WKNavigationDelegate {
var wkWebview : WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
needsLogin()
}
func needsLogin() {
wkWebview = WKWebView.init(frame: self.view.bounds)
wkWebview?.navigationDelegate = self
self.view.addSubview(wkWebview!)
let url = URL(string: "https://www.instagram.com/oauth/authorize/? client_id="+clientid+"&redirect_uri="+redirecturl+"&response_type=token&scope=likes+comments+public_content+follower_list+relationships")
let urlRequest: URLRequest = URLRequest.init(url: url!)
wkWebview?.load(urlRequest)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print("\(error.localizedDescription)")
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// This is the URL you need.
let url = webView.url
}
}

Simple Webview: navigationDelegate crashes on start

I have a small problem with my WebView. This is what I do in my app:
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
#IBOutlet var webView: WKWebView! // draged from storyboard
override func viewDidLoad() {
super.viewDidLoad()
var urlToLoad : (String)
urlToLoad = "http://wwww.myapp.com"
webView.sizeToFit()
webView.isUserInteractionEnabled = true
let url = URL(string: urlToLoad)
let request = URLRequest(url:url!)
//webView.navigationDelegate = self
webView.load(request)
}
As you see the row "webView.navigationDelegate = self" is commented. If I uncomment it my app will crash on start and telling me this:
Debugger: libc++abi.dylib: terminating with uncaught exception of type NSException
Any idea of why is this happening and how to solve this? I need this in order to use methods like "didFinish navigation" that I already implemented in the page but they are never called.
Also, by having a look at my code... you see anything I should change regarding the use of my webview?
Thank you for helping me.
You are using UIWebView and trying to call the methods of WKWebView which is leading to crash your app due to unrecognised selector send on UIWebView.
Try to create new project and use below mentioned code.
import "WebKit" framework to your class.
override func viewDidLoad() {
super.viewDidLoad()
let myWebView:WKWebView = WKWebView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
myWebView.navigationDelegate = self;
let url = URL(string: "https://www.Apple.com")!
myWebView.load(URLRequest(url: url))
self.view.addSubview(myWebView)
}
then implement WKNavigationDelegate method
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
let url = webView.url
print(url as Any) // this will print url address as option field
if url?.absoluteString.range(of: ".pdf") != nil {
pdfBackButton.isHidden = false
print("PDF contain")
}
else {
pdfBackButton.isHidden = true
print("No PDF Contain")
}
}
Hope this will help you!
You are binding an UIWebView to a property of type WKWebView. As a result it crashes when trying to call navigationDelegate on the UIWebView, as it does not offer this method.
There is no template version of WKWebView available in Storyboard, so you have to create the WKWebView programatically:
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView(frame: view.frame)
webView.navigationDelegate = self
view.addSubview(webView)
let url = URL(string: "https://www.google.com")!
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
}
You don't initialize the webView. The app crashes because it's nil.
You need to bind it to the storyboard or the xib file (uncomment the #IBOutlet) or initialize it programmatically and then add it to you viewController's view.
I was getting the error Value of type '(WKWebView, WKNavigation?) -> ()' has no member 'navigationDelegate' (which I'm guessing was the same issue as what was causing the crash when adding webView.navigationDelegate = self).
I found that the view controller class needs to implement the WKNavigationDelegate protocol (kinda like inheritance) by adding it to the class definition, which fixed the error for me. Make sure to have that as in the first line of this code:
class ViewController: UIViewController, WKNavigationDelegate {
// ...
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// ...
}
}

Loading webpage inside iOS application

If we load a webpage, we can forward it to safari, but this causes users to leave our app. Is there any way so that a user visits any webpage and then come back to our application.
If you want some browser type functionality for devices earlier then iOS7, you can use this inline browser
iOS 9 Update:
Apple has introduced a visible standard interface for browsing the web i.e. SFSafariViewController for iOS 9+ devices.
Example:
func showTutorial() {
if let url = URL(string: "https://www.example.com") {
let config = SFSafariViewController.Configuration()
config.entersReaderIfAvailable = true
let vc = SFSafariViewController(url: url, configuration: config)
present(vc, animated: true)
}
}
You can use a UIWebView to display the page in your application.
I wanted to add a more detailed answer for others in the future (key coding!) :
In the object library, search for WebKit View and add it to your ViewController
Place "import WebKit" under "import UIKit"
Create an outlet from the WebKit View you placed in your ViewController in your code directly under the opening "{"
Under "superViewDidLoad()", all you need is this:
let url = URL(string: "your_url_here"")
and
webview.load(URLRequest(url:url!))
and dassit!
I'll attach a copy of my code just in case I didn't explain it very well:
import UIKit
import WebKit
class WebsiteViewController: UIViewController {
#IBOutlet weak var webview: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://www.eventbrite.com/e/pretty-in-petals-tea-party-tickets-43361370025")
webview.load(URLRequest(url: url!))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Use a UIWebView Here's how to program one. Let me know if you need more help or examples
#user1706456 UIWebView is deprecated by Apple, You can use WKWebView for it.
Here's code to do that :
step1: Import WebKit
Step2:
//ViewController's LifeCycle.
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
webView.navigationDelegate = self
view = webView
}
Step3 :
In ViewDidLoad:
let myURL = URL(string: "www.google.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
Step 4: WKWebView Delegate Methods to handle navigation and loading etc.
//MARK: - WKNavigationDelegate
extension GPWebViewController : WKNavigationDelegate {
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// Refreshing the content in case of editing...
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
}
}

Resources