当只观察一个属性时,以下代码可以正常工作:
[[[[RACObserve(self, userName) ignore:nil]
flattenMap:^(NSString *userName) {
return [self authenticateUserWithUserName:userName andPassword:@"password"];
}] deliverOn:RACScheduler.mainThreadScheduler]
subscribeError:^(NSError *error) {
// TODO: Propagate error
}];
但是当我尝试同时观察两个属性时,我不能得到结果:
[[[RACSignal
combineLatest:@[ [RACObserve(self, userName) ignore:nil],
[RACObserve(self, password) ignore:nil] ]
reduce:^(NSString *userName,
NSString *password) {
return [self authenticateUserWithUserName:userName andPassword:password];
}]deliverOn:RACScheduler.mainThreadScheduler]
subscribeError:^(NSError *error) {
// TODO: Propagate error
}];
以下是代码的其余部分:
@property (nonatomic, strong) PFPClient *client;
-(RACSignal *)authenticateUserWithUserName:(NSString *)userName andPassword:(NSString *)password {
return [[self.client authenticateUser:_userName withPassword:_password] doNext:^(PFPAccessToken *accessToken) {
self.accessToken = accessToken;
}];
}
客户端类:
-(RACSignal *)authenticateUser:(NSString *)userName withPassword:(NSString *)password {
NSString *urlString = [NSString stringWithFormat:@"https://xxxx?username=%@&password=%@", userName, password];
NSURL *url = [NSURL URLWithString:urlString];
return [[self fetchJSONFromURL:url] map:^(NSDictionary *json) {
return [MTLJSONAdapter modelOfClass:[PFPAccessToken class] fromJSONDictionary:json error:nil];
}];
}
-(RACSignal *)fetchJSONFromURL:(NSURL *)url {
NSLog(@"Fetching: %@", url.absoluteString);
// When observing two properties, next block is never executed...
return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"Opening request...");
NSURLSessionDataTask *dataTask = [self.session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse
*response, NSError *error) {
NSLog(@"Request finished.");
if (! error) {
NSError *jsonError = nil;
id json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
if (! jsonError) {
[subscriber sendNext:json];
}
else {
[subscriber sendError:jsonError];
}
}
else {
[subscriber sendError:error];
}
[subscriber sendCompleted];
}];
[dataTask resume];
return [RACDisposable disposableWithBlock:^{
[dataTask cancel];
}];
}] doError:^(NSError *error) {
NSLog(@"%@",error);
}]; }
知道我做错了什么?
EDIT。电话必须这样做:
[[[[RACSignal
combineLatest:@[ [RACObserve(self, userName) ignore:nil],
[RACObserve(self, password) ignore:nil] ]]
flattenMap:^(RACTuple *userNameAndPassword) {
RACTupleUnpack(NSString *userName, NSString *password) = userNameAndPassword;
return [self authenticateUserWithUserName:userName andPassword:password];
}]
deliverOn:RACScheduler.mainThreadScheduler]
subscribeError:^(NSError *error) {
// TODO: Propagate error
}];
答案 0 :(得分:4)
[[[RACSignal
combineLatest:@[ [RACObserve(self, userName) ignore:nil],
[RACObserve(self, password) ignore:nil] ]]
flattenMap:^(RACTuple *userNameAndPassword) {
RACTupleUnpack(NSString *userName, NSString *password) = userNameAndPassword;
return [self authenticateUserWithUserName:userName andPassword:password];
}]
deliverOn:RACScheduler.mainThreadScheduler]
subscribeError:^(NSError *error) {
// TODO: Propagate error
}];
答案 1 :(得分:0)
使用Swift非常简单
let emailSignal = self.textFieldEmail.reactive.continuousTextValues
let passwordSignal = self.textFieldPassword.reactive.continuousTextValues
emailSignal.combineLatest(with: passwordSignal).observeValues { (mail, password) in
guard let mailText = mail, let passwordText = password else {
self.buttonLogin.isEnabled = false
return
}
self.buttonLogin.isEnabled = mailText.count > 0 && passwordText.count > 0
}