Isolating CloudKit from your Controllers

So far in this series we've been using CloudKit directly from our controllers. This can be somewhat limiting. It requires you to be online or everything fails, we may want to add a caching layer, or we might want to use CloudKit as a network synchronization layer, rather than a primary data store. In this episode we'll examine an architecture that will allow you to decouple your view controllers from CloudKit as a first step to achieving more flexibility with your CloudKit implementation.

Episode Links

A Protocol for our Models

First we define a protocol for the Note:

protocolNote:CustomStringConvertible{varidentifier:String?{get}vartitle:String{get}varcontent:String{getset}varcreatedAt:Date?{get}varmodifiedAt:Date?{get}varfolderIdentifier:String?{getset}}extensionNote{vartitle:String{letlength=content.lengthOfBytes(using:.utf8)iflength==0{return"New Note"}else{letpreviewLength=20// if it's short enough, just use the entire contentiflength<previewLength{returncontent}varindex=content.index(content.startIndex,offsetBy:previewLength)varfoundTitle=falseifletfirstNewLine=content.range(of:"\n"){iffirstNewLine.upperBound<index{index=firstNewLine.upperBoundfoundTitle=true}}varpreview=content.substring(to:index)ifcontent.lengthOfBytes(using:.utf8)>previewLength&&!foundTitle{preview.append("...")}returnpreview}}vardescription:String{return"Note > \(title) (\(identifier??"nil"))"}}

Here we have a simple computed property for the title we can use so any Note implementation can get this for free.

A Facade for all Data Access

To fetch or save any of the objects in our application, we will use a façade that encapsulates this logic. Different implementations of this protocol can be used to swap out the implementation strategy of the app:

There are a lot of methods to implement, but each one should be straight-forward to implement.

The In-Memory Implementation

To get the app working without worrying about CloudKit yet, we can code our view controllers to only depend on the Note and Folder protocols as well as the NoteManager protocol. The actual implementation of these will be hidden.