i trying implement method chaining success , failure calls in code seem having trouble getting onsuccess
methods called.
- a view controller calls
getproduct(_:)
function. getproduct(_:)
makes api call , callsstoreproduct(_:)
retrieved jsonstoreproduct(_:)
callsfetchproduct(_:)
fetchproduct(_:)
callsdosuccess(_:)
never getsonsuccess
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
Post a Comment