I'm trying to open external links from my app but it won't open - swift

I have a wkwebview app, I need help with my code, I can't seems to open external links from my website inside my app.
import UIKit
import WebKit
import UserNotifications
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
var webView: WKWebView!
var activityIndicator: UIActivityIndicatorView!
var bgImage: UIImageView!
var urlString = ""
override func loadView() {
super.loadView()
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
webView.navigationDelegate = self
view = webView
}
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
let vc = ViewController()
vc.urlString = navigationAction.request.url?.absoluteString ?? "https://mywebsite"
vc.view.frame = UIScreen.main.bounds
vc.webView = WKWebView(frame: UIScreen.main.bounds, configuration: configuration)
navigationController?.pushViewController(vc, animated: false)
return vc.webView
}
return nil
}
override var prefersStatusBarHidden: Bool{
return true
}
override func viewDidLoad() {
super.viewDidLoad()
let image : UIImage = UIImage(named:"bgx1")!
bgImage = UIImageView(image: image)
bgImage.frame = CGRect(x: 0, y: 0, width: 1000, height: 2000)
view.addSubview(bgImage)
let myURL = URL(string: "https://mywebsite/")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
webView.allowsBackForwardNavigationGestures = true
activityIndicator = UIActivityIndicatorView()
activityIndicator.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
self.activityIndicator.center = CGPoint(x:self.view.bounds.size.width/2.0,y: self.view.bounds.size.height/2.0);
activityIndicator.autoresizingMask = (UIView.AutoresizingMask(rawValue: UIView.AutoresizingMask.RawValue(UInt8(UIView.AutoresizingMask.flexibleRightMargin.rawValue) | UInt8(UIView.AutoresizingMask.flexibleLeftMargin.rawValue) | UInt8(UIView.AutoresizingMask.flexibleBottomMargin.rawValue) | UInt8(UIView.AutoresizingMask.flexibleTopMargin.rawValue))))
activityIndicator.hidesWhenStopped = true
activityIndicator.style = UIActivityIndicatorView.Style.whiteLarge
activityIndicator.color = UIColor.darkGray
self.view.addSubview(activityIndicator)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
activityIndicator.startAnimating()
bgImage.startAnimating()
}
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
print("It is an error")
activityIndicator.stopAnimating()
bgImage.stopAnimating()
let alert = UIAlertController(title: "Network Error", message: "You have no internet connection", preferredStyle: .alert)
let restartAction = UIAlertAction(title: "Reload page", style: .default, handler: { (UIAlertAction) in
self.viewDidLoad()
})
alert.addAction(restartAction)
present(alert, animated: true, completion: nil)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
activityIndicator.stopAnimating()
bgImage.stopAnimating()
bgImage.isHidden = true
}
}
What am I doing wrong? Please help.

You have to implement the webView(_:decidePolicyFor:decisionHandler:) function of WKNavigationDelegate protocol in order to allow following the links in your web view.
Here is the documentation

please use this webview as I shown in image
code:-
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self;
webView.loadRequest(URLRequest.init(url: URL(string: "https://mywebsite")!));
}
func webViewDidStartLoad(_ webView: UIWebView) {
SVProgressHUD.setDefaultMaskType(SVProgressHUDMaskType.custom)
SVProgressHUD.show();
}
func webViewDidFinishLoad(_ webView: UIWebView) {
SVProgressHUD.dismiss();
}

Related

ios: How to reload webview from a Coordinator class SwiftUi

