Reputation: 1351
I am using a UIWebView
to load a webpage that is an article. Once I press a button, I create a struct with the url
, title
, and image
. To access the title, I need to access the webpage's source code and grab the title from a h1 header
that has the same class ID (class="c-page-title") for every article. Would anyone know how to use the stringByEvaluatingJavaScript
or evaluateJavaScript
function to get the text from the h1 header
?
Here is some of my code for reference:
Struct:
struct Article {
var url: URL
var img: URL
var title: String
init(url: URL, img: URL, title: String) {
self.url = url
self.img = img
self.title = title
}
}
Function that fills the Article struct:
@IBAction func bookmarkArt(_ sender: Any) {
let articleInst = Article(url: (mainWebView.request?.url)!, img: (mainWebView.request?.url)!, title: "Article Here")
bookmarks.append(articleInst)
print("array: \(bookmarks)")
let alertController = UIAlertController(title: "Bookmark added!", message: "This article was just added to your bookmarks.", preferredStyle: UIAlertControllerStyle.alert)
// Replace UIAlertActionStyle.Default by UIAlertActionStyle.default
let okAction = UIAlertAction(title: "Awesome, thanks!", style: UIAlertActionStyle.default) {
(result : UIAlertAction) -> Void in
print("OK")
}
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
}
Any help would be immensely appreciated!! Thanks so much in advance.
Cheers, Theo
Upvotes: 1
Views: 5393
Reputation: 690
Sure you can use func stringByEvaluatingJavaScript(from script: String) -> String?
articleInst.title = webView.stringByEvaluatingJavaScript("document.getElementsByClassName(\"c-page-title\")[0].innerHtml;")
The return value will be the html inside of the first element with the class name of "c-page-title".
However, I think a better approach would be the changing your UIWebView into a WKWebView. This will give your javascript a performance boost, if you are running lots of scripts inside your webView from your iOS code. I would also change that "c-page-title" from a class, into a ID, and make sure only one exists on a page. You could then usefunc evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Void)? = nil)
which is much better imo.
So it would look like:
webView.evaluateJavaScript("document.getElementById(\"c-page-title\").innerHtml;") {(response, error) in
if (response != nil) {
articleInst.title = response as! String
}
// error handling
}
Also keep in mind that this is using a complete handler, it is async, so you will need to build your logic for that.
Upvotes: 3