Swift
SwiftData - New Framework of Apple
8 ay önce yazıldı. | Okuma süresi: 6 dk.

First of all, I'm not one of those people who generally view new frameworks positively during the development phase. However, this time, I realized I was mistaken. I think SwiftData has turned out well in its current state.

A few days ago, while working on a freelance project, I noticed that some features of Core Data were restricted, and there were some changes in its structure. Of course, not knowing this is a mistake, as it is always an event that happens when a new product comes out due to Apple's policies. Even when Apple is about to launch a new product, they shut down the market and focus people on the new product.

In conclusion, Swift Data can actually be thought of as a greatly simplified and automated version of Core Data that operates in the background. In my initial tests and test app models, I found that you don't need to deal with those complex Core Data schemas anymore. It has become quite flexible and user-friendly. However, since SwiftData only serves versions 17 and above, it doesn't have a wide user base yet. Professional-level tasks will continue with the Core Data architecture. Of course, its counterpart Realm is a different world altogether...

Anyway, let's move on to the example structure right away.

Now, first of all, as usual, we need a model. It's generally the same, but we'll add a little something extra.


import Foundation
import SwiftData

@Model
final class Person {

var personName: String
var personAge: Int
var personIsHired: Bool
var timeStamp: Date

init(personName: String, personAge: Int, personIsHired: Bool = false, timeStamp: Date) {
self.personName = personName
self.personAge = personAge
self.personIsHired = personIsHired
self.timeStamp = timeStamp
}
}


Did you notice the import and @Model?

Apart from this, the main structure of the App will be as follows.


import SwiftUI
import SwiftData

@main
struct SwiftData_ExampleApp: App {

var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(for: Person.self)
}
}


Did you notice we added the .model container and provided "for Person.self" (which means we operated on our model in these constructs where "self" comes to the right side, as you know, not to the left.)

Our contentview.swift is as follows:


import SwiftUI
import SwiftData

struct ContentView: View {
@Environment(\.modelContext) private var modelContext

@Query private var allPersons: [Person]
@Query(filter: #Predicate { $0.personIsHired == true } ) private var hiredPersons: [Person]
@Query(filter: #Predicate { $0.personIsHired == false } ) private var firedPersons: [Person]



var body: some View {


NavigationView {
List {
Section(header: Text("Hired")) {
ForEach(hiredPersons) { person in

HStack {
Text("Name: \(person.personName)")
Text("Age: \(person.personAge)")

Button {
withAnimation {
person.personIsHired.toggle()

}

} label: {
Image(systemName: person.personIsHired ? "heart.fill" : "heart")
.tint(.red)
}
}
.swipeActions{
Button {
modelContext.delete(person)

} label: {
Image(systemName: "trash")
}

}

}

}

Section(header: Text("Fired")) {
ForEach(firedPersons) { person in

HStack {
Text("Name: \(person.personName)")
Text("Age: \(person.personAge)")

Button {
withAnimation {
person.personIsHired.toggle()

}

} label: {
Image(systemName: person.personIsHired ? "heart.fill" : "heart")
.tint(.gray)
}
}
.swipeActions{
Button {
modelContext.delete(person)
} label: {
Image(systemName: "trash")
}
}
}
}
}

.toolbar {
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
}

}

private func addItem() {
withAnimation {

let newPerson = Person(personName: " \(UUID().uuidString.prefix(10))", personAge: Int.random(in: 18...70), timeStamp: Date())

modelContext.insert(newPerson)

}
}

}


Here, the most important issue is the query at the top and the environment structure.


@Environment(\.modelContext) private var modelContext

@Query private var allPersons: [Person]
@Query(filter: #Predicate { $0.personIsHired == true } ) private var hiredPersons: [Person]
@Query(filter: #Predicate { $0.personIsHired == false } ) private var firedPersons: [Person]


In the early versions of SwiftData, there was no "after predicate" section. But now you should also set that part. You should already remember the meaning of "$0" from the "take the selected one" part. If you don't know, please take a moment to research it. The second "Person" in the structure can be confusing, but I believe they will make an update in the syntax in other versions. If many examples on GitHub give errors related to the initial structure, you can adjust it like this.


private func addItem() {
withAnimation {

let newPerson = Person(personName: " \(UUID().uuidString.prefix(10))", personAge: Int.random(in: 18...70), timeStamp: Date())

modelContext.insert(newPerson)

}
}


With this function, you can insert data just like in Core Data. For insertion, we create dummy data with a random UUID on the username, a random age value, and a date, similar to Core Data. When you open then close it, you will see that the data persists. In the app, you will first generate data and see examples of hire and fire. Of course, they have added some lovely things, like hearts :)

I find it enjoyable. The iCloud sync parts are still at an experimental level, but I find them promising. I will come with more original examples.

You can access the buggy version of this example on this GitHub repository. But you can edit the working version from here.

Stay Swift with love :) + SwiftUI


Page generated in 0.0222 seconds.