I am making an app that contains multiple web-view's. I am wanting to reload my web-view from the coordinator class after a JS command is sent from the webpage and inside the "func processReturnedJS(body: String)" shown below. I am wondering how I can achieve this in a simple way?
Thanks
SubscriptionViewController:
import SwiftUI
import WebKit
struct SubscriptionViewController: UIViewRepresentable {
#StateObject var storeManager: StoreManager
let frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
let config = WKWebViewConfiguration()
let cookies = HTTPCookieStorage.shared.cookies ?? []
func makeUIView(context: UIViewRepresentableContext<SubscriptionViewController>) -> WKWebView {
for cookie in cookies {
config.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
}
let preferences = WKPreferences()
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
let userContentController = WKUserContentController()
userContentController.add(context.coordinator, name:"observer")
configuration.userContentController = userContentController
let view = WKWebView(frame: frame, configuration: configuration)
view.navigationDelegate = context.coordinator
DispatchQueue.main.async {
let url = URL(string:"theurl")!
let request = URLRequest(url: url)
for cookie in cookies {
config.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
view.configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
}
view.load(request)
}
return view
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<SubscriptionViewController>) {
}
func makeCoordinator() -> CoordinatorSubscription {
CoordinatorSubscription(self, storeManage: self.storeManager)
}
typealias UIViewType = WKWebView
}
class CoordinatorSubscription: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var control: SubscriptionViewController
var storeManage: StoreManager
init(_ control: SubscriptionViewController, storeManage: StoreManager) {
self.control = control
self.storeManage = storeManage
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
processReturnedJS(body: message.body as! String)
}
func sendjs(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func processReturnedJS(body: String) {
print("kkkk")
//want to reload webview from here
}
}
You can store a reference to the WKWebView in your coordinator:
class CoordinatorSubscription: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var control: SubscriptionViewController
var storeManage: StoreManager
var webView : WKWebView? //<-- Here
init(_ control: SubscriptionViewController, storeManage: StoreManager) {
self.control = control
self.storeManage = storeManage
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
processReturnedJS(body: message.body as! String)
}
func sendjs(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func processReturnedJS(body: String) {
self.webView?.reload() //here
}
}
Then, make sure to set that property in makeUIView:
func makeUIView(context: UIViewRepresentableContext<SubscriptionViewController>) -> WKWebView {
for cookie in cookies {
config.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
}
let preferences = WKPreferences()
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
let userContentController = WKUserContentController()
userContentController.add(context.coordinator, name:"observer")
configuration.userContentController = userContentController
let view = WKWebView(frame: frame, configuration: configuration)
view.navigationDelegate = context.coordinator
DispatchQueue.main.async {
let url = URL(string:"theurl")!
let request = URLRequest(url: url)
for cookie in cookies {
config.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
view.configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
}
view.load(request)
}
context.coordinator.webView = view //<-- Here
return view
}

How to add back button History in Xcode using swift language

First of all I'm new in swift. I have a WebView app for iOS device using swift language , can add button back to previous page ?
import WebKit
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://google.com/")!
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
let statusBarFrame = UIApplication.shared.statusBarFrame
let statusBarView = UIView(frame: statusBarFrame)
self.view.addSubview(statusBarView)
statusBarView.backgroundColor = .systemBackground
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
title = webView.title
}
}

Loader image before webView finish loading Swift 5

I have simple webview.
All I need is the image to disappear after webView finish loading.
This function work, but I get error on line "imageView.isHidden = false"
error is : " Use of unresolved identifier 'imageView' "
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
imageView.isHidden = false
}
Full code:
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
var webView: WKWebView!
public var screenWidth: CGFloat {
return UIScreen.main.bounds.width
}
public var screenHeight: CGFloat {
return UIScreen.main.bounds.height
}
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()
let imageName = "icon.png"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: 0, y: 0, width: screenWidth, height:screenHeight)
view.addSubview(imageView)
let myURL = URL(string:"https://google.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
imageView.isHidden = false
}
}
You need to assign it to an instance property (like you already did for var webView: WKWebView!) and assign it - then you have access to it at a later point in time.
self.imageView = UIImageView(image: image!)
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
var webView: WKWebView!
var imageView: UIImageView!
public var screenWidth: CGFloat {
return UIScreen.main.bounds.width
}
public var screenHeight: CGFloat {
return UIScreen.main.bounds.height
}
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()
let imageName = "icon.png"
let image = UIImage(named: imageName)
imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: 0, y: 0, width: screenWidth, height:screenHeight)
view.addSubview(imageView)
let myURL = URL(string:"https://google.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
imageView.isHidden = false
}
}
try this

Xcode Webview items not loading

