Xcode Wkwebview not Loading - swift

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
Here is also a Video were 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()
}
}

Your data is not being shared between the two UIViewControllers because your WKWebViews are different instances of each other and don't share the same data. It's as if you opened two different tabs in your web browser. If you're logged in, and the cart data is stored on the server, it should work, if you refresh the cart's page. If it's cookie based, you'll need to ensure those cookies are common among the two web views. Instead, use the tab to redirect to the cart's page instead of creating a new View Controller instance, or put the instance of the WKWebView into a static variable that can be shared between the two tabs. You'll have to do a bit of hiding/showing of that view so that you don't see it loading, but that can be handled via the delegate.
If the data is stored on the server, you can simple just reload the webpage within the viewDidAppear() overridden function in your VC. It really depends on what you're going for, but those are a few suggestions that'll work.

Related

WKWebView SWIFT: not show messages in instagram

I'm a new in Swift/iOS developing. I try to create a simple browser:
import UIKit
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://www.instagram.com")!
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
}
}
When I go to https://www.instagram.com, I can't see my messages.
I got this (top header isn't shown):
But I expect this (top header is shown):
Why I can't see the top header through my browser?
I'm able to see the header at my end. The only difference is that I've added WKWebView in XIB and you are loading on view from the code.
Reason can be the frame & constraints of the page. Try setting frame & constraints -
webView = WKWebView(frame: self.view.frame)
webView.translatesAutoresizingMaskIntoConstraints = true
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

How to reference a URL object inside a function from ViewController.swift?

I am trying to pass a web page to another WebView from ViewController.swift. The URL is initiated by another class.
So far I was able to create the webView, create the segue, and load a dummy web page inside that controller upon tapping on the button from ViewController.swift. When I tap the button, the correct web address gets printed on the console with print(wikiURL) call.
I tried to call the variable by first declaring a global variable inside ViewController, then modifying it inside the function, then trying to reach from the webView controller, by setting up variables.
This is the function I am calling the segue from:
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "WikiViewController") as? WikiViewController {
guard let capital = view.annotation as? Capital else { return }
let wikiURL = capital.url
print(wikiURL)
navigationController?.pushViewController(vc, animated: true)
}
And this is my webView controller:
class WikiViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
title = webView.title
let request = URLRequest(url: URL(string: "")!)
webView.load(request)
}
}
I should be able to replace URL(string: "")!) with wikiURL, then load it inside the webView.
Thank you for any assistance.
In WikiViewController, instead of creating url of type Capital?, it must be of type URL?, i.e.
var url: URL?
Use this url to create the URLRequest for WKWebView.
class WikiViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
var url: URL?
override func loadView() {
webView = WKWebView()
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
title = webView.title
if let url = self.url {
let request = URLRequest(url: url)
webView.load(request)
}
}
}
Usage:
When creating instance of WikiViewController in mapView(_:,annotationView:, calloutAccessoryControlTapped:) method, set the property vc.url as wikiURL.
if let vc = storyboard?.instantiateViewController(withIdentifier: "WikiViewController") as? WikiViewController {
guard let capital = view.annotation as? Capital else { return }
let wikiURL = capital.url
print(wikiURL)
vc.url = wikiURL //here......
navigationController?.pushViewController(vc, animated: true)
}
Note: I've assumed that wikiURL is of type URL?. In case it is String, create a URL instance using that String and then set it as vc.url.

Swift view appears to delay being loaded into window hierarchy

