Start using Swift with Parse.com

Unfortunately Parse is closing down in 2017, but we have found a great and actually local (to us) service: AppStax.

We decided to develop an iOS app to interface with #lillygram. #lillygram uses the popular «Backend-as-a-Service» Parse.com. Here’s a quick overview of how to get started using Swift with Parse.com, based on our experiences so far.

Other useful resources:

We assume that you have already imported the Parse.com iOS framework into Xcode or that you are using CocoaPods. This procedure does not differ from how you would do it with Objective-C, so we don’t include an explanation for it here.

To make the Parse headers available in Swift code, you have to provide a special header file. The header file bridges the framework into the Swift universe.

Create a new header file in Xcode (Xcode -> New file -> Header file) and name it
<project-name>-Bridging-Header.h. It’s important that <project-name> matches the actual name of the project.

Add the import statements for the Parse.com framework like this:

I have added the subclassing category to allow for subclassing parse objects, and the Bolts framework to demonstrate more elegant async handling with Parse.

Now you have the Parse.com SDK available to you in Swift. Start by initializing parse with your app id and client key.

Next, I have made a class, Letter, by subclassing PFObject. In Swift that’s really easy. This is enough to get started:

The sequence class Letter : PFObject, PFSubclassing means «create a class called Letter, which is a subclass of PFObject and which conforms to the PFSubclassing protocol.» Whereas in Objective-C you would put protocols in brackets like <PFSubclassing>, in Swift, the comma-separated list of protocols is simply appended after the superclass (if any).

The only method you are required to implement is the class method parseClassName(). You also need to override the load method, in order to call Parse’s special class method registerSubclass().

Setters and Getters

Here is an example of two public getters I have in my Letter class, that correspond to two properties in my data model in Parse:

Here is an example of a setter/getter pair that I have decided should be private. This property also corresponds to one in the Parse data model, but this time the property is of type Array rather than String:

The restriction that the Array should only contain Strings, is entirely Swift-specific. The Parse data-model does not have a restriction like that.

Note also that I have added an instruction to save the object in background after setting this property. You don’t need to do that to «save» the object locally. It is only for saving remotely, which can be done whenever you want, provided that the object is still in memory.

Queries

We are fond of making class factory methods for queries. For example, here is a class method on our Letter class, that constructs a query to find the next shippable letter:

Rather than using the query factory method in other classes, we can use it internally in a public method that calls a block with a Letter object:

Parse and Bolts

The Bolts framework is maintained by Parse/Facebook and provides a neat solution for chaining asynchronous tasks, among other things. Unfortunately, they have not tied Parse and Bolts together, so you have to write your own extensions to «Boltify» Parse’s asynchronous tasks.

I have written an extension to PFQuery which «bolitfies» all the background-with-block functions, as well as a subclass of PFCloud that «boltifies» callFunctionInBackground:

Ideally, the PFCloud subclass should be an extension as well, but I ran into some infinite looping that I wasn’t able to clear out. If anyone has any pointers on how to solve it, please comment below.

Having this utility in place we can simplify querying for the next shippable letter even further:

Notice how we now don’t need to refer to the generic PFObject. Instead we have a BFTask object whose result property we unwrap into a Letter object.

We could even rewrite this method with in Bolts-style, but we leave that as an exercise to the reader. Which do you prefer?

Notes on JSON responses from cloud functions

Parsing the responses from Parse’s cloud function utility is not as straight-forward as I’d like it to be. Hopefully, Parse will release a Swift-specific SDK sometime in the future, to remedy this.

The problem is that the response is wrapped in good-old Objective-C objects, such as NSDictionary and NSArray. Transferring those over to Swift type collections is rather painful. Below is one approach that I have explored, but surely there are other, more effective ones. Feel free to comment on them.

Basically, I have created a class to represent the type of response I get from the cloud function, in this case, an Instagram photo. I wrap the cloud function in a class factory method, which, in the end, calls a block sending a Swift-Array of the type InstagramPhoto (the class itself).

The callback to the Parse cloud function, unwraps the response manually, loops through an NSArray. Inside the loop I create a new object of the class InstagramPhoto, and initializes it using the special fromDictionary method I wrote. That method populates my object using the NSDictionary.

Unfortunately Parse is closing down in 2017, but we have found a great and actually local (to us) service: AppStax.

En kommentar om “Start using Swift with Parse.com”

Legg inn en kommentar