ttrs ttrs - 5 months ago 9
iOS Question

Fetching and parsing functionality location in MVC

I need to load data from rss and display it in tableview. I decided to do it in some other class rather than in ViewController. So I created DataFetch class. The problem is that I use third party library to work with rss, and it works like this:

func fetchPodcastFeed() -> [RSSFeedItem]{
let feedURL = NSURL(string: feedURLString)!
var feedItems = [RSSFeedItem]()
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), {
// Run parsing in a background thread
FeedParser(URL: feedURL)?.parse({ (result) in
feedItems = (result.rssFeed?.items)!
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//reload table

})
})
})
return feedItems
}


Of course when I call
fetchItems = dataFetcher.fetchPodcastFeed()
from ViewController I don't get any data. Should I use notifications and if so, how to pass fetched data to ViewController through them? Or is there better approach?

Answer

So I assume the fetchPodcastFeed() function is your code, right? Then I'd suggest defining it with a callback like so:

func fetchPodcastFeed(onCompletion:(result:[RSSFeedItem]) -> Void) {
    // setup as you have it ...
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                // call the completion closure
                onCompletion(feedItems)
            })
        })
    })
}

Then, wherever you're calling the method, do it like this:

fetchPodcastFeed({(result) in
    // reload your table with result, which is of type [RSSFeedItem]
})

Theoretically you could also simply pass the completion handler directly into the parse method you're calling on the FeedParser object, but since you are on a background thread it's probably wiser to first send it to the main thread again. Otherwise you'd have to put the reload table stuff in a dispatch_asynccall, it's nicer the way you started.

Comments