A very strange thing is happening, it appears my initial view controller loads up, performs its logic and all but the actual view itself isn't added to the hierarchy until everything else happens.
protocol OnboardDisplayLogic: class
{
func handleUserConfirmation(viewModel: OnboardModels.CheckForUser.ViewModel)
}
class OnboardViewController: UIViewController, OnboardDisplayLogic {
var interactor: OnboardInteractor?
var router: (NSObjectProtocol & OnboardRoutingLogic & OnboardDataPassing)?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
//MARK: Setup
private func setup() {
let viewController = self
let interactor = OnboardInteractor()
let presenter = OnboardPresenter()
let router = OnboardRouter()
viewController.interactor = interactor
viewController.router = router
interactor.presenter = presenter
presenter.viewController = viewController
router.viewController = viewController
router.dataStore = interactor
}
private func setupView() {
view.backgroundColor = UIColor.brown
}
//MARK: Routing
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let scene = segue.identifier {
let selector = NSSelectorFromString("routeTo\(scene)WithSegue:")
if let router = router, router.responds(to: selector) {
router.perform(selector, with: segue)
}
}
}
//MARK: View lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupView()
interactor?.checkForUser()
}
func handleUserConfirmation(viewModel: OnboardModels.CheckForUser.ViewModel) {
if let username = viewModel.username {
print("Logged in user: \(username)")
router?.routeToUserFeed(segue: nil)
} else {
print("No user logged in")
router?.routeToLoginRegister(segue: nil)
}
}
The reason I think it's delayed is that although I've set the view background colour to brown, using breakpoints at the print("user not logged in") code I get that printed to console, because there is no user logged in as determined the Interactor, but view remains white. It's not until I step over and complete running all the code does the screen then become brown.
Therefore I'm getting the error
Warning: Attempt to present ... whose view is not in the window
hierarchy!
as something is preventing the view from being added until the very end.
Actual views aren't loaded until they enter the view controller lifecycle.
If you need to load the view to setup before it's added to a superview's hierarchy, just use the getter of the view (let _ = viewController.view).
UIViewControllers also have the loadView() method, check it out: Apple documentation.
We've also had these kind of problems with Clean Swift. The correct way of working would be to instantiate from the storyboard and just use normal segues/lifecycle, just as MVC does for Apple examples.
Instead of doing let viewControllerToPush = MyVCSublass(...), you should instantiate from storyboard let viewControllerToPush = storyboard?.instantiate... and use that view controller.

MacOS issue with loading url in web-view

I have done with codes below but I'm having problem loading the webview with an url which show an error with on runtime
Thread 1:signal SIGABRT
so please help me with, i have just started with macOS application development,
Thanks,
import Cocoa
import WebKit
class ViewController: NSViewController, WebFrameLoadDelegate {
#IBOutlet weak var webView: WebView!
let urlpath = NSURL(string: "http://www.google.com/")!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//let url = "https:www.apple.com"
//self.webView.mainFrame.load(NSURLRequest(URL: NSURL(string: url)! as URL))
webView.policyDelegate = self as! WebPolicyDelegate
webView.mainFrame.load(NSURLRequest(url: self.urlpath as URL ) as URLRequest!)
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
You don't implement the WebPolicyDelegate so
webView.policyDelegate = self as! WebPolicyDelegate
will fail.
self (ViewController) does not implement WebPolicyDelegate.
You need to do:
class ViewController: NSViewController, WebFrameLoadDelegate, WebPolicyDelegate {
and implement the delegate.
Also make sure that your webView
#IBOutlet weak var webView: WebView!)
is connected to your webView in your Interface Builder!

WKWebview adjustment to be in the background

I've switched one of my apps to use WKWebview and it's the first time for me, I had a problem which is as you know I can't control it from the storyboard, I have a scrollview inside a sidebar that comes out when you click the button on the upper left, but it seems like it appears in the back of the view, how can I fix this please?
let configuration = WKWebViewConfiguration()
configuration.preferences = preference
webView = WKWebView(frame: view.bounds, configuration: configuration)
view.addSubview(webView)
please note that I already clicked the button in that screeshot but the scroll didn't show]1
Use this,
first import
import WebKit
set delegate of WKWebview
WKScriptMessageHandler , WKNavigationDelegate
declare webview
var webView: WKWebView!
var webConfiguration:WKWebViewConfiguration! = nil
override func loadView() {
webView = WKWebView(frame: .zero, configuration: self.webConfig())
webView.navigationDelegate = self
view = webView
}
viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
/*if let url = URL(string: "http://192.168.1.122/arvee/piyush/mobileViewPages/owner/manager.html") {
let request = URLRequest(url: url)
webView.load(request)
}*/
let url = Bundle.main.url(forResource: "AddAppointment/bookApp", withExtension:"html")
let request = URLRequest(url: url!)
webView.load(request)
}
WKWebview Delegate
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print(error)
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
let data = JSON(message.body)
}
func webConfig() -> WKWebViewConfiguration {
//if webConfiguration != false {
webConfiguration = WKWebViewConfiguration()
let userController = WKUserContentController()
userController.add(self, name: "buttonClicked")
userController.add(self, name: "pageLoaded")
webConfiguration.userContentController = userController
//}
return webConfiguration
}