Skip to content

Instantly share code, notes, and snippets.

@gboyegadada
Last active November 5, 2023 06:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gboyegadada/612d64557b14924e54d0c5f52610f0d7 to your computer and use it in GitHub Desktop.
Save gboyegadada/612d64557b14924e54d0c5f52610f0d7 to your computer and use it in GitHub Desktop.
Simple view model for extracting `og:meta` tags from a web page with Swift and WKWebView (without displaying the web view).
struct WebImageMetaData: Decodable {
let title: String?
let summary: String?
let url: URL?
let image: URL?
let mimetype: String?
let width: String?
let height: String?
private enum CodingKeys: String, CodingKey {
case title = "og:title"
case summary = "og:description"
case url = "og:url"
case image = "og:image"
case mimetype = "og:image:type"
case width = "og:image:width"
case height = "og:image:height"
}
}
// usage.
import SwiftUI
struct ScraperView: View {
@StateObject var modelView = WKWebViewScraper()
var body: some View {
if clipboard.content != nil {
Text(modelView.html)
}
}
}
import SwiftUI
import WebKit
class WKWebViewScraper: NSObject, ObservableObject, WKNavigationDelegate {
@Published var html: String = ""
var webView: WKWebView
private let js: String = """
JSON.stringify(Array.from(document.getElementsByTagName('meta'))
.filter(el => [
"og:image:type",
"og:title",
"og:description",
"og:url",
"og:image",
"og:image:type",
"og:image:width",
"og:image:height"
].includes(el.getAttribute("property")))
.reduce((result, el) => {
let prop = el.getAttribute("property")
let content = el.getAttribute("content")
if (prop && content) {
result[prop] = content
}
return result
}, {}))
"""
override init() {
self.webView = WKWebView()
super.init()
}
func load(_ url: URL?) -> Void {
let request = URLRequest(url: url!)
webView.navigationDelegate = self
webView.load(request)
}
// MARK: - add other navigation delegate methods here if you like.
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Webview finished loading.")
webView.evaluateJavaScript(self.js, completionHandler: {result, error in
if let html = result as? String {
self.html = html
}
})
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
// handle errors...
print("Webview failed with error: \(error.localizedDescription)")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment