CoreData
Array
Swift
iOS Development
Data Persistence

How to save Array to CoreData?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Core Data does not have a native column type called Array. When people ask how to save an array to Core Data, the real question is which representation fits the data: a transformable value, a to-many relationship, or a serialized blob. Choosing the right one matters because it affects querying, migrations, and performance.

Decide What the Array Represents

There are two common cases:

  • a small value list that belongs entirely to one record, such as a user's favorite tags
  • a collection of real objects that should be queried, sorted, or related independently

If the array contains real domain objects, model them as a separate Core Data entity with a relationship. If the array is just a small bundle of values, a transformable attribute is often enough.

Option 1: Use a Transformable Attribute for Small Value Arrays

For simple arrays such as [String], a transformable attribute is often the shortest path. In the data model editor, define an attribute such as tags and set its type to Transformable.

With modern Core Data, a secure archiving transformer is the safest route. The managed object can expose the value as a Swift array.

swift
1import CoreData
2
3@objc(Note)
4public class Note: NSManagedObject {
5    @NSManaged public var title: String
6    @NSManaged public var tags: [String]?
7}

Saving looks normal:

swift
1let context = persistentContainer.viewContext
2let note = Note(context: context)
3note.title = "Release checklist"
4note.tags = ["ios", "qa", "urgent"]
5
6try context.save()

Reading is just as simple:

swift
let request: NSFetchRequest<Note> = Note.fetchRequest()
let notes = try context.fetch(request)
print(notes.first?.tags ?? [])

This works well when you do not need to query inside the array values from Core Data itself.

Option 2: Use a Separate Entity for Queryable Items

If the array contains items you may search, sort, or reuse, a to-many relationship is a better design.

For example, instead of storing a [String] of skills on Person, create a Skill entity and relate it to Person.

swift
1@objc(Person)
2public class Person: NSManagedObject {
3    @NSManaged public var name: String
4    @NSManaged public var skills: Set<Skill>
5}
6
7@objc(Skill)
8public class Skill: NSManagedObject {
9    @NSManaged public var name: String
10    @NSManaged public var owner: Person
11}

Create and save linked objects like this:

swift
1let context = persistentContainer.viewContext
2
3let person = Person(context: context)
4person.name = "Maya"
5
6let swiftSkill = Skill(context: context)
7swiftSkill.name = "Swift"
8swiftSkill.owner = person
9
10let coreDataSkill = Skill(context: context)
11coreDataSkill.name = "Core Data"
12coreDataSkill.owner = person
13
14try context.save()

This design is more verbose, but it supports fetches such as all people with a given skill. That is impossible if the values are buried inside one serialized array blob.

Which Option Should You Prefer

Use a transformable attribute when:

  • the array is small
  • you only read or write it as a whole
  • the values do not need independent relationships

Use a separate entity when:

  • items need predicates or sorting in fetch requests
  • the list can grow large
  • each item has its own properties
  • you care about migration safety and schema clarity

In production apps, the relationship approach is usually the better long-term model even if it takes more setup.

Preserve Order When the Array Order Matters

A to-many Core Data relationship is not an array by default. If order matters, you need either:

  • an ordered relationship
  • or an explicit position attribute on the child entity

A position field is often the clearest option because it works well in fetch requests.

swift
1@objc(ChecklistItem)
2public class ChecklistItem: NSManagedObject {
3    @NSManaged public var title: String
4    @NSManaged public var position: Int16
5    @NSManaged public var checklist: Checklist
6}

Then fetch the children with a sort descriptor on position.

Avoid Encoding Everything Into One String

Some developers join an array into a comma-separated string and store that in Core Data. It looks easy, but it breaks as soon as values contain commas, need escaping, or need querying.

If you want a compact single-field representation, use a proper transformable value or encoded Data, not an ad hoc delimiter scheme.

A Codable Wrapper Can Help

If your array contains a custom value type that is not directly stored by Core Data, a Codable wrapper encoded to Data is another option.

swift
1import Foundation
2
3struct TagList: Codable {
4    let values: [String]
5}
6
7let data = try JSONEncoder().encode(TagList(values: ["ios", "swift"]))
8let decoded = try JSONDecoder().decode(TagList.self, from: data)
9print(decoded.values)

You can store data in a Binary Data attribute. This is still not queryable by Core Data, but it is better structured than a manually concatenated string.

Migration and Performance Considerations

Transformable values are convenient, but they hide structure from the persistence layer. That has consequences:

  • Core Data cannot index inside the stored array
  • migrations can get harder when the serialized type changes
  • large blobs increase read and write cost for whole-object updates

That is why transformable attributes are best for small auxiliary data, not central relational data.

Common Pitfalls

Treating every array as a transformable value. This is convenient early and painful later when you need queries.

Expecting a to-many relationship to preserve order automatically. Use an ordered relationship or a position field.

Storing arrays as comma-separated strings. That is fragile and hard to evolve.

Saving large serialized arrays repeatedly. Core Data must rewrite the whole value.

Forgetting that transformable types need safe archival behavior. Keep the stored type stable.

Summary

  • Core Data does not store arrays directly, so you need a representation strategy.
  • Use a transformable attribute for small value lists read as a whole.
  • Use a separate entity and relationship when array items need querying or their own fields.
  • Preserve order explicitly if sequence matters.
  • Avoid ad hoc string serialization for structured data.

Course illustration
Course illustration

All Rights Reserved.