Ich versuche, Methode Verkettung für Erfolg und Misserfolg Anrufe in meinem Code zu implementieren, aber ich habe Probleme mit der onSuccess
Methoden tatsächlich aufgerufen werden.Swift Method Chaining mit Erfolg und Fehler
- Ein View-Controller ruft die
getProduct(_:)
-Funktion auf. getProduct(_:)
macht einen API-Aufruf und ruft dannstoreProduct(_:)
mit dem abgerufenen jsonstoreProduct(_:)
AnrufefetchProduct(_:)
fetchProduct(_:)
AnrufedoSuccess(_:)
aber das wird nie wieder in dieonSuccess
der vorherigen Anrufe.
Einige Code-Schnipsel
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 get 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
do {
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 as NSError {
print("Could not fetch \(error), \(error.userInfo)")
productChains.doFailure(error)
}
return productChains
}
ich zunächst Initialis edited die kettenfähige Klasse pro Funktion, aber dies hatte seine eigenen Probleme, von denen ich (möglicherweise fälschlicherweise) dachte, dass ich die kettenfähige Klasse nur einmal initialisieren und ihre Referenz weitergeben sollte.
Einige Eingabe, wo ich falsch liege/was ich als nächstes versuchen könnte, wäre großartig.
Warum nicht ein Framework statt eigene zu bauen? Werfen Sie einen Blick auf Promekit; https://github.com/mxcl/PromiseKit –
Das mag die Art sein, wie ich gehe, da ich bereits zu viel Zeit damit verbracht habe zu versuchen, dies zu lösen. – Hodson