实战编程·使用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的运作模式。

快来动手试试吧~

相关文章
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
仓颉语言实战分享,教你如何用仓颉开发外卖App界面。内容包括页面布局、导航栏自定义、搜索框实现、列表模块构建等,附完整代码示例。轻松掌握Scroll、List等组件使用技巧,提升HarmonyOS应用开发能力。
|
11月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1874 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
11月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1204 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
11月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1260 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
11月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
504 0
|
12月前
|
运维 iOS开发 Windows
windows电脑备案ios APP获取公钥和证书指纹Sha-1值的方法
在阿里云进行APP备案、在备案IOS端的环节的时候,发现需要我们将p12证书安装在电脑上,再用xcode或或钥匙串访问来获取这个证书的公钥和sha-1值。 但是大部分开发uniapp应用的同学们,或者进行发布的运维人员的电脑都是windows,无法按照阿里云的教程来获取ios的公钥和sha-1。备案就被卡主了。 这里介绍下另一个方法,就是使用香蕉云编来在线上传证书获取。如下图所示,打开香蕉云编后,找到下图这个功能
1481 0
|
缓存 小程序 视频直播
基于uni-app+vite5+vue3实战短视频+直播+聊天app应用
基于uniapp+vue3+vite5从0-1实战搭建仿抖音/微信直播带货商城。集短视频+聊天+直播功能于一体。实现全屏沉浸式切换短视频/直播,支持编译运行到h5+小程序端+app端。
705 4
|
存储 移动开发 监控
App Trace功能实战:一键拉起、快速安装与免提写邀请码的应用实践
App Trace系统通过一键拉起、快速安装和免提写邀请码三大功能,显著提升用户转化率、安装成功率和邀请注册率。结合深度技术实现与优化,助力公司用户增长,成为移动端核心基础设施。
|
数据库 iOS开发 存储
iOS 地址簿编程指南(Address Book Programming Guide for iOS)
iOS 地址簿编程指南(Address Book Programming Guide for iOS) 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
1527 0
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。