Loading webpage inside iOS application - ios

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

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

WK WebView calling completion handler but now showing anything

I want to load privacy policy (simple string) from server say, https://*****.com/privacy-policy.html to my app.
What I have tried till now is given below:
class TermsAndConditionsDetailViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var contentView: UIView!
var webView: WKWebView!
func webView(_ webView: WKWebView,
didFinish navigation: WKNavigation!) {
print("loaded")
}
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView()
contentView.addSubview(webView)
let myURL = URL(string: "https://***.com/privacy-policy.html")
let myRequest = URLRequest(url: myURL!)
webView.navigationDelegate = self
//I have tried these both one by one
webView.loadHTMLString("", baseURL: myURL)
webView.load(myRequest)
}
}
When i run this code "loaded" gets printed after 2 - 3 seconds but it doesn't show anything on the screen. I have been searching this issue for some time now and have tried to play around with the code. I have cross checked the constraints of all view specially contentView, but no luck.
You forget to add frame for your WKWebView
just add
webView = WKWebView(frame: self.contentView.frame)
after
webView = WKWebView()
and it will work fine.

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!) {
// ...
}
}

wkwebview won't display a youtube video in an iframe

I am trying to use a WKWebView under iOS 9 and one of the pages happens to have a youtube video in an iframe. The video does not display. The same video works in Safari so doesn't seem to be an iOS issue, I assume I am missing a configuration option in the view. A sample URL is http://www.w3schools.com/html/tryit.asp?filename=tryhtml_youtubeiframe.
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate
{
var webView : WKWebView!
override func viewDidLoad()
{
super.viewDidLoad()
let webviewConfiguration = WKWebViewConfiguration()
webviewConfiguration.allowsInlineMediaPlayback = true
webviewConfiguration.preferences.javaScriptCanOpenWindowsAutomatically = true
webviewConfiguration.allowsAirPlayForMediaPlayback = true
webviewConfiguration.allowsPictureInPictureMediaPlayback = true
webviewConfiguration.requiresUserActionForMediaPlayback = false
webView = WKWebView(frame: self.view.bounds,
configuration: webviewConfiguration)
webView.navigationDelegate = self
self.view = webView
let url = NSURL(string: "http://www.w3schools.com/html/tryit.asp?filename=tryhtml_youtubeiframe")
let req = NSURLRequest(URL: url!)
self.webView!.loadRequest(req)
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
func webView(webView: WKWebView,
didFailNavigation navigation: WKNavigation!,
withError error: NSError)
{
print("didFailNavigation \(error)")
}
func webView(webView: WKWebView,
didFailProvisionalNavigation navigation: WKNavigation!,
withError error: NSError)
{
print("didFailProvisionalNavigation \(error)")
}
}
Go to Projects info.plist file
Added a Key called NSAppTransportSecurity as a Dictionary.
Added a Subkey called NSAllowsArbitraryLoads as Boolean and set its value to YES. It works.

Resources