乐趣区

关于swift:Swift-UI项目调用core-data

一. 前言

这篇文章是我写的第一篇 Swift UI 相干的笔记吧。

这真的难搞哦,毕竟新进去的。国内文档真的是少之又少,国外的文档也真不多,根本搜进去的都是 UIKit 的。官网文档,也是一言难尽,根本就处于,我要实现一个性能,而后去搜一下各种帖子,筛选掉无用的帖子,找到有用的点,当然也是时常基本找不到有用的帖子,而后就要去油管上看各种教程,而后发现:哦!原来还有这个办法!接着去官网文档搜一下,看一下属性,本人调用调用 ……

光是这个 core data 我就折腾了近一周,最初发现,原来还是官网好呀 …..

吐槽一下自学 swift ui,当初进入正题了。

core data 呢,是苹果官网的本地数据库,然而其存储的文件其实是 sqlite 文件。其能够通过 icloud 实现备份和同步,当然 icloud 我会额定写一篇文档来具体讲述的(又是一把辛酸泪 …)。

二. 环境

如下是我以后的环境:

  • 零碎:macOS Big Sur 11.4
  • Xcode:Version 12.5 (12E262)
  • Swift:5.4

三. 操作步骤

1. 创立我的项目

在创立我的项目的时候,能够间接抉择 Use Core Data 选项,xcode 会间接在 ContentView.swift 中生成一个相干 demo。

2. 查看相干文件

创立之后,查看文件目录,绝对于不抉择Use Core Data,会多出如下几个文件:

  • <Your-Project-Name>.xcdatamodeId
  • Persistence.swift

3. 创立 core data 表

点击 <Your-Project-Name>.xcdatamodeId 文件,进入页面。

能够看到页面内有默认的 CONFIGURATIONSDefault,默认的 ENITITIESItem,能够了解为别离对应 sql 中的库和表。

而后点击 Item,能够看到其字段,有默认的timestamp 字段。

若要新增 ENTITIES(表),点击底部的Add Entity 按钮即可。

若要新增 Attributes(字段),点击右侧Attributes 中的 + 即可,留神字段要抉择类型。

比方,此处以默认的 Item 为例,新增 usernameage两个字段。

4. 代码层面操作 core data

1)查看

@Environment(\.managedObjectContext) private var viewContext

@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
  animation: .default)
private var items: FetchedResults<Item>

// body 中便当 items 即可

2)新增

private func addItem() {
  withAnimation {let newItem = Item(context: viewContext)
    newItem.timestamp = Date()

    do {try viewContext.save()
    } catch {
      // Replace this implementation with code to handle the error appropriately.
      // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
      let nsError = error as NSError
      fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    }
  }
}

如上是 xcode 主动生成的新增函数,若是要自定义增加字段能够这样改变下:

// 此处依照如上增加 Attributes 批改,具体批改依照我的项目具体情况
private func addItem(username: String, age: Int16) {
  withAnimation {let newItem = Item(context: viewContext)
    newItem.username = username
    newItem.age = age
    newItem.timestamp = Date()

    do {try viewContext.save()
    } catch {
      // Replace this implementation with code to handle the error appropriately.
      // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
      let nsError = error as NSError
      fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    }
  }
}

3)删除

private func deleteItems(offsets: IndexSet) {
  withAnimation {offsets.map { items[$0] }.forEach(viewContext.delete)

    do {try viewContext.save()
    } catch {
      // Replace this implementation with code to handle the error appropriately.
      // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
      let nsError = error as NSError
      fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    }
  }
}

4)汇总

在默认生成代码中,有一个 toolbar,其在macos 中能够失效,然而在 ios 中只有 EditionButton() 能够应用,为了不便演示,此处新增一个 Button 来增加数据。

其次有点要申明下,在 xcode 中写代码时,右侧的 canvas 会实时渲染,列表中呈现的数据并不是 core data 中的数据,而是默认生成的 Persistence.swift 中生成的演示数据,只能看看,不能当真。只有在模拟器 / 实体机编译运行时能力操作core data

如下为批改过后的 ContentView.swift 文件:

//
//  ContentView.swift
//  HelloKuari
//
//  Created by Kuari on 2021/6/5.
//

import SwiftUI
import CoreData

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

    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        
        VStack {
            List {ForEach(items) { item in
                    Text("Tom: \(item.username!) age: \(item.age) time :  \(item.timestamp!, formatter: itemFormatter)")
                }
                .onDelete(perform: deleteItems)
            }
            
            // 新增一个按钮来增加数据
            Button(action: {addItem(username: "tom", age: 12)
            }, label: {Text("Add Item")
            })
        }

    }

    private func addItem(username: String, age: Int16) {
        withAnimation {let newItem = Item(context: viewContext)
            newItem.username = username
            newItem.age = age
            newItem.timestamp = Date()

            do {try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {offsets.map { items[$0] }.forEach(viewContext.delete)

            do {try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
}

private let itemFormatter: DateFormatter = {let formatter = DateFormatter()
    formatter.dateStyle = .short
    formatter.timeStyle = .medium
    return formatter
}()

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

而后点击左侧顶部的运行按钮,编译运行。

一开始是空白一片,点击 Add Item 按钮之后,便会开始增加数据。

对于记录右滑即可删除,其为 ListonDelete办法。

四. 原文链接

https://github.com/Kuari/Blog…

五. 结语

该文章是面向老手的,也是记录下我踩过的坑,因为目前文档匮乏,身边也没 swift 的开发小伙伴儿,只能靠本人摸索,若有大佬有更好的办法,真的还请不吝赐教。

前面继续记录踩坑中 ……

退出移动版