实战编程·使用SwiftUI从0到1完成一款iOS笔记App(四)(2)

简介: 实战编程·使用SwiftUI从0到1完成一款iOS笔记App(四)

功能方法

下面我们来创建一些念头笔记用到的方法,在之前的章节中我们实现了新建笔记的功能,但当我们每次重新打开APP时,它又会“恢复”到初始模式,在上一次操作的数据全部清空了。

这是因为我们只是完成了简单的操作而已,而没有实现其核心功能,即把数据存起来。但是我们没有数据库也没有云端,数据存在哪里呢?是的,放在本地,放到本地缓存起来。

在我们创建iOS项目时,系统会创建一个plist文件,作为缓存区,我们可以将数据暂时存储在这里。

加载数据

ViewModel类中,我们需要使用到的基本方法如下代码所示:

//初始化
    init() {
        loadItems()
        saveItems()
    }
  // 获取设备上的文档目录路径
    func documentsDirectory() -> URL {
        FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    }
    // 获取plist数据文件的路径
    func dataFilePath() -> URL {
        documentsDirectory().appendingPathComponent("IdeaNote.plist")
    }
    // 将数据写入本地存储
    func saveItems() {
        let encoder = PropertyListEncoder()
        do {
            let data = try encoder.encode(noteModels)
            try data.write(to: dataFilePath(), options: Data.WritingOptions.atomic)
        } catch {
            print("Error writing items to file: (error.localizedDescription)")
        }
    }
    // 从本地存储加载数据
    func loadItems() {
        let path = dataFilePath()
        if let data = try? Data(contentsOf: path) {
            let decoder = PropertyListDecoder()
            do {
                noteModels = try decoder.decode([NoteModel].self, from: data)
            } catch {
                print("Error reading items: (error.localizedDescription)")
            }
        }
    }

image.png

上述代码中,首先创建了一个方法documentsDirectory获取设备上的文档目录路径,再指定要获取的目录IdeaNote.plist的方法dataFilePath

获得本地设备目录后,使用saveItems方法将noteModels数组中的数据写入到到本地存储中,当App打开的时候,使用loadItems方法让List列表从本地存储中加载数据遍历列表。

最后在我们App初始化加载的时候,调用loadItems加载数据方法,并调用saveItems方法将数据写入缓存中。

以上是加载本地数据的基本方法。

增删改查

紧接着,我们来实现念头笔记的增删改查的基本方法,如下代码所示:

// 创建笔记
    func addItem(writeTime: String, title: String, content: String) {
        let newItem = NoteModel(writeTime: writeTime, title: title, content: content)
        noteModels.append(newItem)
        saveItems()
    }
    // 获得数据项ID
    func getItemById(itemId: UUID) -> NoteModel? {
        return noteModels.first(where: { $0.id == itemId }) ?? nil
    }
    // 删除笔记
    func deleteItem(itemId: UUID) {
        noteModels.removeAll(where: { $0.id == itemId })
        saveItems()
    }
    // 编辑笔记
    func editItem(item: NoteModel) {
        if let id = noteModels.firstIndex(where: { $0.id == item.id }) {
            noteModels[id] = item
            saveItems()
        }
    }
    // 搜索笔记
    func searchContet() {
        let query = searchText.lowercased()
        DispatchQueue.global(qos: .background).async {
            let filter = self.noteModels.filter { $0.content.lowercased().contains(query) }
            DispatchQueue.main.async {
                self.noteModels = filter
            }
        }
    }

image.png

由于列表中每一行的数据都有对应的ID,因此除了新增数据以外,删改查的基本功能都是通过数据的ID操作的,计算机都是先找到数据,再对数据进行操作。

新建笔记的方法addItem,通过传入对应参数的值,然后将参数的值赋值给NoteModel模型类,再通过append添加的方法添加到noteModels数组中,最后调用saveItems方法保存到本地。

删除笔记的方法deleteItem,需要先获取到指定行数据的ID,这里抽离出了获得数据ID的方法getItemById,通过传入数据ID与NoteModel模型类的ID进行匹配就可以知道是哪一条数据,再调用removeAll删除noteModels数组中指定ID的数据,最后调用saveItems方法保存操作。

编辑笔记的方法editItem,也是传入符合NoteModel模型类的数据,找到它的ID,最后调用saveItems方法保存到本地。

搜索笔记的方法searchContet,先定义用户搜索内容为searchText,再拿用户输入的内容和noteModels数组中的content内容数据做对比,如果符合,就返回符合的数据到noteModels数组中。

其他方法

除此之外,我们将原来在新建笔记页面使用到的获得当前时间的方法,包括判断输入内容是否为空的方法也纳入到ViewModel里面,如下代码所示 :

