ios - How to return a value from a function that is generated from a parse query within the function? -


problem: when call below function within viewcontroller tableview cellforrowatindexpath method, nil, need set generated object pfobject variable called rankobject declared globally in viewcontroller. i've tried lot of things, including completion handlers, , still stuck. how accomplish task?

func getormakerankrelations(sound: pfobject) {     var rankrelation = sound.relationforkey("userranks")     let currentuser = pfuser.currentuser()!     var relationquery = rankrelation.query()     relationquery?.wherekey("user", equalto: currentuser)     relationquery?.findobjectsinbackgroundwithblock { (theobject: [anyobject]?, error: nserror?) -> void in         if (theobject?.isempty == true) {             println("rank object empty")              //make ranking pfobject             var ranking = pfobject(classname: "ranking")             ranking["user"] = pfuser.currentuser()!             ranking["rank"] = 0              //upload ranking parse             ranking.saveinbackgroundwithblock { (saved: bool, error: nserror?) -> void in                 if saved {                     println("saved ranking")                      //add relation between sound , ranking                     rankrelation.addobject(ranking)                     sound.saveinbackgroundwithblock { (saved: bool, error: nserror?) -> void in                         if saved {                             println("saved relation")                             var theobject = (theobject![0] as? pfobject)!                             self.rankobject = theobject //////////note:  variable saves while in closure /////////////                         } else {                             println("relation not saved :(")                         }                     }                 } else {                     println(error)                 }             }         } else {             var theobject = (theobject![0] as? pfobject)!             self.rankobject = theobject  //////////note:  variable saves while in closure /////////////         }     } } 

here how call function in tableview:

getormakerankrelation(sound) 

not dealing specifics of asynch call, fact asynchronous, in objective-c (and swift) declare function take @ least 2 parameters: whatever needed parameterize remote request, , block run when request completes.

reading code, i'd advise breaking , create part own functions, remain sane, so...

- (void)getorcreaterankforsound:(pfobject *)sound completion:(void (^)(pfobject *, nserror *))completion {      [self getrankforsound:sound completion:^(pfobject *rank, nserror *error) {         if (!rank && !error) {  // there's no rank, , no error either, must create 1              [self createrankforsound:sound completion:^(pfobject *rank, nserror *error) {                 completion(rank, error);             }];          } else {             completion(rank, error);         }     }]; }  - (void)createrankforsound:(pfobject *)sound completion:(void (^)(pfobject *, nserror *))completion {      // build pfobject rank sound, save , tell our     // caller happened invoking completion block     // ...     [newlycreatedrank saveinbackgroundwithblock:^(bool success, nserror *error) {         return (success)? completion(newlycreatedrank, nil) : completion(nil, error);     }]; } 

now cellforrowatindexpath can safely call method, because caches results.

// pseudo code in cellforrowatindexpath pfobject *sound = self.mydatasourcearray[indexpath.row];  // want change cell subview present rank object  // don't make network requests in method without caching result // assume have dictionary of rank objects indexed sound object id correspond pfobject *rank = self.ranksforsound[sound.objectid]; if (rank) {     // no need make network request, use rank, presumably update cell     cell.ranklabel.text = // function of rank } else {     // need make network request, put placeholder value in cell , call our function     cell.ranklabel.text = // placeholder value     [self getorcreaterankforsound:sound completion:^(pfobject *rank, nserror *error) {         // important, cell might have scrolled away time block runs         // don't alter cell directly, reload it.  cellforrowatindexpath         // called again, cache primed         if (!error) {             [tableview reloadrowsatindexpaths:@[indexpath]];         }     }]; } // configure other parts of cell return cell; 

Comments

Popular posts from this blog

c# - Better 64-bit byte array hash -

webrtc - Which ICE candidate am I using and why? -

php - Zend Framework / Skeleton-Application / Composer install issue -