SwiftData, pre-seed database

I started developing a new app, and it's been an exciting journey so far. Recently, I've begun utilising SwiftData, which is proving to be a fantastic tool for managing data within the app. It's been a smooth transition from CoreData.

Below is an example of how you can pre-seed your database using SwiftData.

Country.swift that is Codable:

import SwiftData

@Model
class Country: Codable {
	enum CodingKeys: CodingKey {
		case id
		case name
		case continent
	}

	var id: String = ""
	var name: String = ""
	var continent: String = ""

	init(id: String, name: String, continent: String) {
		self.id = id
		self.name = name
		self.continent = continent
	}

	required init(from decoder: Decoder) throws {
		let container = try decoder.container(keyedBy: CodingKeys.self)
		self.id = try container.decode(String.self, forKey: .id)
		self.name = try container.decode(String.self, forKey: .name)
		self.continent = try container.decode(String.self, forKey: .continent)
	}

	func encode(to encoder: Encoder) throws {
		var container = encoder.container(keyedBy: CodingKeys.self)
		try container.encode(id, forKey: .id)
		try container.encode(name, forKey: .name)
		try container.encode(continent, forKey: .continent)
	}
}

In App.swift add this to your window group where you also added your modelContainer (.modelContainer(sharedModelContainer)).

.modelContainer(for: Country.self) { result in
	do {
		let container = try result.get()

		// Check we haven't already added our countries.
		let descriptor = FetchDescriptor<Country>()
		let existingCountries = try container.mainContext.fetchCount(descriptor)
		guard existingCountries == 0 else { return }

		// Load and decode the JSON.
		guard let url = Bundle.main.url(forResource: "countries", withExtension: "json") else {
			fatalError("Failed to find countries.json")
		}

		let data = try Data(contentsOf: url)
		let countries = try JSONDecoder().decode([Country].self, from: data)

		// Add all our data to the context.
		for country in countries {
			container.mainContext.insert(country)
		}
	} catch {
		print("Failed to pre-seed database.")
	}
}

Category:

Tag:

Year: