I just started developing with swift, so I am sorry if the question is basic/stupid.
I have the following setup, just a test
import WebKit
import UIKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://hackingswift.com")!
webView.load(URLRequest(url:url))
webView.allowsBackForwardNavigationGestures = true
}
}
Unfortunately the browser doesn't load. The simulator only shows an empty navigation bar.
Suggestions? I am following a tutorial on hackingswift, so it's supposed to work.
You have to add webView as a subview or make an IBOutlet using Interface builder.
Try this:
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView?
func loadView() {
webView = WKWebView()
webView?.navigationDelegate = self
self.view.addSubview(webView!)
}
override func viewDidLoad() {
super.viewDidLoad()
self.loadView()
let url = URL(string: "https://hackingswift.com")!
webView?.load(URLRequest(url:url))
webView?.allowsBackForwardNavigationGestures = true
}
}
If you want it a bit more simple (without nullable variable), for example:
class ViewController: UIViewController, WKNavigationDelegate {
var webView = WKWebView()
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
self.view.addSubview(webView)
webView?.allowsBackForwardNavigationGestures = true
self.loadUrl("https://hackingswift.com")
}
func loadUrl(_ url: String) {
if let url = URL(string: url) {
webView.load(URLRequest(url:url))
}
}
}
EDIT: it looks like some websites to load, while others do not, even if they are secure. If I put apple.com in the example, it loads, but a few others do not
Your url should be started with http or https for the webView to load.
Another possible reason is that your url containing an invalid certificate. Add the delegate function below into your code. You have to let WKWebView to bypass the certificate checking. However, this code is never recommended to go into production. You should be careful about what website your webView should and will load.
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: #escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!)
completionHandler(.useCredential, cred)
}
The problem is this line:
let url = URL(string: "https://hackingswift.com")!
There is no such URL on the Internet, so you're not actually going to see anything. (You won't see anything if you paste that URL into any browser.)
So change that line to this:
let url = URL(string: "https://www.hackingwithswift.com")!
Now run the app, and presto, you'll see the web site:
Related
I have a WebView app which contains external links that I wish to have users open within Safari as opposed to the webview itself, on tap. I believe it has something to do with a Navigation Delegate but I am new to iOS Dev and have no idea where to start! Below is my code as it is today. If you can tell me specifically what changes to make and where to put in any code, that would make my life so much easier. Thanks everyone in advance for any help! I think there's a way along the lines of setting a Navigation delegate such that all URL's that start with https://example-root.com/ open normal, in the webview since they are native nav buttons but all other URL's I want to open in safari on tap.
import UIKit
import WebKit
class ViewController: UIViewController {
let webView: WKWebView = {
let prefs = WKWebpagePreferences()
prefs.allowsContentJavaScript = true
let configuration = WKWebViewConfiguration()
configuration.defaultWebpagePreferences = prefs
let webView = WKWebView(frame: .zero, configuration: configuration)
return webView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(webView)
// Do any additional setup after loading the view.
guard let url = URL(string: "https://example-root.com/") else {
return
}
webView.load(URLRequest(url: url))
DispatchQueue.main.asyncAfter(deadline: .now()+5) {
self.webView.evaluateJavaScript("document.body.innerHTML") { result, error in guard lethtml = result as? String, error == nil else {
return
}
}
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
webView.frame = view.bounds
}
}
You're right that you'll need to use the NavigationDelegate to intercept the navigation action. Make your ViewController conform to WKNavigationDelegate and implement the webView(_:decidePolicyFor:decisionHandler:) method:
extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url, !url.host.contains("example-root.com") {
UIApplication.shared.open(url)
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
}
Don't forget to set the navigationDelegate property of your WKWebView, you can do this in viewDidLoad with the following:
webView.navigationDelegate = self
I'm a beginner in programming and am trying to make a simple app for displaying a webpage after choosing from menu options. However, I'm having trouble linking the code window to the storyboard, especially for linking a new page for the app to a new class. I think it's partly b/c I can't view the code and storyboard side by side.
I've also written code for displaying the website in on an app page, but I'm getting an error message saying "Argument passed to call that takes no arguments" (code below). Any tips on how I can address these?
import WebKit
import UIKit
//class ViewController: UIViewController {
class WebViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad() {
let url = URL(string: "https://google.com")!
webView.load(URLRequest(url: url))
}
}
override func viewDidLoad() {
super.viewDidLoad() {
let url = URL(string: "https://google.com")!
webView.load(URLRequest(url: url))
}
}
Above should be:
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://google.com")!
webView.load(URLRequest(url: url))
}
without the inner brackets.
I am trying to load a URL using webView in swift 4. I tried https://www.google.co.in and it works fine. and the mobile site for the specific URL works fine with android.
But when I tried this in the simulator, it is loading forever.
my code is below:
import UIKit
class WebViewController: UIViewController, UIWebViewDelegate {
#IBOutlet weak var webView: UIWebView!
let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.whiteLarge)
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
if let url = URL(string: "https://www.myurl.com") {
let request = URLRequest(url: url)
webView.loadRequest(request)
}
}
public func webViewDidStartLoad(_ webView: UIWebView)
{
activityIndicator.center = CGPoint(x: self.view.bounds.size.width/2, y: self.view.bounds.size.height/2)
self.view.addSubview(activityIndicator)
activityIndicator.color = UIColor.red
self.activityIndicator.startAnimating()
}
public func webViewDidFinishLoad(_ webView: UIWebView)
{
self.activityIndicator.stopAnimating()
}
}
I don't think that my code is wrong. but I was wondering if I can do anything to make it work on simulator.
Thanks
I just made a small project with your code and no problem in the simulator, https://www.google.co.in loaded just fine.
I noticed you mention you are using Swift 4, I think you should consider using WebKit View (WKWebView) since UIWebView is deprecated. In Apple's documentation you can see how to implement it, it's pretty straight forward.
If your certificate is not trusted you must add to Info.plist App Transport Security Settings, Allow Arbitrary Loads to YES. (This is not recommended).
The code is really simple, give it a try:
import UIKit
import WebKit
class WebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
#IBOutlet weak var webView: WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let myURL = URL(string: "https://www.myurl.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: #escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
if let serverTrust = challenge.protectionSpace.serverTrust {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
}
}
}
I am would like open a website, using a password/username (basic)Authorization in a WKWebView.
To do that I use the method didReceiveAuthenticationChallenge.
import UIKit
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var container: UIView!
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView()
container.addSubview(webView)
let urlStr = "https://vplan.bielefeld-marienschule.logoip.de/subst_002.htm"
let url = NSURL(string: urlStr)!
let request = NSURLRequest(url: url as URL)
webView.load(request as URLRequest)
}
func webView(webView: WKWebView, didReceiveAuthenticationChallenge challenge: URLAuthenticationChallenge, completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void){
if challenge.protectionSpace.host == "https://vplan.bielefeld-marienschule.logoip.de/subst_002.htm" {
let userStr = "********"
let passwordStr = "********"
let credential = URLCredential(user: userStr, password: passwordStr, persistence: URLCredential.Persistence.forSession)
challenge.sender?.use(credential, for: challenge)
completionHandler(.useCredential, credential)
}
}
override func viewDidAppear(_ animated: Bool) {
let frame = CGRect(x: 0, y: 0, width: container.bounds.width, height: container.bounds.height)
webView.frame = frame
But for some reason, it does not work.
Adding the code line
completionHandler(URLSession.AuthChallengeDisposition.UseCredential, credential)
like in the description here: Authentication with WKWebView in Swift produced an error.
I have also tried to change the challenge.protectionSpace.host into vplan.bielefeld-marienschule.logoip.de:443 which is shown as the login adress in the Safari pop-up and into the IP-Adress of the server (93.206.31.253).
Hope you can help me.
Thank You!
In your code, you have not set the navigation delegate of the web view to your controller.
Change the definition of your controller to:
class ViewController: UIViewController, WKNavigationDelegate
And after creating your web view, set the navigation delegate to your controller:
webView.navigationDelegate = self
Depending on if you are using Swift 3, you may need to change the signature of the method to webView(_:didReceive:completionHandler:).
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) {
}
}