How to Add Caching to Cloud Functions in Parse

cloud

Parse is a popular backend-as-a-service (BaaS) that essentially gives developers a virtual database and app server in the cloud. You can create a “cloud code endpoint” with a unique name that accepts any number of parameters. This endpoint can then be invoked by the mobile SDK, and a response returned. This response can consist of any number of data objects. For standard database queries, this SDK comes with an additional powerful feature: client-side caching. However, the Parse mobile SDK does not provide caching functionality for cloud functions.

Caching is critical to making your mobile app feel faster and more responsive. Instead of forcing the user to wait for a network response, caching allows your app to serve up a slightly older copy of your data immediately, and then refresh it at a more convenient/less obtrusive time. The Parse team probably didn’t include this because they assumed that cloud functions only have value when invoked real-time. However, there are many cases when caching cloud functions would be appropriate. Plus developers don’t like to be limited!

I encountered this very roadblock when working on the iOS app for UpdateZen, so I created an open-source library called PFCloud+Cache. This category on PFCloud adds an additional cachePolicy parameter to Parse’s existing asynchronous (background) cloud function call methods. It replicates the existing caching behavior available on the PFQuery class: it lets you specify when the cached should expire, and select one of several caching policies to use.

+ (void)callFunctionInBackground:(NSString*)function
                  withParameters:(NSDictionary*)parameters
                     cachePolicy:(PFCachePolicy)cachePolicy
                           block:(PFIdResultBlock)block;

+ (void)callFunctionInBackground:(NSString*)function
                  withParameters:(NSDictionary*)parameters
                     cachePolicy:(PFCachePolicy)cachePolicy
                          target:(id)target
                        selector:(SEL)selector;

Sample Usage

Using this category is super easy and behaves just like the standard Parse methods — only with an additional cachePolicy parameter:

#import "PFCloud+Cache.h"

[PFCloud callFunctionInBackground:function
                   withParameters:params
                      cachePolicy:kPFCachePolicyCacheThenNetwork
                            block:^(id object, NSError* error) {
    //Because we are using kPFCachePolicyCacheThenNetwork as our cache policy,
    //this block will be invoked twice (if a cached result exists).
}];

Cache Management

Cached objects are persisted to disk in the following folder on the user’s device:

~/Library/Caches/com.tumblr.TMDiskCache/TMDiskCacheShared/

Cached objects persist between app restarts until they expire. By default they never expire. To impose a maximum cache age use the setMaxCacheAge: method. The cache can also be explicity cleared for a particular cloud function call using the clearCachedResult: method, or for all calls using the clearAllCachedResults method.

How it Works

This library creates a record in the cache for every unique combination of function name + parameters. For it to work, the contents of the parameters dictionary must conform to the NSCoding protocol. The trick is to create a unique key in the cache for every unique function call, so this library concatenates the function name with a JSON-serialized string of the parameters dictionary. It then takes an MD5 hash of this string using the RSCategories library to create a unique key in the cache. Actual caching is performed using Tumblr’s TMCache library. Thanks to those libraries for their great work!

Installation

The recommended way is by using CocoaPods to resolve all dependencies:

pod 'PFCloud+Cache', '~> 0.0.1'

Otherwise you must manually copy the .h and .m files from this repo as well as from RSCategories and TMCache. Obviously you must also have the Parse SDK installed. Enjoy!

Advertisements

About Martin Rybak

I am a New York area software developer and MBA with 10+ years of server-side experience on the Microsoft stack. I've also been a native iOS developer since before the days of ARC. I architect and develop full-stack web applications, iOS apps, database systems, and backend services.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: