How to Start Building a Backend for Your iOS App Without Relying on Parse or Firebase
You need a backend for your iOS app. With Parse closing shop, what to do now? Find a Parse replacement or build your own backend? Find out what Moe Burney decided to do.
Join the DZone community and get the full member experience.
Join For FreeYou need a backend for your iOS app. With Parse closing shop, what to do now? Find a Parse replacement or build your own backend?
I am firmly in the “learn to build your own” backend camp.
Many developers advise not to build your own backend. After a BaaS shuts down, those developers scramble to find the next replacement BaaS. And then they’ll try to convince you to use a replacement BaaS too. But we all know the inevitable will happen all over again. One day you’ll get a surprise email from your BaaS provider informing you that they’re shutting down right in the middle of your new app version launch.
I remember the time that it happened to me — a BaaS that I relied on shut down. When I first saw the shut down email, I felt used. I felt betrayed. Then I felt angry. And as I fell into a downward spiral, I isolated myself. I binged on ice cream and listened to Celine Dion while sobbing in the shower. I should have seen it coming, but I got seduced by the illusion of convenience and stability that the service provided. But that’s all it was — an illusion.
So why do fly-by-night BaaS providers keep coming up and doing this to all of us poor mobile developers?
The Idea of Building Your Own Backend Can Seem Overwhelming.
Learning everything about building backends is a lot of work. This is why BaaS seems like a good option at first.
But if you want to break free of BaaS dependence and build your own backends instead, here’s the trick: don’t try to learn everything about backends! Start small.
When you built your first iOS “app”, you probably weren’t focused on making it scalable and maintainable. You didn’t stress out too much the first time those UITableview cells got recycled and showed the wrong data. You probably didn’t worry about whether your app should follow MVC or MVVM or MMVCM (I made that last one up). I’m willing to bet your first app probably never even made it past the simulator.
I recommend the same approach to building a backend: start small. Get something working first, no matter how small. And then build on that.
The Backwards Backend Method
You don’t need to bury yourself in books about Python or Ruby and learn everything about servers before you can get a backend up and running. Designing the entire API, deploying it, and scaling — all those things can come later.
Do this first:
Write a Single iOS Function That Will Make a Call to Your Backend, Even Before You Build the Backend
Here’s an example. Suppose you decide that your first function will make an API call that retrieves the messages of a particular user.
The following function, written in Swift, makes a POST request to ‘/get_messages’ on a local server that doesn’t exist yet (but will soon). Let’s look at the code for this function:
func printMessagesForUser() -> Void {
let json = ["user":"larry"]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted)
let url = NSURL(string: "http://127.0.0.1:5000/api/get_messages")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = jsonData
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data, response, error in
if error != nil{
print("Error -> \(error)")
return
}
do {
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) as? [String:AnyObject]
print("Result -> \(result)")
} catch {
print("Error -> \(error)")
}
}
task.resume()
} catch {
print(error)
}
}
This code makes a POST request to “http://127.0.0.1:5000/api/get_messages” with the username “larry”. Of course, if we run this code now it won’t work, because we haven’t created the endpoint “http://127.0.0.1:5000/api/get_messages” yet. That’s what we’ll do next.
Install Flask (and Python If You Don’t Already Have It)
Check out the Python and Flask docs.
Write the Backend Function
Now, we have to create the get_messages endpoint for our iOS function to call. Here’s how it looks in the default Flask file, app.py:
@app.route('/api/get_messages', methods = ['POST'])
def get_messages():
json = request.get_json()
if json['user'] == "larry":
return jsonify({'messages':['test1', 'test2']})
return jsonify({'error':'no user found'})
This Python/Flask stub function is as simple as it gets. The @app.route decorator at the top specifies that the function should correspond to the ‘get_messages’ endpoint and that it should be a POST request. The body of the ‘get_messages’ function checks inside request.get_json(), a Flask function that returns a dictionary containing the values that were sent in the POST request. If the messages for the username ‘larry’ was requested for the ‘user’ parameter, then our function sends the client a JSON object dictionary that contains an array of strings “test1” and “test2”.
The get_messages function returns hardcoded JSON, but later on you can connect it to a real database. Before that, run the Flask server and the iOS client to see if your first building block for your backend is working. We’ll do that next.
Run the Local Server
We make sure app.py has the following:
if __name__ == '__main__':
app.run(debug = True)
Now you can run the app.py to start up the Flask server:
Python app.py
This starts the Flask server hosted on your localhost with the default port of 5000.
Call the Function From Your App
Actually seeing your backend API returning something will give you the motivation to keep going forward with your backend building adventures.
Run the “getMessages” Swift function that you wrote in the beginning — just stick it in your main view controller or app delegate, and re-factor later. Also, make sure you add this to your info.plist so that you can disable iOS transport security requirements in your development phase:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Once you get the array {“test1”, “test2”} printed out on the console, you know that you’ve successfully called your own backend. If you’re not getting the output, tweak things up until you do.
If you’ve got this far, congratulations. With a bit more “filling in the gaps” (learning some more Python, plugging in an ORM for database queries), you now can write a backend without needing Parse or any BaaS service of any kind.
Is this oversimplified? Yes, what we just wrote is not a finished backend. Proper API design, database design, server maintenance, and scalability are all concerns that you will have to address as you continue your journey. But if you start backward like this, you’ve got a foundation, and you’ve got control over your own system. And having that control is much better than being dependent on yet another third party provider that may pull the plug on you at any minute.
You can create powerful backend APIs without needing a third party service. Click here to get the book on building backends for iOS apps.
Published at DZone with permission of Moe Burney, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments