一. 前言

这篇文章是我写的第一篇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 SwiftUIimport CoreDatastruct 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的开发小伙伴儿,只能靠本人摸索,若有大佬有更好的办法,真的还请不吝赐教。

前面继续记录踩坑中......