我正在尝试使用MVVM模式将RxSwift添加到代码中。我的应用程序需要从API获取FoodType(沙漠,餐等)列表并将其保存到Realm数据库。然后,我有一个UITextField和UIButton的视图。
用户写食物类型(例如:沙漠):
视图模型
struct FoodTypeViewModel {
// Get datas from API
private func getFoods() {
foodService.getAll(completionHandler: { result in
switch result {
case .Success(let foods):
for food in foods {
food.save()
}
break
case .Failure(let error):
debugPrint(error)
break
}
})
}
// Get datas from API
private func getFoodTypes() {
foodService.getAll(completionHandler: { result in
switch result {
case .Success(let foodTypes):
for type in types {
type.save()
}
break
case .Failure(let error):
debugPrint(error)
break
}
})
}
}
的ViewController
class SetupViewController: UIViewController {
@IBOutlet weak var foodTypeTextField: UITextField!
@IBOutlet weak var foodTypeButton: UIButton!
}
模型
class FoodType: Object {
dynamic var identifier: String = ""
dynamic var fullName: String?
let foods = List<Food>()
}
我想将RxSwift添加到该代码中,但我该如何处理异步API。首次启动时,应用程序没有数据(我不想在开始时填充)但是当用户单击按钮时。因此,在按钮单击时,UI应等待来自服务的响应(使用等待动画),并且ViewModel应在服务响应时更新UI。有什么想法吗?
答案 0 :(得分:1)
首先,创建一个通用的返回对象来包装通信错误。
enum APIResult<T> {
case success(T)
case error(Error)
}
然后,转换完成处理程序以返回Observable
:
func getFoods() -> Observable<APIResult<[FoodType]>> {
return Observable<APIResult<[FoodType]>>.create { observer -> Disposable in
self.foodService.getAll(completionHandler: { result in
switch result {
case .Success(let foods):
observer.onNext(.success(foods))
break
case .Failure(let error):
observer.onNext(.error(error))
break
}
observer.onCompleted()
return Disposables.create()
})
}
}
现在只需像在RxSwift中一样处理observable。
getFoods().subscribe(onNext: { result in
switch result {
case .success(let foods):
print("Received foods: \(foods)")
break
case .error(let error):
print("Received error: \(error)")
break
}
}.addDisposableTo(disposeBag)
使用these utility classes将帮助您映射成功结果,并将错误和成功信号拆分到不同的可观察对象。例如:
let foodsRequest = getFoods().splitSuccess
foodsRequest.error.subscribe(onNext: { error in
print("Received error: \(error)")
})
foodsRequest.success.subscribe(onNext: { foods in
print("Received foods: \(foods)")
}
您还可以将Realm对象转换为RxSwift observables:
let realm = try! Realm()
realm.objects(Lap).asObservable()
.subscribeNext {[weak self] laps in
self?.tableView.reloadData()
}
请查看Using Realm Seamlessly in an RxSwift App以获取更多信息和示例。