简体   繁体   中英

RACSignal from rac_sequance is not delivering signals correctly

I am playing with code from some book regarding Reactive Cocoa and I am stuck with this one: Here is my photo importer code :

+ (RACSignal *)importPhotos {
    NSURLRequest *request = [self popularURLRequest];

    return [[[[[[NSURLConnection rac_sendAsynchronousRequest:request] map:^id(RACTuple *value) {
        return [value second];
    }] deliverOn:[RACScheduler mainThreadScheduler]]
            map:^id(NSData *value) {
                id result = [NSJSONSerialization JSONObjectWithData:value
                                                            options:0
                                                              error:nil];
                return [[[result[@"photos"] rac_sequence] map:^id(NSDictionary *photoDictionary) {
                    FRPPhotoModel *photoModel = [FRPPhotoModel new];
                    [self configurePhotoModel:photoModel withDict:photoDictionary];
                    [self downloadThumbnailForPhotoModel:photoModel];

                    return photoModel;

                }] array];

            }] publish] autoconnect];
}

+ (void)configurePhotoModel:(FRPPhotoModel *)photoModel withDict:(NSDictionary *)dict {
    photoModel.photoName = dict[@"name"];
    photoModel.identifier = dict[@"id"];
    photoModel.photographerName = dict[@"user"][@"username"];
    photoModel.rating = dict[@"rating"];
    [[self urlForImageSize:3 inArray:dict[@"images"]] subscribeNext:^(id x) {
        photoModel.thumbnailURL = x;
    }];
 }

+ (RACSignal *)urlForImageSize:(NSInteger)size inArray:(NSArray *)array {
    return [[[[array rac_sequence] filter:^BOOL(NSDictionary *value) {
        return [value[@"size"] integerValue] == size;
    }] map:^id(NSDictionary *value) {
        return value[@"url"];
    }] signal];
}

+ (void)downloadThumbnailForPhotoModel:(FRPPhotoModel *)photoModel {
        [[RACObserve(photoModel, thumbnailURL) flattenMap:^RACStream *(id value) {
            return [self download:value];
        }] subscribeNext:^(id x) {
            photoModel.thumbnailData = x;
        }];
}
+ (RACSignal *)download:(NSString *)urlString {
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];

    return [[NSURLConnection rac_sendAsynchronousRequest:request] map:^id(RACTuple *value) {
        return [value second];
    }];
}

and UI is updated like this:

RAC(self.imageView, image) = [[RACObserve(self, photoModel.thumbnailData) filter:^BOOL(id value) {
    return value != nil;
}] map:^id(id value) {
    return [UIImage imageWithData:value];
}];

Can you please explain why my UI is not updated or updated wrongly with new UIImages which I get from that NSData objects.

So the first problem was that flattenMap delivers on some background RACScheduler. Changed to this:

[[[[RACObserve(photoModel, thumbnailURL) ignore:nil] flattenMap:^RACStream *(id value) {
    return [self download:value];
}] deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) {
    photoModel.thumbnailData = x;
}];

Also another problem was that download:nil was throwing an error, which was not caught by subscriber and thus terminated signal which provided values of observing. Adding ignore:nil fixed issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM