• CoreData/数据存储管理, CoreDataRelationships/关系型数据结构存储管理 的使用


    1. CoreData 数据的增删改查操作

      1.1 创建数据实体管理文件

        点击菜单栏 File -> New -> File... -> Core Data 栏下,选择 Data Mode,创建 FruitsContainer.xcdatamodeld 文件

      1.2 创建 FruitEntity 实体表

        打开 FruitsContainer.xcdatamodeld 文件,点击 Add Entity,创建 FruitEntity 实体表,添加 name 属性

      1.3 添加信息如下图:

      1.4 实现

    1. import CoreData
    2. // View - UI
    3. // Model - data point
    4. // ViewModel - manages the data for a view
    5. class CoreDataViewModel: ObservableObject{
    6. // 添加数据容器
    7. let container: NSPersistentContainer
    8. // 实体数组
    9. @Published var savedEntities:[FruitEntity] = []
    10. init() {
    11. self.container = NSPersistentContainer(name: "FruitsContainer")
    12. // 加载持久
    13. self.container.loadPersistentStores { description, error in
    14. if let error = error{
    15. print("Error loading core data. \(error)")
    16. }
    17. }
    18. // 获取实体数据
    19. fetchFruits()
    20. }
    21. // 获取数据
    22. func fetchFruits(){
    23. // 获取实体
    24. let request = NSFetchRequest<FruitEntity>(entityName: "FruitEntity")
    25. do {
    26. savedEntities = try container.viewContext.fetch(request)
    27. }catch let error{
    28. print("Error retching. \(error)")
    29. }
    30. }
    31. // 添加数据
    32. func addFruit(text: String){
    33. let newFruit = FruitEntity(context: container.viewContext)
    34. newFruit.name = text
    35. saveData()
    36. }
    37. // 删除数据
    38. func deleteFruit(indexSet: IndexSet){
    39. guard let index = indexSet.first else{ return }
    40. let fruitEntity = savedEntities[index]
    41. container.viewContext.delete(fruitEntity)
    42. saveData()
    43. }
    44. // 更新数据
    45. func updateFruit(entity: FruitEntity){
    46. //let currentName = entity.name ?? ""
    47. //let newName = currentName + "!"
    48. //entity.name = newName
    49. entity.name = (entity.name ?? "").appending("!")
    50. saveData()
    51. }
    52. // 保存数据
    53. func saveData(){
    54. do{
    55. try container.viewContext.save()
    56. fetchFruits()
    57. }catch let error{
    58. print("Error saving. \(error)")
    59. }
    60. }
    61. }
    62. /// 核心数据的使用,新建项目 CoreDataBootcamp 实现修改 Demo 示例
    63. struct CoreDataBootcamp: View {
    64. @StateObject var vm = CoreDataViewModel()
    65. @State var textFileText = ""
    66. var body: some View {
    67. NavigationView {
    68. VStack(spacing: 20) {
    69. TextField("Add fruit here...", text: $textFileText)
    70. .font(.headline)
    71. .padding(.horizontal)
    72. .frame(height: 55)
    73. .background(Color.secondary.opacity(0.3))
    74. .cornerRadius(10)
    75. .padding(.horizontal)
    76. Button {
    77. // 判断是否为空
    78. guard !textFileText.isEmpty else { return }
    79. vm.addFruit(text: textFileText)
    80. textFileText = ""
    81. } label: {
    82. Text("Submit")
    83. .font(.headline)
    84. .foregroundColor(.white)
    85. .frame(height: 55)
    86. .frame(maxWidth: .infinity)
    87. .background(Color.pink)
    88. .cornerRadius(10)
    89. .padding(.horizontal)
    90. }
    91. List {
    92. ForEach(vm.savedEntities) { entity in
    93. Text(entity.name ?? "NO Name")
    94. .onTapGesture {
    95. vm.updateFruit(entity: entity)
    96. }
    97. }
    98. .onDelete(perform: vm.deleteFruit)
    99. }
    100. .listStyle(.plain)
    101. }
    102. .navigationTitle("Fruits")
    103. }
    104. }
    105. }

      1.5 效果图:

    2. CoreDataRelationships 关系型数据表结构的操作

      2.1 创建管理数据表文件 CoreDataContainer.xcdatamodeld,实体类,属性及对应关系

      2.2 实体关系表如图:

                

      2.3 实现

    1. import CoreData
    2. // 3 enitites
    3. // BusinessEntity 企业
    4. // DepartmentEntity 部门
    5. // EmployeeEntity 员工
    6. /// 核心数据操作管理
    7. class CoreDataManager{
    8. // Sinstance 单例模式
    9. static let instance = CoreDataManager()
    10. let container: NSPersistentContainer
    11. let context: NSManagedObjectContext
    12. init() {
    13. container = NSPersistentContainer(name: "CoreDataContainer")
    14. // 加载数据
    15. container.loadPersistentStores { description, error in
    16. if let error = error{
    17. print("Error loading core data: \(error)")
    18. }
    19. }
    20. context = container.viewContext
    21. }
    22. // 保存
    23. func save(){
    24. do{
    25. try context.save()
    26. print("Saved successfully!")
    27. }catch let error{
    28. print("Error saving core data: \(error.localizedDescription)")
    29. }
    30. }
    31. }
    32. /// ViewModel
    33. class CoreDataRelationshipViewModel: ObservableObject{
    34. let manager = CoreDataManager.instance
    35. /// 所有的企业
    36. @Published var businesses:[BusinessEntity] = []
    37. /// 所有的部门
    38. @Published var departments:[DepartmentEntity] = []
    39. /// 所有的员工
    40. @Published var employees:[EmployeeEntity] = []
    41. init() {
    42. getBusinesses()
    43. getDepartments()
    44. getEmployees()
    45. }
    46. /// 获取企业实体
    47. func getBusinesses(){
    48. let request = NSFetchRequest<BusinessEntity>(entityName: "BusinessEntity")
    49. // 排序
    50. let sort = NSSortDescriptor(keyPath: \BusinessEntity.name, ascending: true)
    51. request.sortDescriptors = [sort]
    52. // 过滤
    53. //let filter = NSPredicate(format: "name == %@", "Apple")
    54. //request.predicate = filter
    55. do{
    56. businesses = try manager.context.fetch(request)
    57. }catch let error{
    58. print("Error fatching. \(error.localizedDescription)")
    59. }
    60. }
    61. /// 获取部门实体
    62. func getDepartments(){
    63. let request = NSFetchRequest<DepartmentEntity>(entityName: "DepartmentEntity")
    64. do{
    65. departments = try manager.context.fetch(request)
    66. }catch let error{
    67. print("Error fatching. \(error.localizedDescription)")
    68. }
    69. }
    70. /// 获取所有的员工信息 EmployeeEntity
    71. func getEmployees(){
    72. let request = NSFetchRequest<EmployeeEntity>(entityName: "EmployeeEntity")
    73. do{
    74. employees = try manager.context.fetch(request)
    75. }catch let error{
    76. print("Error fatching. \(error.localizedDescription)")
    77. }
    78. }
    79. //获取指定企业的员工
    80. func getEmployees(forBusiness business: BusinessEntity){
    81. let request = NSFetchRequest<EmployeeEntity>(entityName: "EmployeeEntity")
    82. //过滤器
    83. let filter = NSPredicate(format: "business == %@", business)
    84. request.predicate = filter
    85. do{
    86. employees = try manager.context.fetch(request)
    87. }catch let error{
    88. print("Error fatching. \(error.localizedDescription)")
    89. }
    90. }
    91. /// 更新企业里信息
    92. func updateBusiness(){
    93. let existingBusiness = businesses[1]
    94. existingBusiness.addToDepartments(departments[0])
    95. // existingBusiness.removeFromDepartments(departments[0])
    96. // existingBusiness.addToEmployees(employees[0])
    97. save()
    98. }
    99. /// 添加企业实体
    100. func addBusiness(){
    101. let newBusiness = BusinessEntity(context: manager.context)
    102. // Apple Microsoft Facebook
    103. newBusiness.name = "Apple"
    104. // add existing departments to the new business
    105. // 添加现有的部门实体到新的企业实体内
    106. // newBusiness.departments = [departments[0], departments[1]]
    107. // add existing employees to the new business
    108. // 添加现有的员工实体到现的企业实体内
    109. // newBusiness.employees = [employees[1]]
    110. // add new business to existing department
    111. // 添加新的企业实体到部门实体内
    112. // newBusiness.addToDepartments()
    113. // add new business to existing employee
    114. // 添加新的企业实体到现有的员工实体内
    115. // newBusiness.addToEmployees()
    116. save()
    117. }
    118. /// 添加部门实体
    119. func addDepartment(){
    120. let newDepartment = DepartmentEntity(context: manager.context)
    121. //Marketing Engineering Finance
    122. newDepartment.name = "Marketing"
    123. // 对应第一个企业
    124. newDepartment.businesses = [businesses[0],businesses[1],businesses[2]]
    125. //newDepartment.addToEmployees(employees[0])
    126. //newDepartment.employees = [employees[1]]
    127. //newDepartment.addToEmployees(employees[1])
    128. save()
    129. }
    130. /// 添加员工
    131. func addEmployee(){
    132. let newEmployee = EmployeeEntity(context: manager.context)
    133. // Emily John
    134. newEmployee.name = "John"
    135. newEmployee.age = 21
    136. newEmployee.dateJoined = Date()
    137. // 对应企业
    138. newEmployee.business = businesses[2]
    139. // 对应部门
    140. newEmployee.department = departments[1]
    141. save()
    142. }
    143. /// 删除部门实体
    144. func deleteDepartment() {
    145. let index = 1
    146. guard departments.count > index else { return }
    147. let department = departments[index]
    148. manager.context.delete(department)
    149. save()
    150. }
    151. /// 保存
    152. func save(){
    153. // 移除数组内容
    154. businesses.removeAll()
    155. departments.removeAll()
    156. employees.removeAll()
    157. // 保存获取数据
    158. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
    159. self.manager.save()
    160. self.getBusinesses()
    161. self.getDepartments()
    162. self.getEmployees()
    163. }
    164. }
    165. }
    166. // 核心数据关系型结构
    167. struct CoreDataRelationshipsBootcamp: View {
    168. // ViewModel
    169. @StateObject var viewModel = CoreDataRelationshipViewModel()
    170. var body: some View {
    171. NavigationView {
    172. ScrollView {
    173. VStack(spacing: 20) {
    174. Button {
    175. //viewModel.addBusiness()
    176. //viewModel.addDepartment()
    177. //viewModel.addEmployee()
    178. //viewModel.updateBusiness()
    179. viewModel.deleteDepartment()
    180. } label: {
    181. Text("Perform Action")
    182. .foregroundColor(.white)
    183. .frame(height: 55)
    184. .frame(maxWidth:.infinity )
    185. .background(Color.accentColor.cornerRadius(10))
    186. }
    187. // 企业
    188. ScrollView(.horizontal, showsIndicators: true) {
    189. HStack(alignment: .top) {
    190. ForEach(viewModel.businesses) { business in
    191. BusinessView(entity: business)
    192. }
    193. }
    194. }
    195. // 部门
    196. ScrollView(.horizontal, showsIndicators: true) {
    197. HStack(alignment: .top) {
    198. ForEach(viewModel.departments) { department in
    199. DepartmentView(entity: department)
    200. }
    201. }
    202. }
    203. // 员工
    204. ScrollView(.horizontal, showsIndicators: true) {
    205. HStack(alignment: .top) {
    206. ForEach(viewModel.employees) { employee in
    207. EmployeeView(entity: employee)
    208. }
    209. }
    210. }
    211. }
    212. .padding()
    213. }
    214. .navigationTitle("Relationships")
    215. }
    216. }
    217. }
    218. // 企业视图
    219. struct BusinessView: View{
    220. let entity: BusinessEntity
    221. var body: some View {
    222. VStack(alignment: .leading, spacing: 20) {
    223. Text("Name: \(entity.name ?? "")")
    224. .bold()
    225. // 获取企业下的部门
    226. if let departments = entity.departments?.allObjects as? [DepartmentEntity]{
    227. Text("Departments:")
    228. .bold()
    229. // 获取所有部门
    230. ForEach(departments) { department in
    231. Text(department.name ?? "")
    232. }
    233. }
    234. // 获取企业下的员工
    235. if let employees = entity.employees?.allObjects as? [EmployeeEntity]{
    236. Text("Employees:")
    237. .bold()
    238. // 获取所有的员工
    239. ForEach(employees) { employee in
    240. Text(employee.name ?? "")
    241. }
    242. }
    243. }
    244. .padding()
    245. .frame(maxWidth: 300,alignment: .leading)
    246. .background(Color.gray.opacity(0.5))
    247. .cornerRadius(10)
    248. .shadow(radius: 10)
    249. }
    250. }
    251. // 部门视图
    252. struct DepartmentView: View{
    253. let entity: DepartmentEntity
    254. var body: some View {
    255. VStack(alignment: .leading, spacing: 20) {
    256. Text("Name: \(entity.name ?? "")")
    257. .bold()
    258. // 获取部门的企业
    259. if let businesses = entity.businesses?.allObjects as? [BusinessEntity]{
    260. Text("Businesses:")
    261. .bold()
    262. // 获取所有企业
    263. ForEach(businesses) { business in
    264. Text(business.name ?? "")
    265. }
    266. }
    267. // 获取部门下的员工
    268. if let employees = entity.employees?.allObjects as? [EmployeeEntity]{
    269. Text("Employees:")
    270. .bold()
    271. // 获取所有的员工
    272. ForEach(employees) { employee in
    273. Text(employee.name ?? "")
    274. }
    275. }
    276. }
    277. .padding()
    278. .frame(maxWidth: 300,alignment: .leading)
    279. .background(Color.green.opacity(0.5))
    280. .cornerRadius(10)
    281. .shadow(radius: 10)
    282. }
    283. }
    284. // 员工视图
    285. struct EmployeeView: View{
    286. let entity: EmployeeEntity
    287. var body: some View {
    288. VStack(alignment: .leading, spacing: 20) {
    289. Text("Name: \(entity.name ?? "")")
    290. .bold()
    291. Text("Age: \(entity.age)")
    292. Text("Date jiined: \(entity.dateJoined ?? Date())")
    293. // 获取企业
    294. Text("Businesses:")
    295. .bold()
    296. Text(entity.business?.name ?? "")
    297. // 获取部门
    298. Text("Departmentes:")
    299. .bold()
    300. Text(entity.department?.name ?? "")
    301. }
    302. .padding()
    303. .frame(maxWidth: 300,alignment: .leading)
    304. .background(Color.blue.opacity(0.5))
    305. .cornerRadius(10)
    306. .shadow(radius: 10)
    307. }
    308. }

      2.4 效果图:

  • 相关阅读:
    代码随想录算法训练营第三十一天|理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
    Multi-task Classification Model Based On Multi-modal Glioma Data
    用增之Google
    [山东科技大学OJ]2297 Problem F: 编写函数:字符串的小写转大写(Append Code)
    Spring原理学习(五)初始化与销毁
    AWS SSA-C003 #21
    64.C++运算符重载
    浅谈必应bing搜索国内广告开户流程
    .NET深入了解哈希表和Dictionary
    [附源码]Python计算机毕业设计Django青栞系统
  • 原文地址:https://blog.csdn.net/u011193452/article/details/133356997