iOS WKWebView Swift javascript enable - ios

I'm trying to develop a simple app to browse my website. However my website contains some javascript and it doesn't successfully show my website.
In the past develop with android the same app and had to activate like this:
webSettings.setJavaScriptEnabled(true);
This currently my code I just have missing the option to enable javascript if somebody can help will really appreciate
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://132.148.136.31:8082")
let urlRequest = URLRequest(url: url!)
webView.load(urlRequest)
}
}

Working with WKWebView is better to create it from code. And you can set javaScriptEnabled to configuration:
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
let webview = WKWebView(frame: .zero, configuration: configuration)
Update. This is WKWebView in view controller class:
import UIKit
import WebKit
class ViewController: UIViewController {
private var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
webView = WKWebView(frame: view.bounds, configuration: configuration)
view.addSubview(webView)
}
}

For those who are building for iOS 14 with Swift 5 and Xcode 12, it has changed to the following ...
webView.configuration.defaultWebpagePreferences.allowsContentJavaScript = true

You are using WKWebView storyboard view so you can directly access the configuration. So use preferences under your WKWebView configuration.
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://132.148.136.31:8082")
let urlRequest = URLRequest(url: url!)
// enable JS
webView.configuration.preferences.javaScriptEnabled = true
webView.load(urlRequest)
}
}

The above answer is right you need to set this value as true to enable JavaScript.
webView.configuration.preferences.javaScriptEnabled = true
But if the JS scripts are from a non-HTTPS source then you need to allow "App Transport Security's Arbitrary Loads".
Here is how to fix that:
Navigate to Project Settings/Target/[your app's target]/Info.
Check whether there is a dictionary called App Transport Security Settings. If not, create it.
Inside it, create a boolean value called Allow Arbitrary Loads (if it's not there yet) and set it to YES.

IOS 15.5
add this
webView.configuration.defaultWebpagePreferences.allowsContentJavaScript = true

try this code :
override func viewDidLoad() {
super.viewDidLoad()
configureWebView()
currentWebView.load(requestURL)
}
private func configureWebView() {
webView.navigationDelegate = self
webView.uiDelegate = self
webView.allowsBackForwardNavigationGestures = true
/// javaScript 사용 여부
if #available(iOS 14, *) {
let preferences = WKWebpagePreferences()
preferences.allowsContentJavaScript = true
webView.configuration.defaultWebpagePreferences = preferences
}
else {
webView.configuration.preferences.javaScriptEnabled = true
/// user interaction없이 윈도우 창을 열 수 있는지 여부를 나타냄. iOS에서는 기본값이 false이다.
webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
}
}
func createNewWebView(_ config: WKWebViewConfiguration) -> WKWebView {
/// autoLayout 되어 있는 webView와 frame을 같게 한다.
let newWebView = WKWebView(frame: webView.frame,
configuration: config)
newWebView.navigationDelegate = self
newWebView.uiDelegate = self
newWebView.allowsBackForwardNavigationGestures = true
view.addSubview(newWebView)
popupWebViews.append(newWebView)
return newWebView
}

Related

how to open url with dynamic query string in WKWebView

I have a button on my website which has href https://live.example.net/?dynamic_encypted_query-string, So I wanted to open this url in my webview of ios app. Currently I'm building a web app through capacitor framework where I wrote a code to my WebViewController.swift file
class WebViewController: UIViewController, WKUIDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://live.example.net/?*")
let myRequest = URLRequest(url: url!)
webView.load(myRequest)
// Do any additional setup after loading the view.
}
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
}
This opens the domain(https://live.example.net) in the web view but i wanted to open it with the query string data.
let url = URL(string: "https://live.example.net/?*")
I think this doesn't work to fetch the query string data as well.

WKWebView does not allow camera access in application

We are trying to make a conference call with multiple users, So by using Kurento server we have achieved this and it's working on safari browser. But when it comes to implementation in WebView / WKWebView. It does not even ask for permissions.
#IBOutlet weak var webViewContainer: UIView!
var webView: WKWebView!
override open func loadView() {
super.loadView()
let webConfiguration = WKWebViewConfiguration()
webConfiguration.ignoresViewportScaleLimits = true
webConfiguration.suppressesIncrementalRendering = true
webConfiguration.allowsInlineMediaPlayback = true
webConfiguration.allowsAirPlayForMediaPlayback = false
webConfiguration.allowsPictureInPictureMediaPlayback = true
webConfiguration.mediaTypesRequiringUserActionForPlayback = .all
webConfiguration.requiresUserActionForMediaPlayback = true
webView = WKWebView(frame: webViewContainer.frame, configuration: webConfiguration)
webView.uiDelegate = self
webView.navigationDelegate = self
webView.sizeToFit()
webView.backgroundColor = .black
webView.isOpaque = false
self.webViewContainer.addSubview(webView)
}
func webContentController()-> WKUserContentController {
let contentController = WKUserContentController()
let script = try! String(contentsOf: Bundle.main.url(forResource: "WebRTC", withExtension: "js")!, encoding: String.Encoding.utf8)
contentController.addUserScript(WKUserScript(source: script, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: true))
contentController.add(self, name: "callbackHandler")
return contentController
}
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL (string: urlStr) else { return
}
let myRequest = URLRequest(url: url)
self.webView.load(myRequest)
}
I even have tried this link in safariViewController, but it does not ask for camera permissions.
This
Did you follow the steps from the documentation?
The most important part is the NSCameraUsageDescription / NSMicrophoneUsageDescription must be present inside the info.plist file
This is a known limitation of WKWebView for now, see the chrome issue for details
It's a Bug, the WkWebView has limited support to the WebRTC
It's now working since IOS 14.3 version
But to get this working, you need to set properties requiresUserActionForMediaPlayback = false
allowsInlineMediaPlayback = true
I had to do this:
import AVFoundation
#main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
AVCaptureDevice.requestAccess(for: .audio) { haveMicAccess in
print("Access to Microphone: \(haveMicAccess)")
}
return true
}
...
}
It still asks me each time I use the camera with getUserMedia() in the page script too. But without the above code getUserMedia is null. The above code triggers the request for access to the microphone so long as you provide a message in the info.plist for NSMicrophoneUsageDescription
In my case, I need camera open for account identifier. Setting config for webview below work for me:
webConfiguration.allowsInlineMediaPlayback = true
webConfiguration.mediaTypesRequiringUserActionForPlayback = []

