Printing from WKWebView on button click [duplicate] - ios

This question already has answers here:
Detect button click (by class name) in WKWebView with JavaScript.evaluate
(2 answers)
Closed 1 year ago.
I have a print recipe java script function in the backend login for the employees. So in the normal browser it calls the print windows and it's possible to print.
But in the WKWebView it doesn't work. I read and read questions on forums and the apple developer documentation but I could not find a solution.
So how can I detect the print button push on the site, from swift, and call the function which prints the needed area?
I have attached screenshots of my code and the site. The first picture is the site you land on in the app, then you have to login and afterwards click on the order and then on print. screenshots are in this row attached):
My code is:
import UIKit
import WebKit
class MitarbeiterViewController: UIViewController, WKUIDelegate,UIWebViewDelegate {
var webView: WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string:"https://www.pizzeria-lo-straniero.de/mitarbeiterlogin")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
func printRecipeWebViewController(){
//MARK: - PRINT
let webviewPrint = webView.viewPrintFormatter()
let printInfo = UIPrintInfo(dictionary: nil)
printInfo.jobName = "page"
printInfo.outputType = .general
let printController = UIPrintInteractionController.shared
printController.printInfo = printInfo
printController.showsNumberOfCopies = false
printController.printFormatter = webviewPrint
printController.present(animated: true, completionHandler: nil)
}

Hi and welcome to StackOverflow ,
Your requirement is certainly possible and it can be done by injecting a script message handler to userContentController. Basically you inject your webview with some JS so it allows you to listen to the certain actions and then you can perform the required actions in the other end. This detailed answer should assist you with the requirement , please make sure to make a quick search to avoid repetitions of questions
https://stackoverflow.com/a/62743190/9343566. - Answer 1
https://stackoverflow.com/a/62743190/9343566. - Answer 2

Related

WKWebView -How to AutoPlay Video Without VideoID?

In my app I use WKWebView and the user can go to different websites like google, wikipedia, vimeo, etc. The issue is if the user decides to go to https://www.youtube.com, when the user taps a thumbnail to play it, it doesn't autoplay because I don't have the videoId (eg. "https://youtu.be/MpvshzR6tNk" + "&autoplay=1"), I just have the youtube website url
For example:
func loadRequest() {
let strThatUserEntered = "https://youtube.com"
let urlStr = "strThatUserEntered"
guard let url = URL(string: urlStr), let request = URLRequest(url: url) else { return }
wkWebView.load(request)
wkWebView.allowsBackForwardNavigationGestures = true
}
Now when the user selects a random thumbnail, the video loads, the youtube play button appears, and when it's pressed, I get An error occurred, please try again later (this video definitely works)
How can I enable autoplay on any selected youtube thumbnail, if I don't have the videoID?
code:
override func viewDidLoad()
super.viewDidLoad()
let webConfiguration = WKWebViewConfiguration()
webConfiguration.allowsInlineMediaPlayback = true
webConfiguration.mediaTypesRequiringUserActionForPlayback = []
wkWebView = WKWebView(frame: .zero, configuration: webConfiguration)
wkWebView.navigationDelegate = self
wkWebView.uiDelegate = self
// pin wkWebView anchors to screen
loadRequest()
}

How to create a iOS Webview App (HTML5) with Xcode?

I'm trying to load local html5 files to Xcode to create an ios App. I tried using a template and it uses both local and web based paths to create a very nice ios app in Xcode.
I need to learn about how to create a a webview app that has normal features and can load my local html5 webapps into Xcode for compiling an ios app.
I tried the following code, and it works alright when loading a url based html5 page.
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {
https://developer.apple.com/documentation/webkit/wkwebview
var webView: WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string:"https://www.apple.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}}
I need to change the URL to local file path. The above code page from apple documentation suggests that I use load(_: ) to load local html files. I'm not sure how to use this function. So, I tried code samples from alternate sources, and here's some part of the code I'm trying with for the Webview app.
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {
#IBOutlet var webView: WKWebView!
//var webView: WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
guard let fileUrl = Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "www-WebsiteContent") else { return; }
//let urlPath = Bundle.main.url(forResource: "input", withExtension: "txt")
if fileUrl != "" {
let url = URL(fileURLWithPath: fileUrl)
//let url = init(_: fileURLWithPath, path: "www-WebsiteContent/index.html")
webView.loadFileURL(url, allowingReadAccessTo : url)
let request = URLRequest(url: url)
webView.load(request)
}
//let myURL = URL(string:"file:///www-WebsiteContent/index.html")
//let myRequest = URLRequest(url: myURL!)
//webView.load(myRequest)
//webView.loadFileURL(URL: , webView.allowingReadAccessTo readAccessURL: URL)
}}
I'm using latest Xcode version on Macbook Air with latest Swift 5 version. There's a main storyboard with the webview object, and a viewcontroller.swift file.
The error is that when I run the project, it doesn't display the index.html file in the www-WebsiteContent folder. Maybe I wasn't able to connect the webview overlay to the viewcontroller.swift file properly.
Things I need to understand:
Can I run the above code and compile it as a complete ios app? Or would I need to edit AppDelegate or SceneDelegate files too? I've only edited the viewcontroller.swift file as a new project.
How can I resize the webview overlay to automatic width and height of the ios device? I have an html5 webapp files that I need to convert to an ios app. How can I create this webview so that it fits all the device types screen sizes? My html5 app fits perfectly when viewed in the device browser.

