关于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的开发小伙伴儿,只能靠本人摸索,若有大佬有更好的办法,真的还请不吝赐教。

前面继续记录踩坑中……

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理