i trying create common class storing , retrieving data in parse. made parseprocessing class singleton class. main view controller load data , store dictionary in parseprocessing. creating shared instance of parseprocessing class. view controller try access data dictionary. assumed because parseprocessing singleton class have single copy of dictionary. not appear correct. how should declare variables inside parseprocessing shared? code shown below:
import uikit var gsep = "," class qwikfileviewcontroller: uiviewcontroller { var loaddata = parseprocessing.sharedinstance override func viewdidload() { super.viewdidload() // load data parse loaddata.loadcategorysubcategorydata() loaddata.loadrecordsfromparse() } override func didreceivememorywarning() { super.didreceivememorywarning() } }
parseprocessing singleton class
import uikit import parse class parseprocessing: parse { var dictmenulist = [string:string]() var notetitle = [string]() var notes = [string]() var thumbnailfiles = [pffile]() var objectids = [string]() var noteimage = uiimage() class var sharedinstance:parseprocessing { struct singleton { static let instance:parseprocessing = parseprocessing() } return singleton.instance } // load category/subcategory data parse data base func loadrecordsfromparse () -> bool{ var tmpfile = [pffile]() var loadcomplete = false var query = pfquery(classname:"record") query.findobjectsinbackgroundwithblock { (objects, error) -> void in if error == nil { // find succeeded. println("successfully retrieved \(objects!.count) items.") object in objects! { self.notetitle.append(object["title"] as! string) self.notes.append(object["notes"] as! string) self.thumbnailfiles.append(object["thumbnail"] as! pffile) self.objectids.append(string(stringinterpolationsegment: object.objectid)) } } else { println("\(error)") } loadcomplete = true } return loadcomplete } // load category/subcategory data parse data base func loadcategorysubcategorydata () // -> dictionary <string,string> { var success : bool = false var d : dictionary <string,string> = ["":""] var menu = pfquery(classname: "classification") println("parseprocessing: loadcategory...") menu.findobjectsinbackgroundwithblock { (objects, error) -> void in if error == nil { var category = "" var subcategory = "" object in objects! { category = object["category"] as! string println("parseprocessing: category = \(category)") subcategory = object["subcategory"] as! string println("parseprocessing: subcategory = \(subcategory)") d[category] = subcategory } success = true self.dictmenulist = d return } else { println("parseprocessing: error = \(error)") success = false } } return } }
another view controller examine data
import uikit class testviewcontroller: uiviewcontroller { var dictmenulist = [string:string]() var loaddata = parseprocessing.sharedinstance override func viewdidload() { super.viewdidload() dictmenulist = loaddata.dictmenulist println("dictmenulist: \(dictmenulist)") } override func didreceivememorywarning() { super.didreceivememorywarning() } }
the problem findobjectsinbackgroundwithblock
asynchronous method (i.e. returns closure called later when query done). cannot return loadcomplete
in loadrecordsfromparse
, example. background request never done time loadrecordsfromparse
returns.
instead, want adopt completionhandler
pattern. example, sample loadrecords
doesn't try return immediately, rather call completionhandler
when request done.
func loadrecords(completionhandler:([someobject]?, nserror?) -> ()) { let query = pfquery(classname: "someclass") query.findobjectsinbackgroundwithblock { objects, error in // build model object completionhandler(objectarray, error) } }
and you'd call so:
loaddata.loadrecords() { objects, error in // use `objects` (and make sure `error` `nil`) here } // not use variables here, above closure has not run yet!
frankly, i'd inclined rid of properties in singleton altogether. when you're dealing asynchronous code, have public properties updated asynchronously going source of heartache. can it, wouldn't first choice.
for example, when testviewcontroller
presented, cannot assume asynchronous fetch associated dictmenulist
done yet. @ , wonder if makes sense testviewcontroller
initiate fetch , use dictmenulist
in completion handler. that's going easiest.
if must initiate asynchronous request 1 view controller , have view controller informed when asynchronous request done, might have use other pattern, such notifications (e.g. use nsnotificationcenter
, , have singleton post notifications when various requests done, , view controller needs informed of fact can add observers notification).
Comments
Post a Comment