How can I get the URL from webView in swift
You are not getting url because webView
has not finished the loading of that requested URL
, you can get that URL
in webViewDidFinishLoad
method of UIWebviewDelegate
. For that you need to set delegate of webView
with your current ViewController
and need to implement UIWebviewDelegate
.
webView.delegate = self
Now you can get current loaded URL
of webView
in webViewDidFinishLoad
method.
func webViewDidFinishLoad(_ webView: UIWebView) {
if let text = webView.request?.url?.absoluteString{
print(text)
}
}
How to get url from webview whenever user move to other pages
you can use:
1. Solution
UIWebViewDelegate
https://developer.apple.com/reference/uikit/uiwebviewdelegate/1617945-webview
optional func webView(_ webView: UIWebView,
shouldStartLoadWith request: URLRequest,
navigationType: UIWebViewNavigationType) -> Bool
UIWebViewNavigationType:
https://developer.apple.com/reference/uikit/uiwebviewnavigationtype
don't forget to return true
case linkClicked
User tapped a link.
case formSubmitted
User submitted a form.
case backForward
User tapped the back or forward button.
case reload
User tapped the reload button.
case formResubmitted
User resubmitted a form.
case other
Some other action occurred.
2. Solution
Inject Javascript JavaScript MessageHandler
(credit to Vasily Bodnarchuk)
Solution is here: https://stackoverflow.com/a/40730365/1930509
Swift 3 example.
Description
The script is inserted into page which will displayed in WKWebView.
This script will return the page URL (but you can write another
JavaScript code). This means that the script event is generated on the
web page, but it will be handled in our function:func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {...}
Full Code example
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView = WKWebView()
let getUrlAtDocumentStartScript = "GetUrlAtDocumentStart"
let getUrlAtDocumentEndScript = "GetUrlAtDocumentEnd"
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
config.addScript(script: WKUserScript.getUrlScript(scriptName: getUrlAtDocumentStartScript),
scriptHandlerName:getUrlAtDocumentStartScript, scriptMessageHandler:
self, injectionTime: .atDocumentStart)
config.addScript(script: WKUserScript.getUrlScript(scriptName: getUrlAtDocumentEndScript),
scriptHandlerName:getUrlAtDocumentEndScript, scriptMessageHandler:
self, injectionTime: .atDocumentEnd)
webView = WKWebView(frame: UIScreen.main.bounds, configuration: config)
webView.navigationDelegate = self
view.addSubview(webView)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
webView.loadUrl(string: "http://apple.com")
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
switch message.name {
case getUrlAtDocumentStartScript:
print("start: \(message.body)")
case getUrlAtDocumentEndScript:
print("end: \(message.body)")
default:
break;
}
}
}
extension WKUserScript {
class func getUrlScript(scriptName: String) -> String {
return "webkit.messageHandlers.\(scriptName).postMessage(document.URL)"
}
}
extension WKWebView {
func loadUrl(string: String) {
if let url = URL(string: string) {
load(URLRequest(url: url))
}
}
}
extension WKWebViewConfiguration {
func addScript(script: String, scriptHandlerName:String, scriptMessageHandler: WKScriptMessageHandler,injectionTime:WKUserScriptInjectionTime) {
let userScript = WKUserScript(source: script, injectionTime: injectionTime, forMainFrameOnly: false)
userContentController.addUserScript(userScript)
userContentController.add(scriptMessageHandler, name: scriptHandlerName)
}
}
Info.plist
add in your Info.plist transport security setting
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Result
Resources ##
Document Object Properties and Methods
iOS Swift : can't Retrieve current url loaded in UIwebView
There are couple of UIWebViewDelegate
such as shouldStartLoadWithRequest
or webViewDidStartLoad
or webViewDidFinishLoad
or didFailLoadWithError
that help you to accomplish your goal. If you want to perform operation after view did finished then implement this delegate method
Swift 3
if let currentURL = webView.request?.url?.absoluteString{
print(currentURL)
}
as it mentioned here.
How to pass different URL to webView from some buttons in swift?
What you need to do is use prepareForSegue:sender:
to set a property in your destination view controller. prepareForSegue:sender:
will be called before your initial view controller segues to any destination view controller. Within this function, we can check which button was pressed and set the appropriate URL in the destination view controller accordingly.
This approach will allow you to use any segue between your buttons and your destination view controller. This means, you simply have to drag the blue line from the buttons to the view controller you want to segue to.
1. Within your storyboard, create a segue between your first view controller and your destination view controller. This is done by holding control, clicking on the first view controller in the interface builder, and dragging over the destination view controller. Then choose a segue type:
Now, select this segue and give it the Identifier
"InitialVCToDestinationVC" in the attributes inspector:
2. Make a property called urlToPass
of type URL
in your initial view controller:
class InitialViewController: UIViewController {
var urlToPass: URL!
@IBAction func googleButtonPressed(_ sender: Any) {
}
@IBAction func facebookButtonPressed(_ sender: Any) {
}
}
3. Make a property called receivedUrl
in the destination view controller:
class DestinationViewController: UIViewController {
var receivedUrl: URL!
@IBOutlet var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: receivedUrl)
webView.load(request)
}
}
4. Set the urlToPass
depending on which button is pressed and use the prepareForSegue:sender:
function to set the destination view controller's url accordingly. Then, make use of performSegue(withIdentifier:sender:)
to perform the segue with identifier InitialVCToDestinationVC
.
class InitialViewController: UIViewController {
var urlToPass: URL!
@IBAction func googleButtonPressed(_ sender: Any) {
urlToPass = URL(string: "www.google.com")
performSegue(withIdentifier: "InitialVCToDestinationVC", sender: nil)
}
@IBAction func facebookButtonPressed(_ sender: Any) {
urlToPass = URL(string: "www.facebook.com")
performSegue(withIdentifier: "InitialVCToDestinationVC", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
guard let destination = segue.destination as? DestinationViewController else { return }
destination.receivedUrl = urlToPass
urlToPass = nil
}
}
5. (optional) Make use of the shouldPerformSegueWithIdentifier:sender:
method within InitialViewController
and check whether or not urlToPass
is valid. If urlToPass
is valid, perform the segue, else present an alert.
class InitialViewController: UIViewController {
...
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if let urlToPass = urlToPass {
// check if your application can open the NSURL instance
if !UIApplication.shared.canOpenURL(urlToPass) {
let alertController = UIAlertController(title: "Cannot open URL.", message: "This is an invalid URL.", preferredStyle: .alert)
let ok = UIAlertAction(title: "Okay", style: .cancel, handler: nil)
alertController.addAction(ok)
present(alertController, animated: true, completion: nil)
}
return UIApplication.shared.canOpenURL(urlToPass)
}
return false
}
}
End result:
Here's a link to the Xcode project I made the above gif from: https://github.com/ChopinDavid/PrepareForSegue
Get current URL of UIWebView
Matt's version is much cleaner. I recommend everyone to use that one instead of this
You could try this:
NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:@"window.location"];
How to load URL on WKWebView?
First of all you need to import
import WebKit
Following code is enough to open URL with WKWebView
let webView = WKWebView(frame: <#AnyRect#>)
let link = URL(string:"https://developer.apple.com/videos/play/wwdc2019/239/")!
let request = URLRequest(url: link)
webView.load(request)
Getting the link URL tapped in WKWebView
Change addObserver
like this
webView.addObserver(self, forKeyPath: "URL", options: [.new, .old], context: nil)
In observeValue
function you able get both value
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let newValue = change?[.newKey] as? Int, let oldValue = change?[.oldKey] as? Int, newValue != oldValue {
//Value Changed
print(change?[.newKey])
}else{
//Value not Changed
print(change?[.oldKey])
}
}
How to load URL in UIWebView in Swift?
loadRequest: is an instance method, not a class method. You should be attempting to call this method with an instance of UIWebview as the receiver, not the class itself.
webviewInstance.loadRequest(NSURLRequest(URL: NSURL(string: "google.ca")!))
However, as @radex correctly points out below, you can also take advantage of currying to call the function like this:
UIWebView.loadRequest(webviewInstance)(NSURLRequest(URL: NSURL(string: "google.ca")!))
Swift 5
webviewInstance.load(NSURLRequest(url: NSURL(string: "google.ca")! as URL) as URLRequest)
How can I open external links in Swift webview?
Try intercepting requests on WKWebView implementing decidePolicyFor navigationAction
:
class ViewController: UIViewController, WKNavigationDelegate {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.uiDelegate = self
webView.navigationDelegate = self
webView.allowsBackForwardNavigationGestures = true
let myURL = URL(string:"https://www.sepettte.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
guard let redirectURL = (navigationAction.request.url) else {
decisionHandler(.cancel)
return
}
if (redirectURL.absoluteString.contains("tel:") ) {
UIApplication.shared.open(redirectURL, options: [:], completionHandler: nil)
}
if (redirectURL.absoluteString.contains("whatsapp") ) {
UIApplication.shared.open(redirectURL, options: [:], completionHandler: nil)
}
decisionHandler(.allow)
}
}
extension ViewController: WKUIDelegate {
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
guard let url = navigationAction.request.url else {
return nil
}
guard let targetFrame = navigationAction.targetFrame, targetFrame.isMainFrame else {
webView.load(URLRequest(url: url))
return nil
}
return nil
}
}
Output:
Related Topics
Insert a Comment Using the Youtube API and Alamofire
Swift Cannot Infer Type from Context
Swiftui: How to Switch to a New Navigation Stack with Navigationviews
Array Extension Called from Other Module
Swift 4.1 Deinitialize and Deallocate(Capacity:) Deprecated
How to Print Escape Sequence Characters in Swift
Checking Conforms Protocol with Associatedtype in Swift
Make a Grid of Buttons of Same Width and Height in Swiftui
Formula to Pick Every Pixel in a Bitmap Without Repeating
How to Get the Url from Webview in Swift
How to Read File Data Applications Document Directory in Swift
How to Customize the Title/Subtitle Font in Callout from Mkannotationview or Just Hide Them
How to Convert an Anykeypath to a Writablekeypath
Why Specializing a Generic Function Explicitly Is Not Allowed
Swift Error with Generic Array
Swift Compilation Time with Nil Coalescing Operator
Mandatory Init Override in Swift Uinavigationcontroller Subclass