一. 前言
这篇文章是我写的第一篇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的开发小伙伴儿,只能靠本人摸索,若有大佬有更好的办法,真的还请不吝赐教。
前面继续记录踩坑中……
发表回复