Eli Perkins
Eli Perkins

Reputation: 68

RACCommand initializer signal doesn't hit executingSignals

I've been working on an MVVM example, using ReactiveCocoa that is a simple collection of App.net posts in a collection view which loads more posts before hitting the edge of the collection view.

I'm having an issue, however, with a command on my view model. I've created a command that loads posts via an AFNetworking client, and responds back after they've been modeled. When it completes, it sends the response to the signal that the command that was created with, and completes the signal.

self.loadPostsCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [[EPHTTPClient sharedClient] getGlobalTimelinePostsWithSuccess:^(NSURLSessionDataTask *task, id responseObject) {
            [self.posts addObjectsFromArray:responseObject];
            [subscriber sendNext:responseObject];
            [subscriber sendCompleted];
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            [subscriber sendError:error];
        }];

        return nil;
    }];
}];

In my view, I create a signal to send the remaining post count over as such.

@weakify(self);

RACSignal *postsRemainingSignal = [[RACObserve(self.collectionView, contentOffset) map:^(id value) {
    // The value returned from the signal will be an NSValue
    CGPoint offset = [value CGPointValue];
    NSNumber *postsPassed = @(floorf(offset.x/320) + 1);

    return @([self.postQueue.posts count] - [postsPassed integerValue]);
}] distinctUntilChanged];

I send these values to a subject on my view model.

// Send the values of the posts to the view model
[postsRemainingSignal subscribeNext:^(id x) {
    [self.postQueue.postsRemainingSubject sendNext:x];
}];

// When the load command is executed, update our view accordingly
[self.postQueue.loadPostsCommand.executionSignals subscribeNext:^(RACSignal *loadSignal) {
    [loadSignal subscribeCompleted:^{
        @strongify(self);
        [self.collectionView reloadData];
    }];
}];

The subject in the view model is instantiated as such:

// Create a subject to send view values to
self.postsRemainingSubject = [RACSubject subject];

// Load more posts when less than 4 posts remain
[self.postsRemainingSubject subscribeNext:^(id x) {
    if ([x integerValue] < 4) {
        [self.loadPostsCommand execute:nil];
    }
}];

Everything works as expected, except for sending values and completion to my command's signal. The network request happens, my posts are modeled, however, the view never receives any values on the self.postQueue.loadPostsCommand.executionSignals signal.

Again, my project is on GitHub in the branch reload-signal-rework. Any thoughts?

Upvotes: 4

Views: 727

Answers (1)

Dave Lee
Dave Lee

Reputation: 6489

The problem is that you're subscribing to executionSignals after sending to postsRemainingSubject (which is what ultimately causes the -execute: to be called).

If you move your subscription to executionSignals above the block that sends on postsRemainingSubject, then you'll see subscription block get called.

Upvotes: 5

Related Questions