Loader image before webView finish loading Swift 5 - swift

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

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
}

WKWebView won't display the webpage I need it to

Given the code below. I can't get the web page "https://baycare.clearstep.health/covid19" to show up. It shows up okay in Safari and I can get other pages to show up in the WKWebView. I have tried implementing all of the navigation and ui delegate methods to try and track down the problem but have failed to find anything.
The URL used to work, but the company has changed something and now it doesn't. Any help is appreciated.
The below is a complete program:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let controller = UIViewController()
.setup { viewController in
WKWebView(frame: viewController.view.bounds)
.setup {
viewController.view.addSubview($0)
$0.uiDelegate = WebViewUIDelegate.instance
$0.navigationDelegate = WebViewDelegate.instance
$0.autoresizingMask = [.flexibleWidth, .flexibleHeight]
$0.load(URLRequest(url: URL(string: "https://baycare.clearstep.health/covid19")!))
}
}
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = controller
window?.makeKeyAndVisible()
return true
}
}
extension NSObjectProtocol {
#discardableResult
func setup(_ fn: (Self) -> Void) -> Self {
fn(self)
return self
}
}
final class WebViewUIDelegate: NSObject, WKUIDelegate {
static let instance = WebViewUIDelegate()
}
final class WebViewDelegate: NSObject, WKNavigationDelegate {
static let instance = WebViewDelegate()
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print("This doesn't fire so no error?", error)
}
}
WKWebView is depricated version but still webview will works fine, I had same issue and I was doing same but then instead of WKWenView I used web view
import UIKit
import WebKit
class PolicyVC: UIViewController {
#IBOutlet weak var webView: UIWebView!
var isPolicyView = false
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: UIButton.ButtonType.custom)
button.setImage(UIImage(named: "ic_arrow_left"), for: .normal)
button.addTarget(self, action:#selector(popView), for: .touchUpInside)
button.frame=CGRect(x: 0, y: 0, width: 20, height: 20)
let barButton = UIBarButtonItem(customView: button)
self.navigationItem.leftBarButtonItems = [barButton]
setUpUI()
}
#objc func popView(){
self.navigationController?.popViewController(animated: true)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.isHidden = false
self.navigationController?.navigationBar.backgroundColor = .black
}
func setUpUI(){
if isPolicyView{
let url = URL(string: "https://www.termsfeed.com/privacy-policy/68c4cdaeba7e146a7d72bf57654520e7")
let urlRequest = URLRequest(url: url!)
webView.loadRequest(urlRequest)
}else{
let url = URL(string: "https://www.termsfeed.com/terms-conditions/0001db2c7a1061a55e2f933bb94102de")
let urlRequest = URLRequest(url: url!)
webView.loadRequest(urlRequest)
}
}
}

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

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

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

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