Start local server iOS & load it on WKWebView

I found following libraries to start a server locally.
https://github.com/httpswift/swifter
https://github.com/swisspol/GCDWebServer
For instance, I'm using swifter. It does compile for iOS.
I also added code to start a local server as follows.
class ViewController: UIViewController {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let server = HttpServer()
server["/hello"] = { .ok(.htmlBody("You asked for \($0)")) }
let semaphore = DispatchSemaphore(value: 0)
do {
try server.start(9080, forceIPv4: true)
print("Server has started ( port = \(try server.port()) ). Try to connect now...")
let config = WKWebViewConfiguration()
webView = WKWebView(frame: self.view.bounds, configuration: config)
/////////////////////////////
// What should be url here to point to local server?
webView.load(URLRequest(url: URL(string: "http://192.168.31.70:9080/hello")!))
/////////////////////////////
view = webView
semaphore.wait()
} catch {
print("Server start error: \(error)")
semaphore.signal()
}
}
}
Also, If I submit it to apple, is there any possibility of rejection because of starting a local server?
Can you elaborate on what you are trying to achieve by starting an HTTP server in-process?
If you need control over the way that responses are made, I would recommend looking at registering a custom URL protocol handler with WKWebViewConfiguration.setURLSchemeHandler(_:forURLScheme:). Then, ask the WKWebView to load a resource from that custom URL scheme, and your handler (that conforms to WKURLSchemeHandler) will get called, and you can construct a URLResponse however you'd like.
I tried Telegraph
Step 1. Open Podfile & add a dependency - pod 'Telegraph'
Step 2. Open AppDelegate.swift & put code as follows.
// Serve the Server from Build folder
let demoBundleURL = Bundle.main.url(forResource: "webApp", withExtension: nil)!
// and handle those requests at Path
serverHTTP.serveDirectory(demoBundleURL, "/webApp")
// Setting Custom Router - OPTIONAL
serverHTTP.httpConfig.requestHandlers.insert(DRHTTPMiddleWare(), at: 0)
// Start Server
try? serverHTTP.start(port: 9000, interface: "localhost")
Step 3. In ViewController.swift, put code as follows.
func loadWebView() {
guard let url = URL(string: "http://localhost:9000/webApp") else { return }
webView = WKWebView(
frame: self.view.bounds,
configuration: WKWebViewConfiguration()
)
webView.load(URLRequest(url: url))
view = webView
}

Add margin at top of webView in Swift IOS

