How To Choose the Best Backend Provider for your iOS App: Parse vs Stackmob vs. Appcelerator Cloud and More!
This is a post by Tutorial Team Member Antonio Martínez, a mobile software developer currently working as an iOS Developer in London. It’s quite common for apps to require a web backend. This allows you to have a central database where users can share content with each other, like photos, messages, or restaurant reviews. In […] By .
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How To Choose the Best Backend Provider for your iOS App: Parse vs Stackmob vs. Appcelerator Cloud and More!
35 mins
This is a post by Tutorial Team Member Antonio Martínez, a mobile software developer currently working as an iOS Developer in London.
It’s quite common for apps to require a web backend. This allows you to have a central database where users can share content with each other, like photos, messages, or restaurant reviews.
In the old days, you used to have to develop this all by yourself, using technologies such as Ruby on Rails or PHP (examples in this tutorial and this tutorial).
However, there are several challenges with this:
- Heavy Time Investment. It takes a huge amount of time to develop the front-end of the app already. Developing a back end just about doubles the work involved!
- Heavy Skill Investment. If you’re an experienced front-end iOS developer, it doesn’t mean you have a lot of skills developing back-ends. They’re completely different technologies, and it takes a lof of time to learn which you might not have.
- Scalability Issues. The nature of iOS apps and the App Store means you’ll never know whether your app will only have limited usage, or become a huge hit with millions of users. Developing your back-end so it scales efficiently with usage is quite a challenge!
Luckily, these days you no longer have to develop a back-end yourself! Several companies are now offering premade and highly configurable web backends that you can integrate into your app. These are known as Backend as a Service, or BaaS for short.
These services provide you with a package of backend storage and other functions that can be leveraged from your app, usually with a handy iOS library to make integration nice and easy. Most of them offer free accounts — with a surprisingly generous usage allowance — as well as priced tiers for apps that need to scale up.
The only problem is there are a great many BaaS providers out there! Which should you choose?
That is exactly what this article is for! :] I surveyed the major players in the BaaS market, chose my favorite three, and developed the same exact app in all three servies so you can compare them on an equal level. This will help you choose which one is best for your app!
What Does a Back-End Provider Do For You?
Before taking a look at the providers, let’s take a look at the common features that BaaS providers supply so you have a better understanding of what they can do for you.
For sake of discussion, let’s think about a hypothetical application where you store lists of sports players who belong to various teams. What support would you need from the back end?
- Custom objects: Arguably the most important feature of a back end is the ability to store your app’s information into a database. Typically you have model objects in your app that represent data (like a sports player object, and a sports team object), and relationships between the objects (like what team a player is in). BaaS providers typically give you an easy way to take this data from object format, and store/retrieve it from the central database.
- File storage: In addition to storing plain old data, sometimes you need to store files – such as images, large documents, and the like. In your hypothetical sports app, maybe you need to store a profile portrait for each player. Most backend services will provide file storage that you can use to associate a file with a custom object.
- Geolocation: In mobile apps, it’s often useful to be able to perform queries of objects near a certain location. For example, maybe you want to find the sports team in the area near the user’s phone. Backend services often provide the ability to tag your objects with a specific location so the user can make queries on objects based on location.
- Users: You’ll certainly need some sort of access control for your objects, and establish which object particular users have access to. Almost of all the BaaS offerings allow you to create your own users, and most of them users login via Facebook or Twitter so that the user doesn’t need to create a new account.
- Push notifications: What if you want to send a push notification when a sports game is about to start? BaaS offerings often provide the ability to send a push notification to all your users, or to a selective subset of your users.
Now that you better know what BaaS providers do, let’s take a closer look at the major players in the field!
Back in the Game: The Major Players in the Backend Service Market
Here are the major players in the BaaS market at the time of writing this article:
-
StackMob: Perhaps the most popular and customizable of all the current BaaS offerings. You can upload your own back end code and create your own web service, which is quite unique among the various backend service providers.
One disadvantage is that if you want to serve up binary assets, like the images mentioned above in your theoretical players app, you will need an Amazon S3 account. You can’t maintain binary assets directly in StackMob. Their free plan is one of the best in the market, it’s completely free for basic features and you can purchase new features in their MarketPlace -
Appcelerator Cloud Service: Without a doubt, this is the most complete of all BaaS in terms of features — and the free plan is really good. It’s clearly designed to work with the Titanium SDK, so the documentation is a little bit obscure and there are some hoops to jump through if you are not using Titanium.
On the other hand, they have a good Q&A webpage for any issues you may have, and response time on support issues seems reasonable. -
Parse: Has one of the best free plans out there. The documentation is the easiest to understand, and the service is one of the easiest to work with, especially for beginners.
Parse has sample projects that you can download, as well as custom UIViews that you can add to your project, such as Facebook and Twitter login views. Additionally, there is a large collection of 3rd party libraries offered for use with the service. While the free plans are very good, the price does seems to ramp up more quickly than other services if you exceed your free allocation. - Applicasa: Offers the same functionality as the others, but it offers a drag & drop functionality to create your own tables and custom objects. Once your data structure is designed to fit your needs, you can download the custom SDK adapted to work with your app. Applicasa charges based on active users. If you are a startup, they will give you a free account with up to 100,000 users per month if you contact them and ask them for it.
- Kinvey: Also a popular service which is based on active users. You can have 200 active users for free per month without going to a paid account, although its prices are a little bit higher compared to Applicasa. Its support service is very good, and they seem like a very promising BaaS provider.
For this article, I decided to pick three of these services and perform an in-depth comparison of them. Here’s the services I picked and why:
- Parse, based on its ease of use, good and clear documentation and free service;
- Appcelerator Cloud Service, based on the amount of features they offer; and
- StackMob, based on its popularity and ease of customization.
Keep reading to find out how I tested these out – and how you can compare them for yourself! :]
Introducing PhotoShare
To test out these three back end providers, I wanted to develop a simple but real-world application in each provider, and then compare and contrast to see the differences.
I decided to make an app called “PhotoShare”, similar in some ways to Instagram and other photo sharing apps. It has a login screen, then presents the user with a wall of images and comments. Every registered user can upload an image with a comment attached to it, and these images are publicly viewable.
In the first view, the user can Register as a new user, or Login if an account has already been created:
Once the user is logged, in the view proceeds to the list of images:
An Upload button in the navigation bar allows users to submit their own images and comments:
Next you’ll take a deeper look at Stackmob, Parse, and Appcelerator Cloud. For each provider, you’ll:
- Get an overview of the features, pricing, and documentation.
- Take a peek at how the code works.
- Learn how to get this PhotoShare sample project up and running on your own account.
Let’s start with Stackmob!
StackMob: How Does it Stack Up?
Features, Pricing, and Documentation
StackMob stands out from the other services as being extremely flexible, and provides the following features:
- Custom Objects
- Files (served through Amazon S3)
- Users
- FB/TW Integration
- Push Notifications
Update: Since writing this article, StackMob has revamped their pricing. Now most of the functionality is free, which is great! You have the option to purchase modules in their MarketPlace for additional advanced features.
You can find more info, and check what is included here:
StackMob Pricing
Well, those features are fairly impressive so far, and the documentation for StackMob is fairly complete. But ease of implementation when you’re coding is really where the rubber meets the road.
Take a look at the following code examples and see how common BaaS tasks are accomplished in StackMob!
Code Examples
The following code shows how to upload a simple object in StackMob. The example below follows on from the theoretical player application mentioned above:
NSManagedObject *newManagedObject = [NSEntityDescription
insertNewObjectForEntityForName:@"PlayerScore"
inManagedObjectContext:self.managedObjectContext];
[newManagedObject setValue:@"Player1" forKey:@"name"];
[newManagedObject setValue:[NSNumber numberWithInt:1000] forKey:@"score"];
[newManagedObject setValue:[newManagedObject sm_assignObjectId]
forKey:[newManagedObject sm_primaryKeyField]];
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
NSLog(@"Error: %@:", error);
}
else {
NSLog(@"Succesfully uploaded");
}
As you can see, uploading an Object using StackMob is a fairly simple process. Essentially, you create a ManagedObject with the object you wish to upload, and then simply make a call to upload it to the BaaS .
Does this look familiar? It should — StackMob backend storage functions are provided through extending Core Data’s mechanisms. Isn’t that terribly nice of them? :]
Now move on to the following sample code, which shows how to retrieve objects from StackMob:
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"PlayerScore"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
//Greater than 900
NSPredicate *greaterThanPredicate =[NSPredicate predicateWithFormat:@"score > %d", 900];
[fetchRequest setPredicate:greaterThanPredicate];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil
cacheName:@"Master"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"An error %@, %@", error, [error userInfo]);
}
return _fetchedResultsController;
}
// You can get the objects calling self.fetchedResultsController
This uses a standard NSFetchedResultsController to retrieve a list of objects – for more information, check out this tutorial.
Deleting objects using StackMob is probably the simplest action of them all:
[self.managedObjectContext deleteObject:aManagedObject];
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
NSLog(@"There was an error! %@", error);
}
else {
NSLog(@"You deleted an object!");
}
Pretty simple, isn’t it; there’s more lines of error handling code than there are lines to delete the object in question! :]
As you can see from the examples above, the process of uploading, querying, and deleting objects is fairly simple and adapted to work with iOS using the SDK that they provide. It’s apparent that an existing project using Core Data could be easily adapted to make use of the StackMob backend.
The image below shows how the StackMob web interface for the object browser will appear after uploading an object:
Common operations such as delete or query are available through the web interface as well. This is useful for managing objects in a manual fashion, such as setting up persistent data for your app.
Creating a Account
Before you can run the Stackmob implementation of PhotoShare, you’ll need your own StackMob account and you’ll need to configure a database for the app. This section will show you how.
If you have not already created a StackMob account, go ahead and follow the directions found at StackMob: Get Started. Signing up is easy, and you are not required to submit any information other than your email address and password. Right away, you’ll receive a welcome email and the usual “verify your account” link.
It’s a bit counter-intuitive, but when creating a new app on StackMob, make sure to choose your platform first, before you enter the app name. The downloadable tutorial examples use “tutorialstackmob” — all lower case — as the app name.
You can skip downloading the SDK — for the purposes of this tutorial, the SDK is provided in the example app, along with the necessary frameworks.
Once you’ve verified your StackMob account, you’ll now need to get an Amazon S3 account setup to store your binary assets. To do this, sign up here.
Don’t be daunted by the Amazon Web Services signup process. You do need a credit card, but there is no signup fee, and if you read the service agreement carefully, you’ll find that you will only ever be charged for data or service usage that exceeds what the free S3 tier offers.
The captcha for the account creation is a bit tricky, and you’ll also need to enter a specific PIN on an automated phone call — but at least you know you’re using a service with security! :] At the end of the process, the result is an access key, required to link your new S3 account to your StackMob account.
In order to get your S3 buckets and access setup, you’ll need to follow the two sections titled “Setup an Amazon S3 bucket” and “Add S3 settings to your StackMob application” in this tutorial. Don’t worry about the section marked “Add a Binary Field” — you’ll do that below.
Now you need to create the schemas of the objects you are going to use in your app!
Go to Manage Schemas and create a new schema called “wallobject”. Add two new fields; one field called “comment” with String type, and another one called “photo” with Binary type, as shown in the screenshot below:
You may be prompted to set permissions before you can save your new schema. If so, “Logged In Permissions -> Allow to any logged in user” is fine for all operations. Now, save your schema!
Running the Sample Project
Now you can try out the app! Go ahead and download it from github.
Note: If you have not used github before, grabbing the sample application code is as simple as navigating to the folder where you would like it to appear using terminal, and then using “git clone https://github.com/toniomg/TutorialStackMobBaaS”.
Open the project in Xcode. If you run the project immediately, you’ll encounter an exception: “‘Incorrect Public Key format provided. Please check your public key to make sure you are passing the correct one, and that you are not passing nil.”
There’s one little piece missing to link your app to StackMob: your public key! In the StackMob Dashboard of your app, find the link to “Manage App Info”. Copy your public key to the project in the Delegate (look for a field called PUBLIC_KEY). The bit of code you’ll need to update will look like this:
#define PUBLIC_KEY @"123456-7890"
Build and run your app! If you receive an error saying that the schema doesn’t exist, try waiting for a minute and trying again — it may take a moment for the backend service to make your schema available to the outside world. However, if you still encounter difficulties, try re-creating the schema just to be sure that it has been properly created.
Congrats – you now have a working example project with StackMob! You can compare this to the other two projects yourself – or keep reading for our own thoughts and conclusions.
Parse: Persistent Points
Features, Pricing, and Documentation
Parse stands out for being one of the the easiest and fastest backend services to work with, as well as having the best documentation. The documentation is easy to understand, as well as being comprehensive. Generally, it will take you less time to start uploading objects to Parse than any other service.
Parse offers most of the features that you’d expect from a backend service provider, including the following:
- Custom Objects
- Users
- Push Notifications
- Social Integration
- Files
- Geolocation
The pricing of the tiers in Parse is again based on API calls, and has a much bigger jump to the paid tier than does StackMob:
- Free: 1M API Calls, 1M Push notifications (0.07 per 1k over)
- $199: 15M API Calls, 15M Push notifications (0.05 per 1k over)
Code Examples
The following code sample shows you how to upload a new object in Parse, again using the mythical Player application:
PFObject *player = [PFObject objectWithClassName:@"Player"];
[player setObject:@"Player1" forKey:@"Name"];
[player setObject:[NSNumber numberWithInt:1000] forKey:@"Score"];
[player saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded){
NSLog(@"Object Uploaded!");
}
else{
NSString *errorString = [[error userInfo] objectForKey:@"error"];
NSLog(@"Error: %@", errorString);
}
}];
Relatively simple, and along the same lines as StackMob. With Parse, the process of uploading the object to the server can be done in synchronous mode or asynchronous using a block or a selector.
The code to retrieve an object in Parse is again incredibly straightforward, and in half the lines of code that StackMob requires:
PFQuery *query = [PFQuery queryWithClassName:@"Player"];
[query whereKey:@"Score" greaterThan:[NSNumber numberWithInt:900]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(@"Successfully retrieved: %@", objects);
} else {
NSString *errorString = [[error userInfo] objectForKey:@"error"];
NSLog(@"Error: %@", errorString);
}
}];
Deleting an object in Parse is again a very simple operation:
PFObject *player = [PFObject objectWithClassName:@"Player"];
[player setObject:@"Player1" forKey:@"Name"];
[player deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error){
if (!error) {
NSLog(@"Successfully deleted");
} else {
NSString *errorString = [[error userInfo] objectForKey:@"error"];
NSLog(@"Error: %@", errorString);
}
}];
This is how the web interface for the Parse object browser looks after uploading an object:
Running the Sample Project
I’m not going to include instructions on how to set up Parse here, since I am going to release a step-by-step tutorial on how to build this project from scratch in a few days!
So stay tuned for our upcoming tutorial. In the meantime, you can get a sneak peek by downloading the completed project from github.
Appcelerator: Accelerating App Access
Features, Pricing, and Documentation
Appcelerator Cloud Services stands out for being the most comprehensive backend service provider of all. Appcelerator Cloud is geared towards developers using the Titanium SDK, so your experience may vary if you are not using Titanium. However, a quick read through the documentation and main concepts of Appcelerator Cloud will get you up and running quickly.
Appcelerator Cloud Services are a bit different in that they break the various features into two tiers. The two-tiered model bundles most of the common features into the first tier, and puts more of the value-added services into the second tier, as shown:
Tier 1:
- Users
- Photos
- Custom Objects
- Push notifications
- Email Templates
Tier 2:
- Places
- Status
- Posts
- Clients
- Social Integration
- Check-ins
- Chat
- Photo Collections
- Ratings, Reviews & Likes
As you can see, there is a more comprehensive range of predefined functionality with Appcelerator Cloud Services.
Pricing for the various services with Appcelerator is as follows:
- Free: 250k Tier 1 API Calls, 250k Tier 2 API Calls
- Paid: Pricing for the Standard, Enhanced, and Premium paid tiers is not made public on the Appcelerator web site; before committing to using ACS in your app, you should contact the sales team and be sure of what your ongoing costs will be!
Code Examples
Uploading an object in Appcelerator Cloud Services is again very easy and comparable to Parse and StackMob. You’re still working with our hypothetical Players app here:
NSMutableDictionary *fieldsDict = [NSMutableDictionary dictionaryWithCapacity:2];
[fieldsDict setObject:@"Player1" forKey:@"name"];
[fieldsDict setObject:[NSNumber numberWithInt:1000] forKey:@"score"];
NSDictionary *paramDict = [NSDictionary dictionaryWithObject:fieldsDict forKey:@"fields"];
CCRequest *request = [[[CCRequest alloc] initWithDelegate:self httpMethod:@"POST"
baseUrl:@"objects/playerscore/create.json" paramDict:paramDict] autorelease];
[request startAsynchronous];
Retrieving objects in Appcelerator is again extremely straightforward:
CCWhere *where = [[[CCWhere alloc] init] autorelease];
[where fieldName:@"score" greaterThan:[NSNumber numberWithInt:900]];
NSMutableDictionary *paramDict = [NSDictionary dictionaryWithObjectsAndKeys:where,@"where", nil];
CCRequest *request = [[CCRequest alloc] initWithDelegate:self httpMethod:@"GET"
baseUrl:@"objects/playerscore/query.json" paramDict:paramDict];
[request startAsynchronous];
Deleting objects in Appcelerator is, once again, a simple operation:
NSDictionary *paramDict = [NSDictionary dictionaryWithObject:@"5049c26fb685537c3902c711"
forKey:@"id"];
CCRequest *request = [[[CCRequest alloc] initHttpsWithDelegate:self httpMethod:@"DELETE"
baseUrl:@"objects/playerscore/delete.json" paramDict:paramDict] autorelease];
[request startAsynchronous];
To check the response from the server for any of these calls you must use a delegate; this should be a very familiar pattern to any iOS developer, as blocks are becoming more commonly used for network operations. A single delegate function is used for all of the create, retrieve, and delete operations:
-(void)ccrequest:(CCRequest *)request didSucceed:(CCResponse *)response
{
if ([response.meta.methodName isEqualToString:@"createObject"]){
NSLog(@"Object created");
}
if ([response.meta.methodName isEqualToString:@"queryCustomObjects"]){
NSLog(@"%@", [response.response objectForKey:@"playerscore"]);
}
if ([response.meta.methodName isEqualToString:@"deleteObjects"]){
NSLog(@"Deleted");
}
}
Unlike Parse and Stackmob, in Appcelerator you must be the owner of an object in order to modify or delete it. To delete an object, you must provide the object’s unique ID, which can be discovered with an API call.
In contrast, in Stackmob and Parse you can simply provide enough information to identify the objects you want to perform operations on without first having to make an API call to retrieve the unique ID.
This is how the web interface for the Appcelerator object browser looks after uploading an object:
Running the Sample Project
Once again the sample project for working with Appcelerator is complete, but it is not configured with your project credentials.
Create your developer account with Appcelerator by signing up here. Once again, you don’t need to download the SDK for appcelerator, since it is included with the sample project.
Once you have created your account, go to Create New App in Appcelerator and create a new app called “tutorialacs”.
The final step is to add your App Key to the AppDelegate. You can find your Appcelerator App Key by navigating to the “Manage ACS” screen once your app has been created.
Update the code below with the App Key you retrieved from Appcelerator:
//Put your key here
#define COCOAFISH_APP_KEY @"1234-5678"
And you’re done! Just like the sample application that was provided that leveraged the StackMob service, now you can upload and view images and comments in your app.
Which to Choose?
Now that you seen some popular BaaS offerings and had a chance to test how they work, it is time to evaluate each service and choose the right one for your needs.
All three of these are great options, and there’s no single right answer for everyone – you will have to make your own decision based on what you need for your app. The following points will help you consider which backend service provider is right for you:
- The most important factor here is to evaluate each service’s features and their usefulness to you — and your app! Preconfigured objects might seem attractive, unless your idea of what those objects should be differs from those of the service provider.
- Services that offer just “users” along with general purpose objects might initially seem more difficult, until you see that substantial flexibility comes with the user-based approach.
- Will you need a support agreement; and should you be paying for phone support? How accessible are the engineers if you need them, and what kind of user community support can you expect?
- Take a close look at the documentation. This is one time you should read it thoroughly, even though the sample projects have given you enough to get started! :] The quality, coverage and currency of the documentation will give you a good idea of how committed each company is to your success.
- Make yourself aware of the costs you will incur in using the service. This will require you to project your future usage for best case and worst case scenarios. Should you find yourself with 100 million users, will your app generate enough income to pay for the level of service you will require?
- If your app is going to require a paid plan from the start but it flops, can you afford that? Some services require you to contact sales before you know what these costs will be; don’t skip this step!
- Doing a search for the name of your service on discussion boards might expose interesting bits of information you might not have found otherwise. If you get no hits at all, how popular is the service — and what are the chances it will be around in six months? If all the hits say “it’s awesome” that might be a good indication – but pay attention to the negative comments as well!
Once you have answered all of these questions and written some proof of concept code, your use of the service itself will probably be enough for you to make a final decision.
TLDR? If you just want us to make a decision for you, we recommend Parse. Parse is incredibly easy to get started with, and for that reason Parse was chosen for the second part of this tutorial because it passes all of the tests with flying colors :]
Where To Go From Here?
Again, here is the sample project I’ve made for you with all three providers:
I hope this article was useful to you to point out some of the options out there, and give you an “apples to apples” example to help you to choose between the different providers.
If you have any questions or comments on this article, or recommendations or thoughts on various backend providers, please join the forum discussion below!
This is a post by Tutorial Team Member Antonio Martínez, a mobile software developer currently working as an iOS Developer in London.