Embed web inside Mac executable - swift

I need to embed a web inside a MAC executable, so that the html is inside the executable (and not loaded from an external server). It should also be possible to print the contents of the webview.
I have tried with Xcode and Swift, but when printing the webview it looks blank, there are lots of entries in Stack Overflow and seems to be no solution for this in swift.
I have also tried Xojo.com, but the contents are outside the executable visible to the user and must be hidden inside.
Any guidance?
CODE:
import Cocoa
import WebKit
class ViewController: NSViewController {
#IBOutlet weak var WEBVW: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
if let url = Bundle.main.url ( forResource: "index"
, withExtension: "html"
, subdirectory: "www")
{
let path = url.deletingLastPathComponent();
self.WEBVW.loadFileURL ( url
, allowingReadAccessTo: path);
WEBVW.printView(self)
}
}
}
IMAGE: Program running and printing: https://postimg.cc/Lqsddv1T
Many thanks

Related

Could not store value in safari browser localstorage using swift

I am using WebKit to store the email in the safari browser local storage. However, I am getting an error of
thread 3: Fatal error: Unexpectedly found nil while unwrapping an
Optional value
One way to store value in localstorage is using UserDefaults but this way the value is not stored in safari local storage thus i used the below way
import SafariServices
import WebKit
class SafariExtensionViewController: SFSafariExtensionViewController {
#IBOutlet weak var webView: WKWebView!
static let shared = SafariExtensionViewController()
override func viewDidLoad() {
self.preferredContentSize = NSSize(width: 300, height: 250)
message.stringValue = ""
emailMessage.stringValue = ""
passwordMessage.stringValue = ""
}
#IBAction func userLogin(_ sender: Any) {
let providedEmailAddress = email.stringValue
self.webView.evaluateJavaScript("localStorage.setItem(\"email\", \"value\")") { (result, error) in
self.webView.reload()
}
}
}
my question is, how do i store the value in safari browser localstorage from swift so i can access that from javascript as well.
You didn't connect webView outlet (that is marked as Implicitly Unwrapped Optional) from storyboard so you got this error.
You can use CoreData, UserDefaults, FileManager, even simple SQLite to store what you want.
EDIT:
A Safari app extension can read and modify your webpage content. Also it allows you to access data in your browser.
Complete the following steps to make Safari App Extension:
Build a Safari App Extension
Inject a script into a webpage
Pass message between your Safari app extension and injected script

Configuring Interface Builder's new WKWebView object

As some of you may have noticed, Apple recently implemented the WKWebView (from WebKit) as an object in the Interface Builder; however, I am having difficulty with properly implementing it. I am still able to implement it by code, but implementing it via the Interface Builder has proven to be a bit of a pain.
The WKWebView appears blank on launch, and although the NSTextField appears to work when configured, the WKWebView continues to remain blank and doesn't even call upon didStartProvisionalNavigation, didCommit or didFinish when implemented (whereas, when done programatically, this continues to work).
Interface Builder Screenshot
Interface Builder Menu Options
Note: I did attempt to implement it using the WebConfiguration as well, but no luck either. Now I'm just trying to keep the code as simplistic as possible to get a better understanding as to why this is not working.
ViewController.swift
import Cocoa
import WebKit
class WindowController: NSWindowController {
override func windowDidLoad() {
super.windowDidLoad()
// Configure Window Appearance
window!.titlebarAppearsTransparent = true
window!.isMovableByWindowBackground = true
window!.title = ""
window!.backgroundColor = NSColor.white
}
}
class ViewController: NSViewController, WKUIDelegate, WKNavigationDelegate {
let myURL = "https://google.com"
#IBOutlet var webView: WKWebView!
#IBOutlet var pageTitle: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Load Homepage URL in WebView
webView.load(URLRequest(url: URL(string: myURL)!))
}
}
So as it turns out, the WKWebView refuses to become active while there is an entitlements file in your project. In my case, I had the App Sandbox enabled with the following settings:
com.apple.security.network.server – YES
com.apple.security.files.user-selected.read-write – YES
Once deleting the entitlements file and removing it entirely from the project, the WKWebView began to work again.