I am downloading files from server and showing in my ios device. File type can be any thing like image, pdf etc. and all loading up fine. Now the problem is, some part of file or image is hiding behind the title of page. I want to add margin at top of file after it loads up.
Code I have written to show file:
func openFile(file:String) {
let myBlog = file
let url = NSURL(string: myBlog)
let request = NSURLRequest(url: url! as URL)
webView.load(request as URLRequest)
self.view.addSubview(webView)
let pdfVC = UIViewController()
pdfVC.view.addSubview(webView)
pdfVC.title = "File"
self.navigationController?.pushViewController(pdfVC, animated: true)
self.navigationController!.navigationBar.tintColor = colors.whiteColor
}
I have created webView property within Class like:
var webView : WKWebView!
And inside viewDidLoad(), I have written:
webView = WKWebView(frame: self.view.frame)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.isUserInteractionEnabled = true
webView.navigationDelegate = self
Result I am getting:
Here some part of image is behind the title. I have tried verious solutions given in link add margins in swift, but nothing is working.
My suggestion is to create instance of WKWebView in controller where you need to display it, in your case instance pdfVC
There is can be model, for example:
enum FileType {
case image(fileURL: URL)
case pdf(fileURL: URL)
}
Creating incase of FileViewController and assign fileType to it
func openFile(file:String) {
let pdfViewController = FileViewController()
pdfVC.fileType = FileType.pdf(fileURL: URL(string: "https://www.google.com")!) // example
pdfVC.title = "File"
navigationController?.pushViewController(pdfVC, animated: true)
}
And inside your VC where you need to display a file:
In this way, even if you do have navigationBar you won't have problem with navigationBar and topMargin
class FileViewController: UIViewController {
var fileType: FileType!
override func viewDidLoad() {
super.viewDidLoad()
var urlRequest: URLRequest!
switch fileType {
case .image(let url), .pdf(let url):
urlRequest = URLRequest(url: url)
#unknown default:
break
}
let webView = WKWebView(frame: view.frame)
webView.load(urlRequest)
self.view = webView
}
}
Hope this will help you!
use Bounds instead of Frame
webView = WKWebView(frame: self.view.Bounds)

"Creating an image format with an unknown type is an error" when displaying a WebApp through WKWebView

I am displaying a WebApp through WKWebView in Swift 3 (Xcode 8.3.3)
The WebApp is functioning as expected, except when I try to post an image to the server through the WebView.
The console from Xcode simply prints "Creating an image format with an unknown type is an error" without any further info to help me troubleshoot.
As this thread indicates, there might be something with alerts that is causing this issue. That the WebView is not set up correctly to display alerts and that this might cause an error.
However I have not been able to figure that one out by looking at the suggested solutions there.
In my viewWillAppear I call the function initWebView() which is set up like this:
func initWebView() {
let source: NSString = "var meta = document.createElement('meta');" +
"meta.name = 'viewport';" +
"meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no';" +
"var head = document.getElementsByTagName('head')[0];" +
"head.appendChild(meta);" as NSString
let sourceScript: WKUserScript = WKUserScript(source: source as String, injectionTime: .atDocumentStart, forMainFrameOnly: true)
let addCookieScript="localStorage.setItem('device', '\(self.tokenFirebase)');"
let script: WKUserScript = WKUserScript(source: addCookieScript as String, injectionTime: .atDocumentStart, forMainFrameOnly: false)
// Create the user content controller and add the script to it
let userContentController = WKUserContentController()
userContentController.addUserScript(script)
userContentController.addUserScript(sourceScript)
// Create the configuration with the user content controller
let config = WKWebViewConfiguration()
config.userContentController = userContentController
let wkWebView = WKWebView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height), configuration: config)
wkWebView.translatesAutoresizingMaskIntoConstraints = true
self.wkWebView = wkWebView
wkWebView.restorationIdentifier = "wkWebView"
view.addSubview(wkWebView)
wkWebView.navigationDelegate = self
wkWebView.uiDelegate = self
let request : NSMutableURLRequest = NSMutableURLRequest(url: self.webUrl as URL)
wkWebView.isHidden = false
wkWebView.load(request as URLRequest)
}
I have been testing the app with the same results across iPhone SE (iOS 10) iPhone 7 (iOS 10) and iPad (iOS 9.3.3).
EDIT: The possible duplicate entry does not appear valid to me as it refers to implementing UIImagePickerController by code, but in my scenario it is the image picker that is created by the WKWebView which seems to cause this issue. However if I'm mistaken please guide me in the right direction :)
Creating an image format with an unknown type is an error this is a generic warning you can safely ignore the warning. The problem should be something else.
import UIKit
import WebKit
class ViewController: UIViewController {
var webView:WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
loadWebView()
}
func loadWebView(){
webView = WKWebView(frame: self.view.frame)
self.view.addSubview(webView)
let urlRequest = URLRequest(url: URL(string: "https://imgbb.com/")!)
webView.load(urlRequest)
}
}
I created a webview and tried to upload an image from photo library. it does give me that warning but it successfully uploaded the pic from photo library. You can try to above code and see if it works for you. btw don't forget to add permission explanation to access photolibrary in info.plist

Resources