CoreData/data storage management, CoreDataRelationships/use of relational data structure storage management

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)
    }
}

  2.4 Rendering:

Guess you like

Origin blog.csdn.net/u011193452/article/details/133356997