Latest 1.0.0
License BS2D-2-Clause
Platforms ios 10.0


Provides a simple way of Encoding and Decoding custom objects to/from Cloudkit through custom Encoder and Decoder which converts your structure to CKRecord and vice-versa. It can be use with nested objects.

Inspired by CloudkitCodable.



Add the following entry to your Podfile:

pod 'NestedCloudKitCodable'

Then run pod install.


Add the following entry to your Cartfile:

github "ggirotto/NestedCloudkitCodable"

Then run carthage update.

If this is your first time using Carthage in the project, see Carthage docs for extra install steps.


  • Drag the Sources folder anywhere in your project.


CKCodable protocol

Implements CustomCloudkitCodable in the models that you want to convert to/from CKRecord. The protocol requires two properties to be implemented.

var cloudKitRecordType: String { get }

is the Record Type that represents that object in CloudKit container.

var cloudKitIdentifier: String { get }

is the identifier from that object, which will be used as the identifier from the CKRecord when converting the object to a CKRecord.

Important: Use unique identifiers for your objects to avoid creating unecessary CKRecords.

This protocol also let you implement the function

func ignoredProperties() -> [String]

which how its name suggests, let you ignore some properties from being encoded in the resultant CKRecord.


CLLocation properties has a special behavior. Since they are primitive types for CloudKit but they are not for Codable protocol, it was necessary to create a workaround to encode/decode them.

Single CLLocation must be encoded in the format "latitude;longitude", i.e, as a String splited by ;.
Multiple CLLocations must follow the same pattern, and must be encoded/decoded as an array of String with each CLLocation splited using the same pattern described above



Let School be your custom object as follows.

struct School: CKCodable {

    var cloudKitRecordType: String {
        return "School"
    var cloudKitIdentifier: String {
        return id

    var id = UUID().uuidString
    var name: String!
    var location: CLLocation!
    var students: [Person]!
    var director: Person!
    var books: [Book]!

To encode it, just use CKRecordEncoder to encode it, simple as follows.

let school = School()

do {
    let encodedRecords = try CKRecordEncoder().encode(school)
    // Save encodedRecords to your Cloudkit database
} catch let error as CKCodableError {
    // Handle errors
} catch { }


Consider the same School object, to Decode from its original CKRecord back to School object, use CKRecordDecoder as follows.

let schoolRecord = ... // Your school object CKRecord fetched from CloudKit
let referenceDatabase = CKContainer.default().publicCloudDatabase // Database where related CKRecords are stored

                         from: schoolRecord,
                         referenceDatabase: referenceDatabase) { (decodedSchool, error) in
    if let error = error {
        // Adds your error handling here

    let schoolObject = decodedSchool as! School


Note that decode function is asynchronous. This is necessary because when your object has nested objects associated, the decode function fetch all CKRecords from this nested objects before decoding the original one. In the example above, the decode funciton will fetch all records from students, books and director nested objects before decoding the main School object.

Also, it’s necessary to send the referenceDatabase which this records will be looked for.

You can find this example objects here


Thanks for using this library! If you are experiencing some kind of trouble in it’s usage or have noticed some inconsistence or bug, please create an issue so I can investigate it.

Also feel free to contribute to the project by creating a PR :)

Latest podspec

    "name": "NestedCloudKitCodable",
    "version": "1.0.0",
    "summary": "Nested encoder and decoder for CKRecords.",
    "description": "NestedCloudKitCodable is a library to help you encode your custom objects to CloudKit CKRecord formatnand decode they back to their original type.",
    "homepage": "",
    "license": "BS2D-2-Clause",
    "authors": {
        "Guilherme Girotto": "[email protected]"
    "platforms": {
        "ios": "10.0"
    "swift_version": "4.2",
    "source": {
        "git": "",
        "tag": "1.0.0"
    "source_files": "NestedCloudKitCodable/Sources/**/*.swift",
    "ios": {
        "frameworks": [

Pin It on Pinterest

Share This