一. 前言
这篇文章是我写的第一篇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 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
按钮之后,便会开始增加数据。
对于记录右滑即可删除,其为List
的onDelete
办法。
四. 原文链接
https://github.com/Kuari/Blog...
五. 结语
该文章是面向老手的,也是记录下我踩过的坑,因为目前文档匮乏,身边也没swift的开发小伙伴儿,只能靠本人摸索,若有大佬有更好的办法,真的还请不吝赐教。
前面继续记录踩坑中......