dpa*_*age 3 mvvm ios reactive-cocoa
我开始使用ReactiveCocoa.简单的事情是有道理的,但我还不能做复杂性.;)
这就是我想要建模的:我有一个视图控制器,它显示从HTTP端点请求的一些数据.HTTP端点使用类似浏览器的基本身份验证和cookie.
所以,我想发出那个HTTP请求.如果成功,那么,显示数据.如果它失败了401,我需要告诉视图弹出一个模态对话框,询问用户名/密码,然后重试HTTP请求.
在我的ViewModel中,那么,我有两个信号吗?一个返回内容,另一个告诉视图层我需要凭据?如何将凭据返回到HTTP请求发生的位置?
您的ViewModel会将您的应用程序模型调整为其视图.换句话说,它维护视图需要显示的任何状态(以可绑定属性的形式)并公开API以更新该状态并执行应用程序的"工作"(以普通旧方法的形式).所以,从你写的内容来判断:
"我有一个视图控制器,显示从HTTP端点请求的一些数据."
听起来好像,你的ViewModel应该有一些方法将这些数据表示为状态.几乎总是可以使用Objective-C属性完成此操作:
@interface MyViewModel : NSObject
@property (nonatomic, strong) NSArray *tableData;
// (Or whatever makes sense for your view.)
@property (nonatomic) BOOL needCredentials;
@end
Run Code Online (Sandbox Code Playgroud)
然后,您的视图控制器应绑定到这些属性,以便每当属性更改时(例如,每当检索到新数据或收到401错误时),都会更新相应的UIView.请注意您的ViewModel的API甚至没有任何ReactiveCocoa代码.这是因为如果您的视图控制器具有对ViewModel对象的引用,则视图控制器可以使用ReactiveCocoa以任何有意义的方式绑定到ViewModel.例如,在更简单的情况下,您可以使用RAC(self, infoView.name) = RACObserve(self, myViewModel.infoViewName);.在更复杂的情况下,例如实现UITableViewDelegate,您需要实现UITableViewDataSource方法,但这是相同的想法.要显示一个询问用户名和密码的模态对话框,您甚至可以使用类似的东西
- (void)viewDidLoad
{
self.myViewModel = [[ViewModel alloc] init];
@weakify(self);
[[RACObserve(self, myViewModel.needCredentials) ignore:@NO] subscribeNext:^(id _) {
@strongify(self);
[self displayModalDialog];
}];
}
Run Code Online (Sandbox Code Playgroud)
"所以,我想发出那个HTTP请求.如果成功,那就好了,显示数据.如果失败了401,我需要告诉视图弹出一个模态对话框,询问用户名/密码,然后重试HTTP请求."
您的ViewModel可以有一个方法,如- (void)sendRequest:(NSDictionary *)parameters.从视图控制器调用此方法可能如下所示:
- (IBAction)handleButtonTap:(id)sender
{
NSDictionary *parameters = [self makeParametersFromTextFields];
[self.myViewModel sendRequest:parameters];
}
Run Code Online (Sandbox Code Playgroud)
再次注意:ViewModel的API中不需要ReactiveCocoa代码.这并不是说你不应该使用RAC,只是说ViewModel的API 不一定依赖于信号或任何ReactiveCocoa概念 - 它只是一个专门用于服务应用程序中特定视图的模型对象.在ViewModel的方法实现中,您可能在整个地方使用信号,或者您可能正在使用一些更强制性的API,如NSOperationQueues等.只要您的ViewModel通过KVO-observable属性向视图公开数据(这样您的视图控制器就可以绑定到那些通常使用ReactiveCocoa完成的属性),这并不重要.
那么你的-sendRequest:方法对这个参数字典做了什么呢?我不知道.那部分取决于你.如果它获得有效响应,则应更新ViewModel上的某些属性(例如,tableData上面代码片段中的属性).如果它得到a 401,它应该更新ViewModel上的一些其他属性(例如,将needCredentials属性设置为YES).已经绑定到这些属性的视图控制器将以您配置的任何方式做出反应.
"在我的ViewModel中,那么,我有两个信号吗?一个返回内容,另一个告诉视图层我需要凭据?如何将凭据返回到HTTP请求发生的位置?"
我希望在这一点上我已经回答了这个问题.ViewModel不需要任何信号.它只需要KVO能力的属性.并且如上面在-handleButtonTap:方法示例中所示,您无需执行任何特殊操作即可将凭据下载到HTTP请求发生的位置 - 只需调用ViewModel上的方法,并传入任何有意义的数据.(当然,ViewModel必须知道哪个对象提供凭据才能启动HTTP请求,并处理响应,但该部分应该是非常学术的.)
| 归档时间: |
|
| 查看次数: |
1137 次 |
| 最近记录: |