2013-08-04 41 views
5

Tôi có thông báo thành công và thông báo lỗi thông qua NSNotificationCenter. Tôi đã viết một số xét nghiệm để tìm ra cách kết hợp các tín hiệu từ hai thông báo đó thành một tín hiệu cung cấp lỗi khi các thông báo thất bại và tiếp theo là hoàn thành khi thông báo thành công.Cách ưa thích để tạo tín hiệu tín hiệu kết hợp với tín hiệu và hoàn thành khi hoàn thành hoặc lỗi là gì?

Hiện tại, các khối hoàn chỉnh sẽ không bị trúng, tiếp theo và lỗi sẽ bị ảnh hưởng.

Ngoài ra, câu hỏi thưởng thứ cấp: tại sao không @ [errorNotification, completeNotification] .rac_sequence.signal làm điều tương tự như tín hiệu tạo tín hiệu bên dưới?

Code:

-(void)test_flatten_signal_of_signals_and_convert_notification_to_error{ 
    RACSignal *errorNotification = [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"TEST_FAILURE" object:nil] take:1]; 


    errorNotification = [errorNotification flattenMap:^(NSNotification *notification){ 
     return [RACSignal error:[NSError errorWithDomain:@"RAC_TEST" code:1 userInfo:nil]]; 
    }]; 

    RACSubject *completeNotification = [RACSubject subject]; 

    RACSignal *signalOfSignals = [[RACSignal 
            createSignal:^RACDisposable *(id<RACSubscriber> subscriber){ 
             [subscriber sendNext:errorNotification]; 
             [subscriber sendNext:completeNotification]; 
             [subscriber sendCompleted]; 
             return nil; 
            }] 
            flatten]; 


    __block BOOL hitCompleted = NO; 

    [signalOfSignals 
    subscribeNext:^(id val){ 
     STFail(nil); 
    } 
    error:^(NSError *err){ 
     hitCompleted = YES; 
    } 
    completed:^{ 
     STFail(nil); 
    }]; 

    [[NSNotificationCenter defaultCenter] postNotificationName:@"TEST" object:self]; 

    STAssertTrue(hitCompleted, nil); 
} 

-(void)test_flatten_signal_of_signals_and_hits_next_complete_on_notification{ 
    RACSubject *errorNotification = [RACSubject subject]; 

    RACSignal *completeNotification = [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"TEST_SUCESS" object:nil] take:1]; 

    RACSignal *signalOfSignals = [[RACSignal 
            createSignal:^RACDisposable *(id<RACSubscriber> subscriber){ 
             [subscriber sendNext:errorNotification]; 
             [subscriber sendNext:completeNotification]; 
             [subscriber sendCompleted]; 
             return nil; 
            }] 
            flatten]; 


    __block BOOL hitCompleted = NO; 
    __block BOOL hitNext = NO; 
    [signalOfSignals 
    subscribeNext:^(id val){ 
     hitNext = YES; 
    } 
    error:^(NSError *err){ 
     STFail(nil); 
    } 
    completed:^{ 
     hitCompleted = YES; 
    }]; 

    [[NSNotificationCenter defaultCenter] postNotificationName:@"TEST_SUCCESS" object:self]; 

    STAssertTrue(hitCompleted, nil); 
    STAssertTrue(hitNext, nil); 
} 
+0

Tôi cho rằng khi trong lần kiểm tra đầu tiên bạn gửi tên thông báo là “TEST” nghĩa là “TEST_FAILURE”, phải không? – yonosoytu

+0

Có. Đó là một lỗi trong bài kiểm tra của tôi. d'oh. – Jon

Trả lời

11

Bạn có thể làm điều này với các nhà khai thác built-in:

RACSignal *successNotification = [[NSNotificationCenter.defaultCenter 
    rac_addObserverForName:SuccessNotification object:nil] 
    take:1]; 

RACSignal *errorNotification = [[NSNotificationCenter.defaultCenter 
    rac_addObserverForName:FailureNotification object:nil] 
    flattenMap:^(NSNotification *notification) { 
     // Convert to a meaningful error somehow. 
     NSError *error = …; 

     return [RACSignal error:error]; 
    }]; 

RACSignal *signal = [RACSignal merge:@[ successNotification, errorNotification ]]; 

này sẽ chăm sóc của xử lý cho bạn, và nhiều hơn nữa rõ ràng là chỉ ra cách mỗi người trong số các thông báo được ánh xạ tới một giá trị hoặc một lỗi.

why doesn't @[errorNotification, completeNotification].rac_sequence.signal do the same thing as the signal of signal creation below?

Tín hiệu được tạo sẽ gửi giá trị không đồng bộ, không giống như tín hiệu bạn đã tạo trong ví dụ.

3

Something như thế này làm việc cho tôi trong cả hai trường hợp thành công và thất bại:

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { 
    RACDisposable *success = [[[[NSNotificationCenter defaultCenter] 
          rac_addObserverForName:@"TEST_SUCESS" object:nil] 
          take:1] 
          subscribeNext:^(id x) { 
           [subscriber sendNext:x]; 
          } completed:^{ 
           [subscriber sendCompleted]; 
          }]; 
    RACDisposable *failure = [[[[NSNotificationCenter defaultCenter] 
          rac_addObserverForName:@"TEST_FAILURE" object:nil] 
          take:1] 
          subscribeNext:^(id x) { 
          [subscriber sendError: 
           [NSError errorWithDomain:@"RAC_TEST" code:1 userInfo:nil]]; 
          }]; 
    return [RACDisposable disposableWithBlock:^{ 
    [success dispose]; 
    [failure dispose]; 
    }]; 
}]; 

tôi tạo ra một tín hiệu độc đáo với cả hai lần hiện. Các tín hiệu thành công gửi “tiếp theo” và “hoàn thành” (take:1 rất quan trọng để hoàn thành công việc). Tín hiệu lỗi gửi "lỗi". Ý tưởng được sử dụng subscriber được gửi vào khối để chuyển tiếp các sự kiện trong hai tín hiệu khác chính xác.

+0

Cảm ơn bạn đã trả lời ... Thay đổi duy nhất là tôi làm phẳng ánh xạ tín hiệu thông báo lỗi thành [RACSigna error:] thay vì đăng ký tiếp theo, tôi chỉ đăng ký lỗi và chuyển nó lên. – Jon

+0

Nhìn vào Justin trả lời cho câu hỏi này. Câu trả lời của anh không cần người đăng ký rõ ràng, điều này luôn tốt hơn. – yonosoytu

Các vấn đề liên quan