Reputation: 345
I'm trying to retrieve the XML from an rss feed, get the links for each article, and then extract info from those articles. I'm using AEXML to get the xml, and ReadabilityKit for link extraction.
I'm successfully pulling the links from the XML, but the parser call on Readability is never executing. I don't want this on the main thread as it blocks all UI, but so far that's the only way I've made it work. Code is below (removed that dispatch get main queue):
func retrieveXML() {
let request = NSURLRequest(URL: NSURL(string: "<XML URL HERE>")!)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
(data, response, error) in
if data == nil {
print("\n\ndataTaskWithRequest error: \(error)")
return
}
do {
let xmlDoc = try AEXMLDocument(xmlData: data!)
for child in xmlDoc.root.children {
if let postURL = child["id"].value {
let url = NSURL(string: postURL)
let parser = Readability(url: url!)
let title = parser.title()
print("TITLE: \(title)")
}
}
} catch {
print(error)
}
}
task.resume()
}
Upvotes: 0
Views: 68
Reputation: 438467
The problem is that Readability
is deadlocking. You're calling it from a NSURLSession
completion block (which defaults to a serial queue), but Readability
blocks that queue with a semaphore until its own network request is completed. So Readability
is deadlocking because it's blocking a thread waiting for a semaphore signal that is supposed to be sent from the same thread it is blocking.
You can fix this by asynchronously dispatching the code that instantiates Readability
to a separate queue (e.g. a global queue).
dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) {
let url = NSURL(string: postURL)
let parser = Readability(url: url!)
let title = parser.title()
print("TITLE: \(title)")
}
It looks like that API has been updated to run asynchronously, so get the latest version and this deadlocking issue is eliminated and the above asynchronous dispatch will not be needed. You'll obviously have to employ the completion handler pattern of the updated API.
Upvotes: 0
Reputation: 503
Thanks for reporting. The new version is available in cocoa pods and cartage with a new aync API. Sync API is removed from the project.
Readability.parse(url: articleUrl, { data in
let title = data?.title
let description = data?.description
let keywords = data?.keywords
let imageUrl = data?.topImage
let videoUrl = data?.topVideo
})
Thanks for your contribution! For more info please check README https://github.com/exyte/ReadabilityKit
Upvotes: 1