Nested dataTaskWithRequest in Swift tvOS -
i'm c# developer convert swift tvos , starting learn. i've made progress, not sure how handle nested calls json. sources different providers can't combine query.
how wait inner request complete tvseries has poster_path? there better way add show collection , process poster path loading in thread doesn't delay ui experience?
func downloadtvdata() { let url_btv = nsurl(string: btv_url_base)! let request_btv = nsurlrequest(url: url_btv) let session_btv = nsurlsession.sharedsession() //get series data let task_btr = session_btv.datataskwithrequest(request_btv) { (data_btv, response_btv, error_btv) -> void in if error_btv != nil { print (error_btv?.description) } else { { let dict_btv = try nsjsonserialization.jsonobjectwithdata(data_btv!, options: .allowfragments) as? dictionary<string, anyobject> if let results_btv = dict_btv!["results"] as? [dictionary<string, anyobject>]{ obj_btv in results_btv { let tvshow = tvseries(tvdict: obj_btv) //for each tv series try load poster_path secondary provider if let str = obj_btv["title"] as? string!{ let escapedstring = str?.stringbyaddingpercentencodingwithallowedcharacters(.urlqueryallowedcharacterset())! if let url = nsurl(string: self.search_url_base + escapedstring!) { let request = nsurlrequest(url: url) let session = nsurlsession.sharedsession() let task = session.datataskwithrequest(request) { (data, response, error) -> void in if error != nil { print (error?.description) } else { { let dict = try nsjsonserialization.jsonobjectwithdata(data!, options: .allowfragments) as? dictionary<string, anyobject> if let results = dict!["results"] as? [dictionary<string, anyobject>] { //iterate through poster array obj in results { if let path = obj["poster_path"] as? string { tvshow.posterpath = path break } } } } catch let error nserror { print(error.description) } } } task.resume() } } self.tvseries.append(tvshow) } dispatch_async(dispatch_get_main_queue()){ self.collectionview.reloaddata() } } } catch let error nserror { print(error.description) } } } task_btr.resume() } thanks help!
i recommend breaking things apart multiple methods, callbacks sequence operations, , utilizing swift's built-in throws error handling mechanism. here's example, not perfect, might starting point:
class tvseries { let title: string var posterpath: string? enum error: errortype { case malformedjson } init(tvdict: [string: anyobject]) throws { guard let title = tvdict["title"] as? string else { throw error.malformedjson } self.title = title } static func loadallseries(completionhandler: [tvseries]? -> void) { nsurlsession.sharedsession().datataskwithurl(nsurl(string: btv_url_base)!) { data, response, error in guard let data = data else { print(error) completionhandler(nil) return } { completionhandler(try fromjsondata(data)) } catch let error { print(error) } }.resume() } static func fromjsondata(jsondata: nsdata) throws -> [tvseries] { guard let dict = try nsjsonserialization.jsonobjectwithdata(jsondata, options: .allowfragments) as? [string: anyobject] else { throw error.malformedjson } guard let results = dict["results"] as? [[string: anyobject]] else { throw error.malformedjson } return try results.map { return try tvseries(tvdict: $0) } } func loadposterpath(completionhandler: () -> void) { guard let searchpath = title.stringbyaddingpercentencodingwithallowedcharacters(.urlqueryallowedcharacterset()) else { completionhandler() return } let url = nsurl(string: search_url_base)!.urlbyappendingpathcomponent(searchpath) nsurlsession.sharedsession().datataskwithurl(url) { [weak self] data, response, error in defer { completionhandler() } guard let strongself = self else { return } guard let data = data else { print(error) return } { strongself.posterpath = try tvseries.posterpathfromjsondata(data) } catch let error { print(error) } }.resume() } static func posterpathfromjsondata(jsondata: nsdata) throws -> string? { guard let dict = try nsjsonserialization.jsonobjectwithdata(jsondata, options: .allowfragments) as? [string: anyobject] else { throw error.malformedjson } guard let results = dict["results"] as? [[string: anyobject]] else { throw error.malformedjson } result in results { if let path = result["poster_path"] as? string { return path } } return nil } } it might worth time rxswift or alamofire, these kinds of data-conversion / sequencing operations.
Comments
Post a Comment