cannot view pdf to web view using file path

i have an app to download pdf file. If the download completed it have a path like
file:///Users/developer/Library/Developer/CoreSimulator/Devices/F9AB746D-20C3-4333-AE70-2840538F4AED/data/Containers/Data/Application/861FA32B-06AA-4176-A499-B4BB8DF224C1/Library/Caches/pdffile.pdf
I try to view using this
#IBOutlet weak var webView: UIWebView!
var path = ""
var receiveData: String = "" //this contain file:///Users/developer.../Caches/pdffile.pdf
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL.fileURLWithPath(receiveData)
print(url)
self.webView.loadRequest(NSURLRequest(URL: url))
}
the build succeded and no error butstill can't view the pdf file
what's wrong?
Change your NSURL path, you need to use receiveData, because that already contain the path of the file, NSBundle is use when you have file inside your project directory.
let url = NSURL.fileURLWithPath(receiveData)

Loading HTML into Webview from a string, OS X

I would like to create some formatted text using HTML in my OS X program. I am programing in swift. I created a web view and set up a simple test.
import Cocoa
import RealmSwift
import WebKit
class invociegenerator: NSViewController {
#IBOutlet var InvoiceView: WebView!
override func viewDidLoad() {
super.viewDidLoad()
var htmlString:String! = "<br /><h2>Hello World!!</h2>"
InvoiceView.loadHTMLString(htmlString, baseURL: nil)
// Do view setup here.
}
}
I receive an error saying "WebView does not have a member named 'LoadHTMLString'" I must be missing something, is it possible to load from a string in an OS X program? There are plenty of tutorials online but the all focus on iOS.
"loadHTMLString" is a method on a WebFrame object not WebView. However, Webview does have a method that returns the mainFrame for the webview. So you could just call mainFrame on the webview like this.
InvoiceView.mainFrame.loadHTMLString(htmlString, baseURL: nil)

Injecting a new stylesheet into a website via uiwebview using iOS8 Swift XCode 6

I've seen a few options on here using just Objective-C, but I'm having trouble doing this with Swift iOS8 in XCode 6. I'm using the uiwebview to load a website. For sake of example, let's say its google.com.
#IBOutlet var website: UIWebView!
var url = "http://www.google.com"
func loadUrl() {
let requestURL = NSURL(string: url)
let request = NSURLRequest(URL: requestURL!)
website.loadRequest(request)
}
override func viewDidLoad() {
super.viewDidLoad()
website.delegate = self
loadUrl()
}
func webViewDidFinishLoad(website: UIWebView) {
var jsscript = "some script here"
website.stringByEvaluatingJavaScriptFromString(jsscript)
}
Using Swift, how would I inject a whole new stylesheet into the website so I can overwrite many of the styles?
Also, I'd like the new stylesheet to exist in one of my app's directories. Where is the best directory for that to be? Under "Supporting files?" And, how would I call that path in my code?
It would also be nice if the website wouldn't load until the styles had been applied.
So, I think I found at least one way to accomplish appending styles to the webpage being loaded using Swift:
var loadStyles = "var script =
document.createElement('link');
script.type = 'text/css';
script.rel = 'stylesheet';
script.href = 'http://fake-url/styles.css';
document.getElementsByTagName('body')[0].appendChild(script);"
website.stringByEvaluatingJavaScriptFromString(loadStyles)
Using the now preferred WKWebView you can put the external css file, say tweaks.css in the root of your project or in a sub-folder, then you can inject it into your page like this:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
guard let path = Bundle.main.path(forResource: "tweaks", ofType: "css") else { return }
let css = try! String(contentsOfFile: path).replacingOccurrences(of: "\\n", with: "", options: .regularExpression)
let js = "var style = document.createElement('style'); style.innerHTML = '\(css)'; document.head.appendChild(style);"
webView.evaluateJavaScript(js)
}
To make the file available:
Click your project
Click your target
Select Build Phases
Expand Copy Bundle Resources
Click '+' and select your file.
Also make sure that your controller implements WKNavigationDelegate:
class ViewController: UIViewController, WKNavigationDelegate