WebKit View not opening certain URLs

I want the webkit view to display my domain webpage but it won't work. It works for regular known websites but not for my own domain. I am using the code below. Also I added this to the pList file but no joy. Thanks in advance.
pList
NSAppTransportSecurity
NSAllowsArbitraryLoads
Code:
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView()
webView.navigationDelegate = self
view = webView
webView.frame = view.bounds
webView.navigationDelegate = self
let url = URL(string: "https://www.MYDOMAIN.co.uk")!
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
}
}
Try for this
class YourCalssviewController : UIViewController ,WKNavigationDelegate ,WKUIDelegate{ }
Write in viewDidLoad()
let url = NSURL(string: "https://www.MYDOMAIN.co.uk")
let request = NSURLRequest(url: url! as URL)
self.webView.load(request as URLRequest)
your code is working fine, the problem here with the URL itself, if you tried an other URL like "https://www.youtube.com/" it will work fine

How to load excel / pdf server url in WKWebView Swift4

I wanted to load the excel sheet url/pdf url (document url) in WKWebView. As I am trying to open that url from browser then it directly downloads that document. So I am confused whether 1] I have to directly load the url into WKWebView or 2] first download those files and then load that local path in WKWebView.
If I go with the 2nd option then will my document download every time?
Following is the code which I have tried but it shows nothing
import UIKit
import WebKit
class OpenReportsFullScreenVC: UIViewController,WKUIDelegate {
var webView : WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
//first way :- webView.load(URLRequest(url: URL(string: "http://ipaddress/projects/ourivf/newourivf/assets/uploads/patient_image/attorney_details - Copy.xls")!))
// second way
let filePathURLData = "http://ipaddress/projects/ourivf/newourivf/assets/uploads/patient_image/attorney_details - Copy.xls"
let fileURL = URL(fileURLWithPath: filePathURLData )
webView.loadFileURL(fileURL, allowingReadAccessTo: fileURL)
}
override func loadView() {
//initialise webview
let webViewConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webViewConfiguration)
webView.uiDelegate = self
view = webView
}
}
Try with this code
import UIKit
import WebKit
class ViewController: UIViewController , **WKNavigationDelegate**{
var webView : WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let myBlog = "your URl"
let url = NSURL(string: myBlog)!
let request = NSURLRequest(url: url as URL)
webView = WKWebView(frame: self.view.frame)
webView.navigationDelegate = self
webView.load(request as URLRequest)
self.view.addSubview(webView)
self.view.sendSubview(toBack: webView)
}
}
File path cannot have blank characters like in your example.

ScriptMessageHandler not always called on actual device, works fine on simulator

I use WKWebView and I want to be notified when website is fully loaded. The webView:didFinishNavigation method of WKNavigationDelegate is fired when document.readyState is either interactive or complete and I want to be sure that site was completely loaded. I came up with the solution which uses JavaScript injection. Here is my MWE:
import UIKit
import WebKit
class ViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate {
var webView: WKWebView!
#IBOutlet weak var loadLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let contentController = WKUserContentController()
let scriptPath = NSBundle.mainBundle().pathForResource("script", ofType: "js")!
let scriptString = try! String(contentsOfFile: scriptPath)
let script = WKUserScript(source: scriptString, injectionTime: .AtDocumentStart, forMainFrameOnly: true)
contentController.addUserScript(script)
contentController.addScriptMessageHandler(self, name: "readyHandler")
let configuration = WKWebViewConfiguration()
configuration.userContentController = contentController
webView = WKWebView(frame: CGRect.zero, configuration: configuration)
webView.navigationDelegate = self
loadLabel.text = nil
}
#IBAction func loadWebsite() {
webView.loadRequest(NSURLRequest(URL: NSURL(string: "http://stackoverflow.com")!))
loadLabel.text = "Loading..."
}
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
print("message received")
loadLabel.text = "Complete"
}
}
And this is the content of script.js file:
document.onreadystatechange = function () {
if(document.readyState === "complete"){
webkit.messageHandlers.readyHandler.postMessage("");
}
}
userContentController:didReceiveScriptMessage method is always called on iOS Simulator, but on the actual device (iPhone 6 in my case) it isn't called most of the times. Any idea what can be wrong about it or what's the other way of checking if website is completely loaded?
For some reason you need to add the webView to a visible view for this to work on the device. If you don't want the webView to be visible, add it and then set the hidden property to true.
For the code example above:
func viewDidLoad(){
...
webView.hidden = true
view.addSubview(webView)
}

Resources