SwiftData — mixing SwiftUI and UIKit

Francesco Pretelli
1 min readNov 26, 2023

--

I read various articles on SwiftData describing how to use it in SwiftUI or in UIKit, but couldn’t find one that describe how to use it when you have an app using both.

Well it turns out it’s easier than expected.

Note: the code below is taken from the template used by Xcode when you create a new project and select “Use SwiftData”.

It’s possible to crate the ModelContainer as singleton, like suggested for UIKit apps:

class DatabaseService {

static var shared = DatabaseService()

var container: ModelContainer = {
let schema = Schema([
Item.self,
])
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)

do {
return try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}()

var context: ModelContext

init() {
context = ModelContext(container)
}

func saveItem(_ item: Item) {
context.insert(item)
}

func deleteWatchlistItem(_ item: Item) {
let itemToBeDeleted = item
context.delete(itemToBeDeleted)

}

func fetchItems(onCompletion: @escaping([Item]?, Error?)->(Void)) {
let descriptor = FetchDescriptor<Item>(sortBy: [SortDescriptor<Item>(\.timestamp)])

do {
let data = try context.fetch(descriptor)
onCompletion(data,nil)
} catch {
onCompletion(nil,error)
}
}

}

To access it from SwiftUI, you just inject it:

@main
struct testApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(DatabaseService.shared.container)
}
}

In the view you can access the context as described in every tutorial and documentation:

@Environment(\.modelContext) private var modelContext
@Query private var items: [Item]

To access it from UIKit classes, call the DatabaseService Singleton directly.

Hope this helps, this is just a simple example and there might be better way to structure it, depending on your needs.

--

--

Francesco Pretelli

Engineering Manager - Tokyo. I write about everything, from tech to daily stuff.