rest - Assigning data from closure after dataTaskWithURL resulting in nil values -


i apologize simplicity of description, i'm new swift language.

i have rest api provides data app. attempting populate table view json feed. essentially, trying best stick mvc patterns use in web development. i've built model of data object, , list model contain individual instances of object.

the actual problem is, when initiate whole process (last code sample) result count 0 that's because data response api call hasn't happened yet. i'd rather not use synchronous calls, i'm feeling that's way i'm going fix this, unless start mucking api calls directly controller itself?

class newsitem {     var id: int     var headline: string     var summary: string     var created: string     var source: string     var company: string     var companylogo: uiimage      init(headline: string, summary: string, created: string, source: string, company: string, companylogourl: string, id: int) {         self.id = id         self.headline = headline         self.summary = summary         self.created = created         self.source = source         self.company = company          if let url = nsurl(string: companylogourl) {             if let data = nsdata(contentsofurl: url) {                 companylogo = uiimage(data: data)!             } else {                 companylogo = uiimage(named: "defaultlogo")!             }         } else {             companylogo = uiimage(named: "defaultlogo")!         }     } } 

i have newslist class builds array of news items using closure rest call.

class newslist {     var name: string     var newsitems: [newsitem]      init(named: string, includenewsitems: [newsitem]) {         name = named         newsitems = includenewsitems     }      class func getnewsitems() -> [newslist] {         return [self.parsednews()]     }      private class func parsednews() -> newslist {         var newsitems = [newsitem]()          api.getlatestactivitydata({jsondata, error -> void in             if (jsondata != nil) {                 (_, subjson) in jsondata["data"] {                     let headline  = subjson["headline"].string!                     let summary = subjson["summary"].string!                     let created = subjson["created"].string!                     let source = subjson["source"].string!                     let company = subjson["company"].string!                     let companylogo = subjson["companylogo"].string!                     let id = subjson["id"].int!                      dispatch_async(dispatch_get_main_queue(), {                         newsitems.append(newsitem(headline: headline, summary: summary, created: created, source: source, company: company, companylogourl: companylogo, id: id))                     })                 }             } else {                 print("api data fetch failed")                 print(error)             }         })          return newslist(named: "news", includenewsitems: newsitems)     } } 

for call above, i've got following method inside remoteapi class

func getlatestactivitydata(completionhandler: ((json!, nserror!) -> void)!) -> void {         let requesturl = self.baseurl + "xxxxxxx"         print("request url: " + requesturl)          let url = nsurl(string: requesturl)!         let request = nsmutableurlrequest(url: url)         request.setvalue("text/json; charset=utf-8", forhttpheaderfield: "content-type")          let task = nsurlsession.sharedsession().datataskwithurl(url, completionhandler: {data, response, error -> void in             if (error != nil) {                 return completionhandler(nil, error)             }              print("latest activity response received")             let returnstring = nsstring(data: data!, encoding: nsutf8stringencoding)             let jsondata = returnstring!.datausingencoding(nsutf8stringencoding)!             let readablejson = json(data: jsondata, options: nsjsonreadingoptions.mutablecontainers, error: nil)              if (error != nil) {                 return completionhandler(nil, error)             } else {                 return completionhandler(readablejson, nil)             }         })          task.resume()     } 

to initiate entire above convoluted process, have in view controller

var newsitems: [newsitem] {     var newslist = newslist.getnewsitems()     return newslist[0].newsitems } 

here our pain point. if fire print(newsitems.count) after above call, result 0. second or 2 later, callback handler receive data , begin assigning items newslist array.

how prevent array assignment until data received? going entirely wrong way?

xcode 7 + swift 2.0 + ios 9.0.x

my error in how using closure. depending upon closure assign values outside closure , completion handler return values.

solution:

  1. i removed entire newslist class, redundant doing

  2. i changed call in view controller following

    var newsitems = [newsitem]()  api.getlatestactivitydata({jsondata, error -> void in     if (jsondata != nil) {         dispatch_async(dispatch_get_main_queue(), {             (_, subjson) in jsondata["data"] {                 let headline  = subjson["headline"].string!                 let summary = subjson["summary"].string!                 let created = subjson["created"].string!                 let source = subjson["source"].string!                 let company = subjson["company"].string!                 let companylogo = subjson["companylogo"].string!                 let id = subjson["id"].int!                  newsitems.append(newsitem(headline: headline, summary: summary, created: created, source: source, company: company, companylogourl: companylogo, id: id))             }              self.activitytableview.reloaddata()         })     } else {         print("api data fetch failed")         print(error)     } }) 

now should need once loop done, should able update table reload.

for 'newer' swift users me, didn't understand have helped know yesterday ... when call tableview.reloaddata() app trigger tabieview related events, if data source has been updated closure mine above, cellforrowatindexpath , numberofrowsinsection able correctly update. assign data in cellforrowatindexpath function.

hope helps someone!


Comments

Popular posts from this blog

1111. appearing after print sequence - php -

java - WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/board/] in DispatcherServlet with name 'appServlet' -

Ruby on Rails, ActiveRecord, Postgres, UTF-8 and ASCII-8BIT encodings -