ios - Swift Method Chaining with Success & Failure -


i trying implement method chaining success , failure calls in code seem having trouble getting onsuccess methods called.

  1. a view controller calls getproduct(_:) function.
  2. getproduct(_:) makes api call , calls storeproduct(_:) retrieved json
  3. storeproduct(_:) calls fetchproduct(_:)
  4. fetchproduct(_:) calls dosuccess(_:) never gets onsuccess of previous calls.

some code snippets

bsproductchainable.swift

import foundation  class bsproductchainable<successparams, failureparams> {      var successclosure: ((successparams) -> ())? = nil     var failureclosure: ((failureparams) -> ())? = nil      func onsuccess(closure: (successparams) -> ()) -> bsproductchainable {         successclosure = closure         return self     }     func onfailure(closure: (failureparams) -> ()) -> bsproductchainable {         failureclosure = closure         return self     }     func dosuccess(params: successparams) {         if let closure = successclosure {             closure(params)         }     }     func dofailure(params: failureparams) {         if let closure = failureclosure {             closure(params)         }     } } 

bsproductmanagerswift.swift

class bsproductmanagerswift: nsobject {  typealias productresponsechain = bsproductchainable<product, nserror?> typealias productsresponsechain = bsproductchainable<[product], nserror?>  var serviceclient: bsnetworkingserviceclient! var objectcontext: nsmanagedobjectcontext! var productchains: bsproductchainable<product, nserror?>! var productschains: bsproductchainable<[product], nserror?>!  convenience init(serviceclient: bsnetworkingserviceclient) {     self.init()     self.serviceclient = serviceclient     self.objectcontext = managedobjectcontext     self.productchains = bsproductchainable<product, nserror?>()     self.productschains = bsproductchainable<[product], nserror?>() }  func getproduct(ean: string) -> productresponsechain {      let urlstring = bsconstants.barcodescanner.productendpoint.stringbyappendingstring(ean)     serviceclient.get(urlstring, failure: { (error) in         print("could not product")     }) { (response) in         if let json = response {             self.storeproduct(json).onsuccess({ (returedproduct) in                 print("stored product")             })         }     }      return productchains }  func storeproduct(json: json) -> productresponsechain {      fetchproduct(json["ean"].stringvalue).onsuccess { (returedproduct) in         self.productchains.dosuccess(returedproduct)     }      return productchains }  func fetchproduct(ean: string) -> productresponsechain {      let fetchrequest = nsfetchrequest(entityname: "product")     let predicateean = nspredicate(format: "%k == %@", "ean", ean)     let predicatemarket = nspredicate(format: "%k == %@", "market", bscountrymanager.sharedinstance().getcurrentcountry().market)     let predicatelocale = nspredicate(format: "%k == %@", "locale", bslocalizationmanager.sharedmanager().currentlocalization.localeidentifier())     let predicatecurrency = nspredicate(format: "%k == %@", "currency", bslocalizationmanager.sharedmanager().currentlocalization.country.currencyidentifierdmw)     let compoundpredicate = nscompoundpredicate(andpredicatewithsubpredicates: [predicateean, predicatemarket, predicatelocale, predicatecurrency])     fetchrequest.predicate = compoundpredicate      {         let matchingprouducts = try objectcontext.executefetchrequest(fetchrequest)          if matchingprouducts.count == 0 {             print("no matching products found")             let entity = nsentitydescription.entityforname("product", inmanagedobjectcontext: objectcontext)             productchains.dosuccess(product(entity: entity!, insertintomanagedobjectcontext: objectcontext))         } else {             print("found matching product")             let d = matchingprouducts.first as! product             productchains.dosuccess(d)         }     } catch let error nserror {         print("could not fetch \(error), \(error.userinfo)")         productchains.dofailure(error)     }      return productchains } 

i initialised chainable class per function had own issues thought (possibly incorrectly) should initialise chainable class once , pass around reference.

some input going wrong/what try next great.

as recommended @john elements, decided use promisekit

this didn't require of code change , here functions (still need bit of code cleanup works!):

func getproduct(ean: string) -> promise<product> {     return promise { fullfill, reject in         let urlstring = bsconstants.barcodescanner.productendpoint.stringbyappendingstring(ean)         serviceclient.get(urlstring, failure: { (error) in             reject(error!)         }) { (response) in             if let json = response {                 self.storeproduct(json).then ({ returnedproduct in                     print("we stored product: \(returnedproduct.ean)")                     fullfill(returnedproduct)                 }).error { returnederror in                     print("we had problem storing product: \(returnederror)")                 }             }         }     } }  func storeproduct(json: json) -> promise<product> {     return promise { fullfill, reject in         fetchproduct(json["ean"].stringvalue).then ({ returnedproduct in              var storedproduct: product!             var isnewproduct = false              print("fetched product: \(returnedproduct.ean)")              isnewproduct = returnedproduct.valueforkey("ean") == nil             storedproduct = returnedproduct             storedproduct.setvalue(json["name"].stringvalue, forkey: "name")             storedproduct.setvalue(json["ean"].stringvalue, forkey: "ean")             storedproduct.setvalue(json["image"].stringvalue, forkey: "image")             storedproduct.setvalue(json["price"].doublevalue, forkey: "price")             storedproduct.setvalue(json["status"].intvalue, forkey: "status")             storedproduct.setvalue(json["pdp"].stringvalue, forkey: "pdp")             storedproduct.setvalue(bscountrymanager.sharedinstance().getcurrentcountry().market, forkey: "market")             storedproduct.setvalue(bslocalizationmanager.sharedmanager().currentlocalization.localeidentifier(), forkey: "locale")             storedproduct.setvalue(bslocalizationmanager.sharedmanager().currentlocalization.country.currencyidentifierdmw, forkey: "currency")              {                 try self.objectcontext.save()                 print("stored product: \(returnedproduct.ean)")                 fullfill(returnedproduct)                  if isnewproduct {                     nsnotificationcenter.defaultcenter().postnotificationname("didaddscanentry", object: nil)                 }              } catch let error nserror {                 print("could not save \(error), \(error.userinfo)")                 reject(error)             }          }).error { returnederror in             print("we had problem fetching product: \(returnederror)")             reject(returnederror)         }     } }  func fetchproduct(ean: string) -> promise<product> {     return promise { fullfill, reject in          let fetchrequest = nsfetchrequest(entityname: "product")         let predicateean = nspredicate(format: "%k == %@", "ean", ean)         let predicatemarket = nspredicate(format: "%k == %@", "market", bscountrymanager.sharedinstance().getcurrentcountry().market)         let predicatelocale = nspredicate(format: "%k == %@", "locale", bslocalizationmanager.sharedmanager().currentlocalization.localeidentifier())         let predicatecurrency = nspredicate(format: "%k == %@", "currency", bslocalizationmanager.sharedmanager().currentlocalization.country.currencyidentifierdmw)         let compoundpredicate = nscompoundpredicate(andpredicatewithsubpredicates: [predicateean, predicatemarket, predicatelocale, predicatecurrency])         fetchrequest.predicate = compoundpredicate          {             let matchingprouducts = try objectcontext.executefetchrequest(fetchrequest)              if matchingprouducts.count == 0 {                 print("no matching products found")                 let entity = nsentitydescription.entityforname("product", inmanagedobjectcontext: objectcontext)                 fullfill(product(entity: entity!, insertintomanagedobjectcontext: objectcontext))             } else {                 print("found matching product")                 let d = matchingprouducts.first as! product                 fullfill(d)             }         } catch let error nserror {             print("could not fetch \(error), \(error.userinfo)")             reject(error)         }     } } 

Comments