iOS Swift 数据管理完整指南
iOS Swift 数据管理完整指南
iOS Swift 数据管理体系
│
├── 1、内存存储 (App关闭数据丢失)
│ ├── @State - 视图内部状态
│ ├── @StateObject - 视图模型
│ └── 单例模式 - 全局数据
│
├── 2、本地持久化存储 (App关闭数据保留)
│ ├── @AppStorage - 简单设置
│ ├── UserDefaults - 键值存储
│ ├── 文件存储 - 文档数据
│ ├── SwiftData - 现代数据库
│ └── SQLite - 关系型数据库
│
└── 3、云端存储
├── CloudKit - 苹果官方后端服务
└── 自建服务器 - 自定义后端服务
1、内存存储
数据保存在设备的内存( RAM )中,当APP关闭或设备重启时,这些数据会丢失。
特点:内存存储的访问速度极快,适合存储临时数据和运行时状态
1.1、@State - 视图内部状态管理
@State 是 SwiftUI 中最基本的状态管理属性包装器,用于管理单个视图的内部状态。它适用于简单的值类型数据,如字符串、整数、布尔值等。
import SwiftUI
struct LoginView: View {
// @State 用于管理视图内部的状态,数据保存在内存中
// 当App关闭时,这些数据会丢失
@State private var username: String = "" // 存储用户名输入
@State private var password: String = "" // 存储密码输入
@State private var rememberMe: Bool = false // 存储记住我选项状态
var body: some View {
Form {
// 文本输入框绑定到username状态
TextField("用户名", text: $username)
.onChange(of: username) { newValue in
// 监听用户名变化并打印日志
print("🧠 @State - 用户名更新: \(newValue)")
}
// 密码输入框绑定到password状态
SecureField("密码", text: $password)
// 开关绑定到rememberMe状态
Toggle("记住我", isOn: $rememberMe)
.onChange(of: rememberMe) { newValue in
// 监听记住我状态变化
print("🧠 @State - 记住我状态: \(newValue)")
}
// 登录按钮
Button("登录") {
// 点击登录按钮时的处理逻辑
print("🧠 @State - 登录操作,用户名: \(username)")
}
}
}
}
1.2、@StateObject - 视图级别状态管理
@StateObject 用于 SwiftUI 中管理更复杂的状态,它适用于复杂的引用类型数据。
import SwiftUI
// ObservableObject协议允许对象被SwiftUI观察,当@Published属性变化时更新视图
class UserSession: ObservableObject {
// @Published属性会在值改变时通知所有观察者
@Published var isLoggedIn: Bool = false // 登录状态
@Published var userProfile: UserProfile? // 用户资料
func login(username: String, password: String) {
// 登录方法,模拟登录过程
print("🧠 @StateObject - 开始登录: \(username)")
// 模拟网络请求延迟
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.isLoggedIn = true
self.userProfile = UserProfile(name: username)
print("🧠 @StateObject - 登录成功")
}
}
}
// 用户资料数据模型
struct UserProfile {
let name: String
var lastLogin: Date = Date() // 默认值为当前时间
}
1.3、单例模式 - 全局应用状态
整个App共享,生命周期与App一致
class AppSettings {
// 静态常量shared是单例实例,整个App中只有这一个实例
static let shared = AppSettings()
// 全局应用设置,所有视图都可以访问
var theme: String = "light" // 应用主题
var language: String = "zh" // 应用语言
// 私有初始化方法,防止外部创建新的实例
private init() {
print("🧠 单例模式 - AppSettings初始化")
}
func updateTheme(_ newTheme: String) {
// 更新主题方法
theme = newTheme
print("🧠 单例模式 - 主题更新为: \(newTheme)")
}
}
2、本地持久化存储
本地持久化存储将数据保存在设备的文件系统中,即使应用程序关闭或设备重启,数据也不会丢失。适合存储用户设置、应用配置和重要业务数据。
2.1、@AppStorage - 简单设置存储
@AppStorage 是 SwiftUI 提供的属性包装器,它封装了 UserDefaults 的使用,让持久化存储变得非常简单直观。
特点:
1、使用简单,类似 @State
2、自动持久化到 UserDefaults
3、支持基本数据类型
4、与 SwiftUI 深度集成
使用场景:
用户偏好设置、简单的应用配置
import SwiftUI
struct SettingsView: View {
// @AppStorage自动将数据保存到UserDefaults,App关闭后数据仍然存在
// "username"是存储的键名,"默认用户"是默认值
@AppStorage("username") private var username = "默认用户"
@AppStorage("isDarkMode") private var isDarkMode = false
@AppStorage("notificationEnabled") private var notificationEnabled = true
var body: some View {
Form {
// 文本输入框,输入的内容会自动保存到UserDefaults
TextField("用户名", text: $username)
.onChange(of: username) { newValue in
// 监听用户名变化,数据会自动持久化
print("💾 @AppStorage - 用户名保存: \(newValue)")
}
// 开关控件,状态会自动保存
Toggle("深色模式", isOn: $isDarkMode)
.onChange(of: isDarkMode) { newValue in
print("💾 @AppStorage - 深色模式: \(newValue)")
}
// 通知开关
Toggle("消息通知", isOn: $notificationEnabled)
}
.onAppear {
// 视图显示时打印当前设置
print("💾 @AppStorage - 加载设置: 用户名=\(username), 深色模式=\(isDarkMode)")
}
}
}
2.2、UserDefaults - 传统的键值存储
UserDefaults 是 Foundation 框架提供的轻量级数据持久化方案,以键值对的形式存储数据。
需要自己管理数据存取,稍复杂一些。
特点:
1、支持基本数据类型和集合
2、线程安全
3、自动序列化/反序列化
4、底层使用 Property List 格式
使用场景:
应用配置信息、用户设置和偏好、小量的结构化数据、简单的缓存数据
class UserDefaultsManager {
// 单例模式,确保只有一个UserDefaults管理器
static let shared = UserDefaultsManager()
// UserDefaults.standard是系统提供的键值存储
private let defaults = UserDefaults.standard
func saveUserProfile(name: String, age: Int, email: String) {
// 创建用户资料字典
let profile: [String: Any] = [
"name": name, // 姓名
"age": age, // 年龄
"email": email, // 邮箱
"lastUpdated": Date() // 最后更新时间
]
// 将字典保存到UserDefaults
defaults.set(profile, forKey: "userProfile")
// 强制立即保存到磁盘
defaults.synchronize()
print("💾 UserDefaults - 用户资料保存成功: \(name)")
}
func loadUserProfile() -> [String: Any]? {
// 从UserDefaults读取用户资料
guard let profile = defaults.dictionary(forKey: "userProfile") else {
print("💾 UserDefaults - 未找到用户资料")
return nil
}
print("💾 UserDefaults - 加载用户资料: \(profile)")
return profile
}
}
2.3、文件存储 - 文档和自定义数据
直接使用文件系统来存储数据,提供最大的灵活性和控制力。
特点:
1、完全控制存储格式
2、支持大文件存储
3、需要手动管理文件路径
4、可以存储任意类型的数据
使用场景:
1、用户文档和文件
2、图片、音频、视频等媒体文件
3、大量的结构化数据
4、需要自定义格式的数据
class FileStorageManager {
static let shared = FileStorageManager()
// 获取应用文档目录的URL
private var documentsURL: URL {
// documentDirectory是保存用户文档的目录
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
}
func saveTextToFile(_ text: String, filename: String) -> Bool {
// 创建文件完整路径
let fileURL = documentsURL.appendingPathComponent(filename)
do {
// 将文本写入文件,atomically:true确保写入操作的原子性
try text.write(to: fileURL, atomically: true, encoding: .utf8)
print("💾 文件存储 - 文本保存成功: \(filename)")
return true
} catch {
// 处理写入错误
print("💾 文件存储 - 保存失败: \(error)")
return false
}
}
func readTextFromFile(filename: String) -> String {
// 创建文件完整路径
let fileURL = documentsURL.appendingPathComponent(filename)
// 尝试读取文件内容,如果失败返回空字符串
guard let content = try? String(contentsOf: fileURL) else {
print("💾 文件存储 - 文件不存在: \(filename)")
return ""
}
print("💾 文件存储 - 文件读取成功: \(filename)")
return content
}
}
2.4、SwiftData - 现代数据库
SwiftData 是 Apple 在 iOS 17 中推出的现代数据持久化框架,它提供了声明式的 API 和强大的类型安全。
特点:
1、Swift 原生语法
2、编译时类型安全
3、自动数据迁移
4、深度 SwiftUI 集成
使用场景:
1、复杂的数据模型和关系
2、需要查询和筛选的数据
3、大量的结构化数据存储
4、需要自动迁移的数据模型
import SwiftData
// @Model宏用于定义数据模型,SwiftData会自动管理持久化
@Model
class Note {
var title: String // 笔记标题
var content: String // 笔记内容
var createdAt: Date // 创建时间
var isFavorite: Bool // 是否收藏
init(title: String, content: String) {
self.title = title
self.content = content
self.createdAt = Date() // 设置创建时间为当前时间
self.isFavorite = false // 默认未收藏
print("💾 SwiftData - 创建Note: \(title)")
}
}
struct NotesApp: View {
// modelContext用于执行数据库操作(增删改查)
@Environment(\.modelContext) private var modelContext
// @Query自动从数据库查询数据,sort指定排序方式
@Query(sort: \Note.createdAt) private var notes: [Note]
var body: some View {
NavigationView {
List(notes) { note in
// 显示每条笔记
VStack(alignment: .leading) {
Text(note.title).font(.headline) // 标题
Text(note.content).font(.body) // 内容
}
}
.navigationTitle("笔记")
}
.onAppear {
// 视图显示时打印笔记数量
print("💾 SwiftData - 加载了 \(notes.count) 条笔记")
}
}
}
2.5、SQLite - 关系型数据库
SQLite 是一个轻量级的、嵌入式的关系型数据库,它不需要单独的服务器进程,整个数据库就是一个单独的文件。在 iOS 开发中,SQLite 是系统内置的数据库引擎。
使用场景:
1、需要复杂查询和关联的数据
2、大量结构化数据的存储
3、需要事务保证的数据操作
4、高性能读写需求的场景(相较于SwiftData性能更高)
import SQLite3
class SQLiteManager {
static let shared = SQLiteManager()
// OpaquePointer是SQLite数据库的指针
private var db: OpaquePointer?
init() {
openDatabase() // 打开数据库连接
createTables() // 创建数据表
}
private func openDatabase() {
// 构建数据库文件路径
let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
.appendingPathComponent("app.db") // 数据库文件名
// 打开数据库连接
if sqlite3_open(fileURL.path, &db) == SQLITE_OK {
print("💾 SQLite - 数据库打开成功")
} else {
print("💾 SQLite - 数据库打开失败")
}
}
private func createTables() {
// SQL语句:创建用户表
let createTableSQL = """
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT, -- 主键,自增
name TEXT NOT NULL, -- 姓名,不能为空
email TEXT UNIQUE NOT NULL -- 邮箱,唯一约束
);
"""
// 执行SQL语句
if sqlite3_exec(db, createTableSQL, nil, nil, nil) == SQLITE_OK {
print("💾 SQLite - 用户表创建成功")
} else {
print("💾 SQLite - 用户表创建失败")
}
}
}
3、云端存储
如果希望数据不受APP卸载影响,可将数据存储在云端。
3.1、CloudKit - 苹果官方后端云服务
苹果官方提供的后端云服务
特点:
1、无服务器架构:无需管理任何服务器基础设施
2、深度集成:与 iOS/macOS 生态系统无缝协作
3、自动同步:跨设备数据自动同步
4、免费额度:每月 10GB 存储 + 50GB 传输 + 200MB 数据库
使用场景:
1、纯苹果生态应用
2、个人开发者或小团队
3、需要快速上线的项目
4、数据模型相对简单
import SwiftUI
import CloudKit
// 数据模型
struct TodoItem: Identifiable {
let id = UUID()
let title: String
let recordID: CKRecord.ID?
}
class CloudKitManager: ObservableObject {
@Published var items: [TodoItem] = []
private let container = CKContainer.default().publicCloudDatabase
// 保存到 CloudKit
func saveItem(_ title: String, completion: @escaping (Bool) -> Void) {
let record = CKRecord(recordType: "TodoItem")
record["title"] = title as CKRecordValue
container.save(record) { [weak self] (record, error) in
DispatchQueue.main.async {
if error == nil, let record = record {
let newItem = TodoItem(title: title, recordID: record.recordID)
self?.items.append(newItem)
completion(true)
} else {
completion(false)
}
}
}
}
// 从 CloudKit 查询数据
func fetchItems() {
let query = CKQuery(recordType: "TodoItem", predicate: NSPredicate(value: true))
container.perform(query, inZoneWith: nil) { [weak self] (records, error) in
guard let records = records, error == nil else { return }
DispatchQueue.main.async {
self?.items = records.compactMap { record in
guard let title = record["title"] as? String else { return nil }
return TodoItem(title: title, recordID: record.recordID)
}
}
}
}
}
// SwiftUI 视图
struct CloudKitView: View {
@StateObject private var manager = CloudKitManager()
@State private var newItemTitle = ""
var body: some View {
VStack {
TextField("输入待办事项", text: $newItemTitle)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
Button("添加") {
manager.saveItem(newItemTitle) { success in
if success { newItemTitle = "" }
}
}
List(manager.items) { item in
Text(item.title)
}
}
.onAppear {
manager.fetchItems()
}
}
}
3.2、自建服务器
特点:
1、完全控制:自主选择技术栈和架构
2、跨平台支持:可为任何平台提供 API
3、功能灵活:可实现任意复杂业务逻辑
4、成本可控:按需选择云服务商和配置
使用场景:
1、需要跨平台支持(Android、Web等)
2、复杂业务逻辑需求
3、企业级应用
4、需要与第三方服务深度集成
5、团队有后端开发能力
//Swift 访问 SpringBoot 接口完整代码示例:
import Foundation
// 用户数据模型
struct User: Codable {
let id: Int?
let name: String
let email: String
}
// 网络请求管理器
class ApiService {
private let baseURL = "http://localhost:8080/api"
// 获取所有用户
func getUsers() async throws -> [User] {
let url = URL(string: "\(baseURL)/users")!
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode([User].self, from: data)
}
// 创建用户
func createUser(name: String, email: String) async throws -> User {
let url = URL(string: "\(baseURL)/users")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let user = User(id: nil, name: name, email: email)
request.httpBody = try JSONEncoder().encode(user)
let (data, _) = try await URLSession.shared.data(for: request)
return try JSONDecoder().decode(User.self, from: data)
}
// 删除用户
func deleteUser(id: Int) async throws {
let url = URL(string: "\(baseURL)/users/\(id)")!
var request = URLRequest(url: url)
request.httpMethod = "DELETE"
_ = try await URLSession.shared.data(for: request)
}
}
// 使用示例
class UserViewModel: ObservableObject {
@Published var users: [User] = []
private let api = ApiService()
func loadUsers() {
Task {
do {
let fetchedUsers = try await api.getUsers()
await MainActor.run {
self.users = fetchedUsers
}
} catch {
print("获取用户失败: \(error)")
}
}
}
func addUser(name: String, email: String) {
Task {
do {
let newUser = try await api.createUser(name: name, email: email)
await MainActor.run {
self.users.append(newUser)
}
} catch {
print("创建用户失败: \(error)")
}
}
}
}
更多推荐


所有评论(0)