ios - nil value when populating views from struct model -
ios - nil value when populating views from struct model -
i'm having problem populating views data. made struct called weatherdata.swift holds properties parsed json.
struct weatherdata { var currenttemp: int? init( city: nsstring) { //grab json via nsurlsession & swiftyjson , assign in closure self.currenttemp = json["currently"]["temperature"].int println("heres current temp: \(self.currenttemp!)") //heres current temp: 65 } }
cool prints fine! @ view controller when i'm trying assign value uilabels:
func requestdataforcity() { currentlocationdata = weatherdata(city: savedcity) var label = uilabel() label.frame = cgrectmake(0, 0, 40, 40) label.backgroundcolor = uicolor.yellowcolor() label.text = "\(currentlocationdata.currenttemp!)" scrollview.addsubview(label) }
i nil currentlocationdata.currenttemp. thought maybe code assigning currenttemp property label before initialized, used nsnotifcationcenter, didn't work. ideas on doing wrong?
https://github.com/yamski/weatherapp
your problem appears assigning value in closure after init completes. don't show closure in code assume looks this:
struct weatherdata { var currenttemp: int? init( city: nsstring) { allow request = nsurlrequest(url: nsurl(string: "http://site/data")) nsurlsession.sharedsession().datataskwithrequest(request, completionhandler: { (data, response, error) -> void in self.currenttemp = readthedata(data) println("heres current temp: \(self.currenttemp!)") }).resume() } }
if alter currenttemp
var
let
, you'll error in assignment: cannot assign 'currenttemp in 'self'
. confirm attempting assign value after init
completes. similarly, if move println out of closure see app crash when trying print nil.
one thing do, if looking synchronous api block execution until completion:
struct weatherdata { var currenttemp: int? init( city: nsstring) { var semaphore = dispatch_semaphore_create(0) allow request = nsurlrequest(url: nsurl(string: "http://site/data")) nsurlsession.sharedsession().datataskwithrequest(request, completionhandler: { (data, response, error) -> void in self.currenttemp = readthedata(data) dispatch_semaphore_signal(semaphore) }).resume() dispatch_semaphore_wait(semaphore, dispatch_time_forever) } }
this approach has problems though:
this of course of study halt ui every time initialize weatherdata on main queue. it assumes nsurlsession has different delegatequeue queue beingness run on. if not deadlock. i haven't seen documentation explicitly stating mutating operations withininit
guaranteed impact current instance. reasonable swift have exclusively different re-create of self
in closure. a improve approach move work out of struct, signature next completionhandler called in main queue:
func getweatherforcity(city:nsstring, completionhandler: ((weatherdata) -> void)?)
weatherdata have init function takes json info extract temperature:
struct weatherdata { allow currenttemp: int init(json:json) { currenttemp = json["currently"]["temperature"].int } }
then ui code this:
func requestdataforcity() { getweatherforcity(savedcity, completionhandler: { weather -> void in currentlocationdata = weather var label = uilabel() label.frame = cgrectmake(0, 0, 40, 40) label.backgroundcolor = uicolor.yellowcolor() label.text = "\(currentlocationdata.currenttemp!)" scrollview.addsubview(label) }) }
ios iphone swift ios8
Comments
Post a Comment