Creating webViews programmatically in Swift - ios

I want to create something like an image gallery in my ViewController. For this, I'd need multiple webViews, depending on the number of images that I get from a JSON request. How can I insert new webViews if I need to?
As you can see in the above image, I have a scrollView and one UIWebView inside of the ViewController. How would I create a new webView inside of the first(second, third, etc.) if necessary? Is it possible?

you can create the web view programatically as simple as possible use this piece of code
override func viewDidLoad() {
super.viewDidLoad()
let webV:UIWebView = UIWebView(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height))
webV.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.google.co.in")))
webV.delegate = self;
self.view.addSubview(webV)
}
and if you want use this delegate function
func webView(webView: UIWebView!, didFailLoadWithError error: NSError!) {
    print("Webview fail with error \(error)");
}
func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {
    return true;
}
func webViewDidStartLoad(webView: UIWebView!) {
    print("Webview started Loading")
}
func webViewDidFinishLoad(webView: UIWebView!) {
    print("Webview did finish load")
}

For Swift 3:
override func viewDidLoad() {
super.viewDidLoad()
let webV = UIWebView()
webV.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
webV.loadRequest(NSURLRequest(url: NSURL(string: "https://www.apple.com")! as URL) as URLRequest)
webV.delegate = self
self.view.addSubview(webV)
}
Reference: Based on the answer provided by #Deepakraj Murugesan

Although UIWebView is probably not the thing you should use for displaying images, you can create one with just a few lines of code:
let webView = UIWebView(frame: someFrame)
webView.loadRequest(NSURLRequest(URL: someURL!))
view.addSubview(webView)

you can't do that, Originally,webview will take up a lot of memory, if you use some quantity of it, can lead to a bad experience, why do not use ImageView?

For Swift 4:
webView = WKWebView()
webView.navigationDelegate = self
view = webView
let url = URL(string: "https://www.earthhero.org")!
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
Plus you need to import WebKit and add WKNavigationDelegate to the Class.

Related

Making certain links in WKWebView open in Safari, not the Webview

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

WebView does not load

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:

WebView is not loading for specific URL in Xcode 9 simulator

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))
}
}
}

Add A Callback To A Prebuilt Asynchronous Function Swift iOS

I'm messing around with pdfs at the moment. I'm attempting to load a PDF into the system and write out the same PDF to gain an understandings of the the whole procedure.
The problem I've got it is that I'm having to load the pdf from the web and because the WebViewUI.loadRequest is asynchronous, it isn't completed in time.
override func viewDidLoad() {
super.viewDidLoad()
let filePath = getDocumentsDirectory().stringByAppendingPathComponent("output.pdf")
let url : NSURL! = NSURL(string: "http://www.nhs.uk/NHSEngland/Healthcosts/Documents/2014/HC5(T)%20June%202014.pdf")
loadTemplate(url, completion: {(webView: UIWebView) -> Void in
print("callback started")
let pdf = self.toPDF(webView)
do {
pdf!.writeToFile(filePath, atomically: true)
} catch {
// failed to write file – bad permissions, bad filename, missing permissions, or more likely it can't be converted to the encoding
}
print("callback started")
})
print("Finished viewDidLoad")
}
func loadTemplate(url: NSURL, completion: (webView: UIWebView) -> Void) {
print("Start loadTemplate")
// do some crunching to create the SketchAnimation instance...
let webView = UIWebView(frame: CGRectMake(20, 100, 300, 40))
webView.loadRequest(NSURLRequest(URL: url))
self.view.addSubview(webView)
// invoke the completion callback
completion(webView: webView)
print("finished loadTemplate")
}
How do I add a callback to the loadRequest instead of loadTemplate?
You don't, exactly. You'd set up your view controller to be the web view's delegate and implement the webViewDidFinishLoad method. In that method you'd check to make sure the load that finished is the one you were after, and if so, then you'd invoked the code you want to run when the load is complete.
Here is a basic example of how to set that up:
//
// ViewController.swift
//
import UIKit
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var webView: UIWebView!
var url = NSURL(string: "http://google.com")
override func viewDidLoad() {
super.viewDidLoad()
//load initial URL
let req = NSURLRequest(URL : url!)
webView.delegate = self
webView.loadRequest(req)
}
func webViewDidStartLoad(webView : UIWebView) {
print("AA")
}
func webViewDidFinishLoad(webView : UIWebView) {
print("BB")
}
}

How to load a webview in a SWIFT based ios App

I am relatively very new to swift. Could you please help me how to load a webview in an ios app based on swift. Basically I want to load the contents of an external URL in an ios app.
Can anyone please help?
override func viewDidLoad() {
super.viewDidLoad()
let webV:UIWebView = UIWebView(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height))
webV.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.google.com")))
webV.delegate = self;
self.view.addSubview(webV)}
and if you want use delegate function
func webView(webView: UIWebView!, didFailLoadWithError error: NSError!) {
print("Webview fail with error \(error)");
}
func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {
return true;
}
func webViewDidStartLoad(webView: UIWebView!) {
print("Webview started Loading")
}
func webViewDidFinishLoad(webView: UIWebView!) {
print("Webview did finish load")
Before asking your questions research what you're looking, because this question has been answered on many forums.
In the viewDidLoad() add the following code. Make sure to connect the WebView to the View and to connect the outlet.
let url = NSURL (string: "https://www.google.com");
let requestObj = NSURLRequest(URL: url!);
myWebView.loadRequest(requestObj);
}

Resources