Last active
August 29, 2015 14:23
-
-
Save jakecraige/d8a9a26add5c2649da8d to your computer and use it in GitHub Desktop.
I'm unsure of what' the best way to dispatch requests in RAC 3. Whether or not using actions or methods is preferred and why. This code shows each way that I've implemented so far.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typealias RequestSignalProducer = SignalProducer<(NSData, NSURLResponse), NSError> | |
class ApiClient: ApiConnectable { | |
let apiURL = NSURL(string: "http://yardclub.github.io/mobile-interview/api")! | |
var getCategories: Action<Void, [Category], NSError>! | |
init() { | |
getCategories = Action { | |
let categoriesURL = self.apiURL.URLByAppendingPathComponent("catalog.json") | |
return self.getRequest(categoriesURL) |> map { parseJsonArray($0.0) } | |
} | |
} | |
func getSubcategoriesForCategory(category: Category) -> SignalProducer<[Subcategory], NSError> { | |
let subcategoriesURL = self.apiURL.URLByAppendingPathComponent("catalog/\(category.id).json") | |
return self.getRequest(subcategoriesURL) |> map { parseJsonArray($0.0) } | |
} | |
func getRequest(url: NSURL) -> RequestSignalProducer { | |
let request = NSURLRequest(URL: url) | |
return NSURLSession.sharedSession().rac_dataWithRequest(request) | |
} | |
} | |
// This class uses the action approach | |
class ChooseCategoryController { | |
let apiClient: ApiConnectable | |
var categories: MutableProperty<[Category]> = MutableProperty([]) | |
init(apiClient: ApiConnectable) { | |
self.apiClient = apiClient | |
self.categories <~ self.apiClient.getCategories.values | |
} | |
func requestCategories() { | |
self.apiClient.getCategories.apply().start() | |
} | |
// With actions I get niceties like this for free. | |
var refreshing: SignalProducer<Bool, NoError> { | |
return apiClient.getCategories.executing.producer | |
} | |
var refreshBegan: SignalProducer<Bool, NoError> { | |
return refreshing |> filter({ $0 == true }) | |
} | |
var refreshEnded: SignalProducer<Bool, NoError> { | |
return refreshing |> filter({ $0 == false }) | |
} | |
} | |
// This class uses the method approach | |
class ChooseSubcategoryController { | |
let apiClient: ApiConnectable | |
let category: Category | |
var subcategories: MutableProperty<[Subcategory]> = MutableProperty([]) | |
let request: SignalProducer<[Subcategory], NSError> | |
init(apiClient: ApiConnectable, category: Category) { | |
self.apiClient = apiClient | |
self.category = category | |
self.request = apiClient.getSubcategoriesForCategory(category) | |
} | |
func requestSubcategories() { | |
// You can only use the <~ operator with a SignalProducer that produces | |
// an error of type NoError | |
let noErrorRequest = request |> catch { _ in SignalProducer<[Subcategory], NoError>(value: []) } | |
subcategories <~ noErrorRequest | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment