将RAC命令与异步网络操作一起使用

Ash*_*row 7 objective-c ios reactive-cocoa raccommand

我正在使用UAGitHubEngineGitHub的API.我想写一个功能性的被动应用程序来获取一些数据.我依靠这里的代码来设置异步网络请求.我正在寻找的是一些名为"General"的团队的团队ID.我可以做过滤/打印部分OK:

[[self.gitHubSignal filter:^BOOL(NSDictionary *team) {
    NSString *teamName = [team valueForKey:@"name"];
    return [teamName isEqualToString:@"General"];
}] subscribeNext:^(NSDictionary *team) {

    NSInteger teamID = [[team valueForKey:@"id"] intValue];

    NSLog(@"Team ID: %lu", teamID);
}];
Run Code Online (Sandbox Code Playgroud)

但是设置命令对我来说是一个谜:

self.gitHubCommand = [RACCommand command];

self.gitHubSignal = [self.gitHubCommand addSignalBlock:^RACSignal *(id value) {
    RACSignal *signal = ???

    return signal;
}];
Run Code Online (Sandbox Code Playgroud)

当某些异步网络调用返回时,如何设置信号块以返回推送事件的信号?

Ash*_*row 4

答案就在 中RACReplaySubjectAFNetworking 使用它来包装其异步请求。

self.gitHubCommand = [RACCommand command];

self.gitHubSignals = [self.gitHubCommand addSignalBlock:^RACSignal *(id value) {
    RACReplaySubject *subject = [RACReplaySubject subject];

    [engine teamsInOrganization:kOrganizationName withSuccess:^(id result) {

        for (NSDictionary *team in result)
        {
            [subject sendNext:team];
        }

        [subject sendCompleted];            
    } failure:^(NSError *error) {
        [subject sendError:error];
    }];

    return subject;
}];
Run Code Online (Sandbox Code Playgroud)

由于addSignalBlock:返回信号的信号,我们需要订阅它发出的下一个信号。

[self.gitHubSignals subscribeNext:^(id signal) {
    [signal subscribeNext:^(NSDictionary *team) {
        NSInteger teamID = [[team valueForKey:@"id"] intValue];

        NSLog(@"Team ID: %lu", teamID);
    }];
}];
Run Code Online (Sandbox Code Playgroud)

最后,addSignalBlock:在执行命令之前该块不会执行,我通过以下方式进行管理:

[self.gitHubCommand execute:[NSNull null]];
Run Code Online (Sandbox Code Playgroud)