共计 4872 个字符,预计需要花费 13 分钟才能阅读完成。
一. 前言
这篇文章是我写的第一篇 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
文件,进入页面。
能够看到页面内有默认的 CONFIGURATIONS
为Default
,默认的 ENITITIES
为Item
,能够了解为别离对应 sql 中的库和表。
而后点击 Item
,能够看到其字段,有默认的timestamp
字段。
若要新增 ENTITIES
(表),点击底部的Add Entity
按钮即可。
若要新增 Attributes
(字段),点击右侧Attributes
中的 +
即可,留神字段要抉择类型。
比方,此处以默认的 Item
为例,新增 username
和age
两个字段。
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
按钮之后,便会开始增加数据。
对于记录右滑即可删除,其为 List
的onDelete
办法。
四. 原文链接
https://github.com/Kuari/Blog…
五. 结语
该文章是面向老手的,也是记录下我踩过的坑,因为目前文档匮乏,身边也没 swift 的开发小伙伴儿,只能靠本人摸索,若有大佬有更好的办法,真的还请不吝赐教。
前面继续记录踩坑中 ……