I have a Xcode Project with a Webview and a TabBar and with the TabBar I can switch between WebViews. My Problem is that when I put something in my ShoppingCard under Lieferworld.de and switch with the TabBar to my Shopping Card url the Items in there are not Visible. How can I solve this? the ShoppingCard URL ends with .php. Below is the code which is implemented
I also uploaded a video on YouTube were I you can see the error
https://youtu.be/qU3Mu1G7MY0
Viewhome:
import UIKit
import WebKit
class viewHome: UIViewController, WKUIDelegate {
#IBOutlet var webViewHome: WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webViewHome = WKWebView(frame: .zero, configuration: webConfiguration)
webViewHome.uiDelegate = self
webViewHome.configuration.preferences.javaScriptEnabled = true
//webViewHome.configuration.preferences.javaEnabled = true
view = webViewHome
}
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://lieferworld.de")
let request = URLRequest(url: url!)
webViewHome.configuration.preferences.javaScriptEnabled = true
//webViewHome.configuration.preferences.javaEnabled = true
webViewHome.load(request)
}
#IBAction func GoBackHome(_ sender: Any) {
if webViewHome.canGoBack {
webViewHome.goBack()
}
}
#IBAction func GoForwardHome(_ sender: Any) {
if webViewHome.canGoForward {
webViewHome.goForward()
}
}
}
ViewShopping | Shopping Cart Class:
import UIKit
import WebKit
class viewShopping: UIViewController, WKUIDelegate {
#IBOutlet var webViewShopping: WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webViewShopping = WKWebView(frame: .zero, configuration: webConfiguration)
webViewShopping.uiDelegate = self
//webViewShopping.configuration.preferences.javaEnabled = true
webViewShopping.configuration.preferences.javaScriptEnabled = true
view = webViewShopping
}
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://lieferworld.de/warenkorb.php")
let request = URLRequest(url: url!)
webViewShopping.configuration.preferences.javaScriptEnabled = true
//webViewShopping.configuration.preferences.javaEnabled = true
webViewShopping.load(request)
}
#IBAction func goBackShoppingCart(_ sender: Any) {
if webViewShopping.canGoBack {
webViewShopping.goBack()
}
}
#IBAction func goForwardShoppingCart(_ sender: Any) {
if webViewShopping.canGoForward {
webViewShopping.goForward()
}
}
#IBAction func webViewRefresh(_ sender: Any) {
webViewShopping.reload()
}
}
WKNavigationDelegate has three delegates.
Here's an example;
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
print(error.localizedDescription)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("Start page load")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
{
let title = webView.title
print("finish load. \(title).")
// you can do processing on the results here or trigger processing elsewhere
webView.evaluateJavaScript("document.documentElement.outerHTML.toString()",completionHandler:
{ (html: Any?, error: Error?) in
print(html as Any)
self.htmlSource = html as! String
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "pageLoaded"), object: nil)
})
}

How can i use open in new tab in swift ?(WEBKIT)

How can i use safari-open in new tab in my webkit app
I am creating a internet browser and i need that
Just like the photo
For example, I want to show the open in new tab option when I hold my finger on a link in Google
enter image description here
class ViewController: UIViewController, UITextFieldDelegate, WKNavigationDelegate {
#IBOutlet weak var backButton: UIButton!
#IBOutlet weak var forwardButton: UIButton!
#IBOutlet weak var webView: WKWebView!
#IBOutlet weak var urlTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
urlTextField.delegate = self
webView.navigationDelegate = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear( animated )
let urlString:String = "https://www.google.com"
let url:URL = URL(string: urlString)!
let urlRequest:URLRequest = URLRequest(url: url)
webView.load(urlRequest)
urlTextField.text = urlString
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let urlString:String = urlTextField.text!
let url:URL = URL(string: urlString)!
let urlRequest:URLRequest = URLRequest(url: url)
webView.load(urlRequest)
textField.resignFirstResponder()
return true
}
#IBAction func backButtonTapped(_ sender: Any) {
if webView.canGoBack {
webView.goBack()
}
}
#IBAction func forwardButtonTapped(_ sender: Any) {
if webView.canGoForward {
webView.goForward()
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
backButton.isEnabled = webView.canGoBack
forwardButton.isEnabled = webView.canGoForward
urlTextField.text = webView.url?.absoluteString
}
}
Use this delegate method in bellow you last medhod :
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.targetFrame == nil {
if let url = navigationAction.request.url {
let app = UIApplication.shared
if app.canOpenURL(url) {
app.open(url, options: [:], completionHandler: nil)
}
}
}
decisionHandler(.allow)
}
is It oky ?