New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about cache - network data gathering #1166

Closed
bolismauro opened this Issue Mar 11, 2014 · 4 comments

Comments

Projects
None yet
3 participants
@bolismauro

bolismauro commented Mar 11, 2014

Hi everyone,
i'm new to reactivecocoa but it seems a really interesting library so i decide to use it in my new application.
Here is my question: i have some pieces of information that are gathered from a remote web service. Every time the application starts i have to check if there are new information. It the version of the online information is different than the local one i have to download them, otherwise i can use the local cached.
At the end i have to populate a table.

I don't understand how to conditionally execute a method (ie: check version -> if needed download info from remote web service and save them -> gather local info -> populate UI).

It is also possible to execute this flow every X seconds?

Thank you

@joshaber

This comment has been minimized.

Show comment
Hide comment
@joshaber

joshaber Mar 12, 2014

Member

Here's a theoretical example. Hopefully it gives you a sense of the shape of the code you'd need to write.

- (RACSignal *)loadData {
    return [[RACSignal 
        createSignal:^(id<RACSubscriber> subscriber) {
            // If the cache is valid then we can just immediately send the 
            // cached data and be done.
            if (self.cacheValid) {
                [subscriber sendNext:self.cachedData];
                [subscriber sendCompleted];
            } else {
                [subscriber sendError:self.staleCacheError];
            }
        }] 
        // Do the subscription work on some random scheduler, off the main 
        // thread.
        subscribeOn:[RACScheduler scheduler]];
}

- (void)update {
    [[[[self 
        loadData]
        // Catch the error from -loadData. It means our cache is stale. Update
        // our cache and save it.
        catch:^(NSError *error) {
            return [[self updateCachedData] doNext:^(id data) {
                [self cacheData:data];
            }];
        }] 
        // Our work up until now has been on a background scheduler. Get our 
        // results delivered on the main thread so we can do UI work.
        deliverOn:RACScheduler.mainThreadScheduler]
        subscribeNext:^(id data) {
            // Update your UI based on `data`.

            // Update again after `updateInterval` seconds have passed.
            [[RACSignal interval:updateInterval] take:1] subscribeNext:^(id _) {
                [self update];
            }];
        }]; 
}

Let me know if you have specific questions, or need me to explain some part of that.

Member

joshaber commented Mar 12, 2014

Here's a theoretical example. Hopefully it gives you a sense of the shape of the code you'd need to write.

- (RACSignal *)loadData {
    return [[RACSignal 
        createSignal:^(id<RACSubscriber> subscriber) {
            // If the cache is valid then we can just immediately send the 
            // cached data and be done.
            if (self.cacheValid) {
                [subscriber sendNext:self.cachedData];
                [subscriber sendCompleted];
            } else {
                [subscriber sendError:self.staleCacheError];
            }
        }] 
        // Do the subscription work on some random scheduler, off the main 
        // thread.
        subscribeOn:[RACScheduler scheduler]];
}

- (void)update {
    [[[[self 
        loadData]
        // Catch the error from -loadData. It means our cache is stale. Update
        // our cache and save it.
        catch:^(NSError *error) {
            return [[self updateCachedData] doNext:^(id data) {
                [self cacheData:data];
            }];
        }] 
        // Our work up until now has been on a background scheduler. Get our 
        // results delivered on the main thread so we can do UI work.
        deliverOn:RACScheduler.mainThreadScheduler]
        subscribeNext:^(id data) {
            // Update your UI based on `data`.

            // Update again after `updateInterval` seconds have passed.
            [[RACSignal interval:updateInterval] take:1] subscribeNext:^(id _) {
                [self update];
            }];
        }]; 
}

Let me know if you have specific questions, or need me to explain some part of that.

@bolismauro

This comment has been minimized.

Show comment
Hide comment
@bolismauro

bolismauro Mar 12, 2014

Just the last question. If i want to tigger this every X seconds i have to create the signal in loadData with [RACSignal interval:X]
right?
Thank you for your help!

bolismauro commented Mar 12, 2014

Just the last question. If i want to tigger this every X seconds i have to create the signal in loadData with [RACSignal interval:X]
right?
Thank you for your help!

@joshaber

This comment has been minimized.

Show comment
Hide comment
@joshaber

joshaber Mar 12, 2014

Member

Sure, that's one way to do it. As it is above, -update would get called every X seconds, which would also call -loadData.

Member

joshaber commented Mar 12, 2014

Sure, that's one way to do it. As it is above, -update would get called every X seconds, which would also call -loadData.

@bolismauro

This comment has been minimized.

Show comment
Hide comment
@bolismauro

bolismauro Mar 12, 2014

Good, thank you very much!

bolismauro commented Mar 12, 2014

Good, thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment