Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c ReactiveCocoa有两个特性_Objective C_Reactive Cocoa - Fatal编程技术网

Objective c ReactiveCocoa有两个特性

Objective c ReactiveCocoa有两个特性,objective-c,reactive-cocoa,Objective C,Reactive Cocoa,仅观察一个属性时,以下代码可以正常工作: [[[[RACObserve(self, userName) ignore:nil] flattenMap:^(NSString *userName) { return [self authenticateUserWithUserName:userName andPassword:@"password"]; }] deliverOn:RACScheduler.mainThrea

仅观察一个属性时,以下代码可以正常工作:

[[[[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);

     }]; }

使用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
}

使用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
}

诀窍在于
展平贴图
。您可以将
map
调用转换为
combineTest:reduce:
调用,但是
flattmap
做的更多,即在映射后进行展平。谢谢,这就是解决方案。诀窍在于
flattmap
。您可以将
map
调用转换为
combinelateTest:reduce:
调用,但是
flattmap
做的更多,即在映射后进行展平。谢谢,这就是解决方案。我将添加一些小注释。你忘了插入@weakify(self)和@strongify(self),我会添加一些小评论。您忘记插入@weakify(self)和@strongify(self)
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
}