Skip to content

Instantly share code, notes, and snippets.

@alexpaul
Last active June 16, 2023 12:23
Show Gist options
  • Save alexpaul/f4d7ed66101613e892e50e8317ab30ca to your computer and use it in GitHub Desktop.
Save alexpaul/f4d7ed66101613e892e50e8317ab30ca to your computer and use it in GitHub Desktop.
Core Data saving an array.

Core Data (Saving an array)

While saving an array to Core Data is supported, one of the first questions you will want to ask, if this array should be a relationship to another entity instead? It the answer is no, then continue reading on....

1. Core Data Model (Graphical Interface)

Set the attribute, in this case, the type you want to save as an array to Core Data supported type Binary Data

Example
attribute is hobbies

type would be Binary Data

2. Save the array to the entity instance

NSKeyedArchiver is a class that serializes (converts) data very similar to JSONEncoder

// saving an array [String] to a Core Data (Binary Data) type
// user is an instance of the User entity class
do {
  user.hobbies = try NSKeyedArchiver.archivedData(withRootObject: ["Fishing", "Biking", "Dancing"], requiringSecureCoding: true)
} catch {
  print("failed to archive array with error: \(error)")
}

Remember to save the NSManagedObjectContext.

3. Retrieve the array using the entity's attribute

NSKeyedUnArchiver is a class that de-serializes (re-converts) data back, very similar to JSONDecoder

NSArray.self - we have to specify what class we are getting back, the class needs to conform to the NSSecureCoding protocol and inherit from NSObject. In this case we are first getting back an NSArray (Objective-C Array, keep in mind Core Data is an Objective-C API. After retrieving the NSArray we use typecasting to convert it to a String array which we stored originally.)

if let hobbies = user.hobbies {
  do {
    if let hobbiesArr = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: hobbies) as? [String] {
      dump(hobbiesArr)
    }
  } catch {
    print("could not unarchive array: \(error)")
  }
}
@FlorianMielke
Copy link

Why not use the Transformable type with an NSSecureUnarchiveFromDataTransformer? That way, there is no need to archive/unarchive data and instead use Core Data's native approach for dealing with custom data types directly.

See: https://developer.apple.com/documentation/coredata/handling_different_data_types_in_core_data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment