Skip to content

Category: Backend

Restoring your sanity reading JSON into Codables

Integrating your app with APIs means you’re going to be dealing with parsing JSON in data objects you can use nicely. iOS provides the Codable protocol to do just that thing, but once you start trying to map JSON to that well-formed protocol, that’s when things fall apart.

JSON doesn’t have standard schemas (at least none that were ever seriously adopted), so you’re stuck with reading documentation like this for the details:

😒 Great, that’s useful… One example response, no field descriptions, types, anything. (And before you ask, this is the GitHub API documentation, so not even large organizations are immune to this problem.)

So you code your app off of these examples, then when you try and use it in the wild, you get:

I followed their documentation, and it didn’t work. How the heck am I ever going to figure out how to make this API JSON into a nice, easy to use Swift struct?!

Thankfully, there are some tricks — and one tool — you can use to make your job a lot easier. We’ll start by deciphering those error messages above, and how to figure out what error they are trying to point out. Then we’ll cover a procedure I like to use whenever I encounter one of these errors to fix them, and even use to avoid these errors in the first place. Let’s dive in.

I create a batch of CloudKit records, but when I try to sort them by date, they’re all jumbled?

If your app stores user data in a database, there are a number of occasions where you may need to make changes to multiple objects at once. The most likely scenario is you are loading the initial database state for a new user as part of the onboarding process, but it may also come at times where a user modifies a bunch of records at once, or an app upgrade requires the app to modify those values somehow.

If you’re using CloudKit as your database, you follow the common advice: per Apple’s recommendation, and for the sake of performance, you want to make as few of these CloudKit operations as possible, so you create or modify records in one batch, using a CKModifyRecordsOperation.

But then if you want to sort these records in order of when they were created, or last modified, using a creationDate or modificationDate NSSortDescriptor, those records are out of order. You inserted them 1-2-3-4-5, but you get 2-4-3-5-1.

Even worse, every time you ask for those records, the order is different. So the next time, it’s 3-1-2-5-4.

I added the records in the order I wanted them; why is CloudKit messing up the order?

There are two things happening that cause this behavior: one of them is specific to CloudKit’s batch creation and modification, and one of them is common behavior across many database systems, including CloudKit. We’ll dig into both issues, and then talk about a couple of ways you can make your records sort by date cleanly.

Order your Core Data entities the right way for maximum speed

One of the earliest things you learn about Core Data is that it doesn’t support ordered entities out of the box. Sometimes you can have an ordered relationship, but the minute you try and move that database to iCloud, you find that ordered relationships aren’t supported. Long story short: if you want to order your entities, then you need to create an index attribute that allows you to sort your entities yourself.

So you do the natural thing: create your index attribute as an Int, and then assign each in order: 1, 2, 3…

This is fine if the data doesn’t change, but if this is data the user can add to and reorder, what if they want to move element 3 between 1 and 2? It means you need to change 2 entities in addition to adding the new one. What if there are 500 entities, and the user wants to insert a new first element. 500 entities to change because the user moved a single entity?!

There must be a way to insert and reorder IDs that avoids all of this rewriting, right?

Thankfully there are a couple of techniques you can use that will almost completely eliminate the need to rewrite a huge number of entities every time you need to insert or rearrange entities. Let’s talk about them now.

Got JSON? Need objects? Stop typing, and start generating your object models with Quicktype

It’s time to integrate another API into your app.

That statement alone brings all these feelings to mind:

  • Poring over the API documentation, teasing out the JSON requests and responses for each call you need to use
  • Extracting a schema out of those requests and responses, being mindful of the structures, types, and required/optional state of each field
  • Writing the Swift or Objective-C code to translate those JSON schema into an object model

Hours gone in an instant. Isn’t parsing and translation something a computer should be taking care of? It can, using a tool called Quicktype.

4 ways to connect your app to a database, and 1 way not to

When you’re putting together a new app, especially if it’s your first exposure to iOS development, it can be a confusing experience. Sometimes you’re starting from scratch, and you have a bunch of options available to you, and you just don’t know which one is right for your app. You may have even been “helped” by a PaaS or IaaS platform that has given you a conventional SQL database instance: great for web apps, but how do I connect this to my iOS app? Do I want to?

There are many different ways to provide a database backend for your app. Here are some recommendations for different situations.