Last active
November 5, 2023 06:41
-
-
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).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// usage. | |
import SwiftUI | |
struct ScraperView: View { | |
@StateObject var modelView = WKWebViewScraper() | |
var body: some View { | |
if clipboard.content != nil { | |
Text(modelView.html) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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