1. Add, delete, modify and query CoreData data
1.1 Create data entity management files
Click File -> New -> File... -> Core Data in the menu bar, select Data Mode, and create the FruitsContainer.xcdatamodeld file
1.2 Create FruitEntity entity table
Open the FruitsContainer.xcdatamodeld file, click Add Entity, create the FruitEntity entity table, and add the name attribute
1.3 Add information as shown below:
1.4 Implementation
import CoreData
// View - UI
// Model - data point
// ViewModel - manages the data for a view
class CoreDataViewModel: ObservableObject{
// 添加数据容器
let container: NSPersistentContainer
// 实体数组
@Published var savedEntities:[FruitEntity] = []
init() {
self.container = NSPersistentContainer(name: "FruitsContainer")
// 加载持久
self.container.loadPersistentStores { description, error in
if let error = error{
print("Error loading core data. \(error)")
}
}
// 获取实体数据
fetchFruits()
}
// 获取数据
func fetchFruits(){
// 获取实体
let request = NSFetchRequest<FruitEntity>(entityName: "FruitEntity")
do {
savedEntities = try container.viewContext.fetch(request)
}catch let error{
print("Error retching. \(error)")
}
}
// 添加数据
func addFruit(text: String){
let newFruit = FruitEntity(context: container.viewContext)
newFruit.name = text
saveData()
}
// 删除数据
func deleteFruit(indexSet: IndexSet){
guard let index = indexSet.first else{ return }
let fruitEntity = savedEntities[index]
container.viewContext.delete(fruitEntity)
saveData()
}
// 更新数据
func updateFruit(entity: FruitEntity){
//let currentName = entity.name ?? ""
//let newName = currentName + "!"
//entity.name = newName
entity.name = (entity.name ?? "").appending("!")
saveData()
}
// 保存数据
func saveData(){
do{
try container.viewContext.save()
fetchFruits()
}catch let error{
print("Error saving. \(error)")
}
}
}
/// 核心数据的使用,新建项目 CoreDataBootcamp 实现修改 Demo 示例
struct CoreDataBootcamp: View {
@StateObject var vm = CoreDataViewModel()
@State var textFileText = ""
var body: some View {
NavigationView {
VStack(spacing: 20) {
TextField("Add fruit here...", text: $textFileText)
.font(.headline)
.padding(.horizontal)
.frame(height: 55)
.background(Color.secondary.opacity(0.3))
.cornerRadius(10)
.padding(.horizontal)
Button {
// 判断是否为空
guard !textFileText.isEmpty else { return }
vm.addFruit(text: textFileText)
textFileText = ""
} label: {
Text("Submit")
.font(.headline)
.foregroundColor(.white)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(Color.pink)
.cornerRadius(10)
.padding(.horizontal)
}
List {
ForEach(vm.savedEntities) { entity in
Text(entity.name ?? "NO Name")
.onTapGesture {
vm.updateFruit(entity: entity)
}
}
.onDelete(perform: vm.deleteFruit)
}
.listStyle(.plain)
}
.navigationTitle("Fruits")
}
}
}
1.5 Rendering:
2. CoreDataRelationships operation of relational data table structure
2.1 Create management data table file CoreDataContainer.xcdatamodeld, entity class, attributes and corresponding relationships
2.2 The entity relationship table is as shown in the figure:
2.3 Implementation
import CoreData
// 3 enitites
// BusinessEntity 企业
// DepartmentEntity 部门
// EmployeeEntity 员工
/// 核心数据操作管理
class CoreDataManager{
// Sinstance 单例模式
static let instance = CoreDataManager()
let container: NSPersistentContainer
let context: NSManagedObjectContext
init() {
container = NSPersistentContainer(name: "CoreDataContainer")
// 加载数据
container.loadPersistentStores { description, error in
if let error = error{
print("Error loading core data: \(error)")
}
}
context = container.viewContext
}
// 保存
func save(){
do{
try context.save()
print("Saved successfully!")
}catch let error{
print("Error saving core data: \(error.localizedDescription)")
}
}
}
/// ViewModel
class CoreDataRelationshipViewModel: ObservableObject{
let manager = CoreDataManager.instance
/// 所有的企业
@Published var businesses:[BusinessEntity] = []
/// 所有的部门
@Published var departments:[DepartmentEntity] = []
/// 所有的员工
@Published var employees:[EmployeeEntity] = []
init() {
getBusinesses()
getDepartments()
getEmployees()
}
/// 获取企业实体
func getBusinesses(){
let request = NSFetchRequest<BusinessEntity>(entityName: "BusinessEntity")
// 排序
let sort = NSSortDescriptor(keyPath: \BusinessEntity.name, ascending: true)
request.sortDescriptors = [sort]
// 过滤
//let filter = NSPredicate(format: "name == %@", "Apple")
//request.predicate = filter
do{
businesses = try manager.context.fetch(request)
}catch let error{
print("Error fatching. \(error.localizedDescription)")
}
}
/// 获取部门实体
func getDepartments(){
let request = NSFetchRequest<DepartmentEntity>(entityName: "DepartmentEntity")
do{
departments = try manager.context.fetch(request)
}catch let error{
print("Error fatching. \(error.localizedDescription)")
}
}
/// 获取所有的员工信息 EmployeeEntity
func getEmployees(){
let request = NSFetchRequest<EmployeeEntity>(entityName: "EmployeeEntity")
do{
employees = try manager.context.fetch(request)
}catch let error{
print("Error fatching. \(error.localizedDescription)")
}
}
//获取指定企业的员工
func getEmployees(forBusiness business: BusinessEntity){
let request = NSFetchRequest<EmployeeEntity>(entityName: "EmployeeEntity")
//过滤器
let filter = NSPredicate(format: "business == %@", business)
request.predicate = filter
do{
employees = try manager.context.fetch(request)
}catch let error{
print("Error fatching. \(error.localizedDescription)")
}
}
/// 更新企业里信息
func updateBusiness(){
let existingBusiness = businesses[1]
existingBusiness.addToDepartments(departments[0])
// existingBusiness.removeFromDepartments(departments[0])
// existingBusiness.addToEmployees(employees[0])
save()
}
/// 添加企业实体
func addBusiness(){
let newBusiness = BusinessEntity(context: manager.context)
// Apple Microsoft Facebook
newBusiness.name = "Apple"
// add existing departments to the new business
// 添加现有的部门实体到新的企业实体内
// newBusiness.departments = [departments[0], departments[1]]
// add existing employees to the new business
// 添加现有的员工实体到现的企业实体内
// newBusiness.employees = [employees[1]]
// add new business to existing department
// 添加新的企业实体到部门实体内
// newBusiness.addToDepartments()
// add new business to existing employee
// 添加新的企业实体到现有的员工实体内
// newBusiness.addToEmployees()
save()
}
/// 添加部门实体
func addDepartment(){
let newDepartment = DepartmentEntity(context: manager.context)
//Marketing Engineering Finance
newDepartment.name = "Marketing"
// 对应第一个企业
newDepartment.businesses = [businesses[0],businesses[1],businesses[2]]
//newDepartment.addToEmployees(employees[0])
//newDepartment.employees = [employees[1]]
//newDepartment.addToEmployees(employees[1])
save()
}
/// 添加员工
func addEmployee(){
let newEmployee = EmployeeEntity(context: manager.context)
// Emily John
newEmployee.name = "John"
newEmployee.age = 21
newEmployee.dateJoined = Date()
// 对应企业
newEmployee.business = businesses[2]
// 对应部门
newEmployee.department = departments[1]
save()
}
/// 删除部门实体
func deleteDepartment() {
let index = 1
guard departments.count > index else { return }
let department = departments[index]
manager.context.delete(department)
save()
}
/// 保存
func save(){
// 移除数组内容
businesses.removeAll()
departments.removeAll()
employees.removeAll()
// 保存获取数据
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.manager.save()
self.getBusinesses()
self.getDepartments()
self.getEmployees()
}
}
}
// 核心数据关系型结构
struct CoreDataRelationshipsBootcamp: View {
// ViewModel
@StateObject var viewModel = CoreDataRelationshipViewModel()
var body: some View {
NavigationView {
ScrollView {
VStack(spacing: 20) {
Button {
//viewModel.addBusiness()
//viewModel.addDepartment()
//viewModel.addEmployee()
//viewModel.updateBusiness()
viewModel.deleteDepartment()
} label: {
Text("Perform Action")
.foregroundColor(.white)
.frame(height: 55)
.frame(maxWidth:.infinity )
.background(Color.accentColor.cornerRadius(10))
}
// 企业
ScrollView(.horizontal, showsIndicators: true) {
HStack(alignment: .top) {
ForEach(viewModel.businesses) { business in
BusinessView(entity: business)
}
}
}
// 部门
ScrollView(.horizontal, showsIndicators: true) {
HStack(alignment: .top) {
ForEach(viewModel.departments) { department in
DepartmentView(entity: department)
}
}
}
// 员工
ScrollView(.horizontal, showsIndicators: true) {
HStack(alignment: .top) {
ForEach(viewModel.employees) { employee in
EmployeeView(entity: employee)
}
}
}
}
.padding()
}
.navigationTitle("Relationships")
}
}
}
// 企业视图
struct BusinessView: View{
let entity: BusinessEntity
var body: some View {
VStack(alignment: .leading, spacing: 20) {
Text("Name: \(entity.name ?? "")")
.bold()
// 获取企业下的部门
if let departments = entity.departments?.allObjects as? [DepartmentEntity]{
Text("Departments:")
.bold()
// 获取所有部门
ForEach(departments) { department in
Text(department.name ?? "")
}
}
// 获取企业下的员工
if let employees = entity.employees?.allObjects as? [EmployeeEntity]{
Text("Employees:")
.bold()
// 获取所有的员工
ForEach(employees) { employee in
Text(employee.name ?? "")
}
}
}
.padding()
.frame(maxWidth: 300,alignment: .leading)
.background(Color.gray.opacity(0.5))
.cornerRadius(10)
.shadow(radius: 10)
}
}
// 部门视图
struct DepartmentView: View{
let entity: DepartmentEntity
var body: some View {
VStack(alignment: .leading, spacing: 20) {
Text("Name: \(entity.name ?? "")")
.bold()
// 获取部门的企业
if let businesses = entity.businesses?.allObjects as? [BusinessEntity]{
Text("Businesses:")
.bold()
// 获取所有企业
ForEach(businesses) { business in
Text(business.name ?? "")
}
}
// 获取部门下的员工
if let employees = entity.employees?.allObjects as? [EmployeeEntity]{
Text("Employees:")
.bold()
// 获取所有的员工
ForEach(employees) { employee in
Text(employee.name ?? "")
}
}
}
.padding()
.frame(maxWidth: 300,alignment: .leading)
.background(Color.green.opacity(0.5))
.cornerRadius(10)
.shadow(radius: 10)
}
}
// 员工视图
struct EmployeeView: View{
let entity: EmployeeEntity
var body: some View {
VStack(alignment: .leading, spacing: 20) {
Text("Name: \(entity.name ?? "")")
.bold()
Text("Age: \(entity.age)")
Text("Date jiined: \(entity.dateJoined ?? Date())")
// 获取企业
Text("Businesses:")
.bold()
Text(entity.business?.name ?? "")
// 获取部门
Text("Departmentes:")
.bold()
Text(entity.department?.name ?? "")
}
.padding()
.frame(maxWidth: 300,alignment: .leading)
.background(Color.blue.opacity(0.5))
.cornerRadius(10)
.shadow(radius: 10)
}
}