// 获取当前系统时间
    func getCurrentTime() -> String {
        let dateformatter = DateFormatter()
        dateformatter.dateFormat = "YYYY.MM.dd"
        return dateformatter.string(from: Date())
    }
    // 判断文字是否为空
    func isTextEmpty(text:String) -> Bool{
        if text == "" {
            return true
        } else {
            return false
        }
    }

image.png

判断内容是否为空的方法是传入一个参数值,通过判断是否为空,从而返回一个Bool类型的值,后面我们用来判断输入的标题和内容是否为空。

App使用

创建好ViewModel后,当我们要使用它,需要在IdeaNoteApp项目页面声明好使用的ViewModel,如下代码所示:

import SwiftUI
@main
struct IdeaNoteApp: App {
    @StateObject  var viewModel: ViewModel = ViewModel()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(viewModel)
        }
    }
}

image.png

IdeaNoteApp页面是整个App启动时的页面,它相当于我们的主函数,当前项目指向的首页是ContentView首页视图,因此在使用MVVM项目开发模式时,当我们用使用到ViewModel时,就需要引用ViewModel到主函数中方可使用。

本章小结

恭喜你,准备工作已经就绪,随时可以开始下一步的内容。

当然,为了让大家更好地吸收学习内容,本章我们就分享了如何完成Model、View Model部分,下一章节中,我们将继续完成View视图的相关内容,我们将在原来View视图的基础上进行内容调整,方便大家更好地理解SwiftUI的运作模式。

快来动手试试吧~

相关文章
|
5天前
|
运维 iOS开发 Windows
windows电脑备案ios APP获取公钥和证书指纹Sha-1值的方法
在阿里云进行APP备案、在备案IOS端的环节的时候,发现需要我们将p12证书安装在电脑上,再用xcode或或钥匙串访问来获取这个证书的公钥和sha-1值。 但是大部分开发uniapp应用的同学们,或者进行发布的运维人员的电脑都是windows,无法按照阿里云的教程来获取ios的公钥和sha-1。备案就被卡主了。 这里介绍下另一个方法,就是使用香蕉云编来在线上传证书获取。如下图所示,打开香蕉云编后,找到下图这个功能
95 0
|
2月前
|
缓存 小程序 视频直播
基于uni-app+vite5+vue3实战短视频+直播+聊天app应用
基于uniapp+vue3+vite5从0-1实战搭建仿抖音/微信直播带货商城。集短视频+聊天+直播功能于一体。实现全屏沉浸式切换短视频/直播,支持编译运行到h5+小程序端+app端。
237 4
|
2月前
|
人工智能 IDE 前端开发
写给尊贵的 Tare Pro 用户的喂饭级 IOS APP 开发指南
本文介绍了如何利用 AI IDE Trae,从零开始快速开发一个 iOS 应用《回声》。通过 AI 辅助完成需求梳理、原型设计、编码与调试,展示了 AI 在整个开发流程中的强大助力。
227 0
|
2月前
|
存储 移动开发 监控
App Trace功能实战:一键拉起、快速安装与免提写邀请码的应用实践
App Trace系统通过一键拉起、快速安装和免提写邀请码三大功能,显著提升用户转化率、安装成功率和邀请注册率。结合深度技术实现与优化,助力公司用户增长,成为移动端核心基础设施。
|
6月前
|
Swift iOS开发 开发者
苹果app上架-ios上架苹果商店app store 之苹果支付In - App Purchase内购配置-优雅草卓伊凡
苹果app上架-ios上架苹果商店app store 之苹果支付In - App Purchase内购配置-优雅草卓伊凡
628 13
苹果app上架-ios上架苹果商店app store 之苹果支付In - App Purchase内购配置-优雅草卓伊凡
|
6月前
|
存储 数据安全/隐私保护 开发者
苹果app上架app store 之苹果开发者账户在mac电脑上如何使用钥匙串访问-发行-APP发布证书ios_distribution.cer-优雅草卓伊凡
苹果app上架app store 之苹果开发者账户在mac电脑上如何使用钥匙串访问-发行-APP发布证书ios_distribution.cer-优雅草卓伊凡
225 8
苹果app上架app store 之苹果开发者账户在mac电脑上如何使用钥匙串访问-发行-APP发布证书ios_distribution.cer-优雅草卓伊凡
|
7月前
|
人工智能 程序员 API
iOS|记一名 iOS 开发新手的前两次 App 审核经历
啥,这玩意也有新手保护期?
147 0
|
移动开发 开发工具 数据安全/隐私保护
iOS APP 版本更新升级教程:如何打包上架新的 APP 版本?
iOS APP 版本更新升级教程:如何打包上架新的 APP 版本?
iOS APP 版本更新升级教程:如何打包上架新的 APP 版本?
|
安全 网络安全 数据安全/隐私保护
iOS App的打包和上架流程
iOS App的打包和上架流程
|
安全 网络安全 数据安全/隐私保护
iOS App 的打包和上架流程
iOS App 的打包和上架流程

热门文章

最新文章