从Java转iOS开发:基于Firebase获取ExercisePreset对象并存入数组
从Firebase获取ExercisePreset并存储到数组的iOS实现
嘿,从Android转iOS开发Firebase应用确实需要适应一下语法和API差异,不过别担心,我帮你把Java的ExercisePreset模型转换成Swift版本,并且实现从Firebase获取数据存入数组的逻辑,分两种常见的数据库类型给你说明:
一、Firebase Realtime Database 版本
1. 定义Swift版模型
对应你Java里的模型,我们用@Ignore标记不需要上传到数据库的selected属性(和Java的@Exclude作用一致),同时实现从数据库快照初始化的方法:
import FirebaseDatabase class ExercisePreset { var key: String? var name: String? var type: String = "Dynamic" var progressions: [String] = [] // 本地状态,不存入数据库 @Ignore var selected: Bool = false // 空初始化方法,Firebase需要 init() {} // 自定义便捷初始化方法 convenience init(name: String, type: String) { self.init() self.name = name self.type = type } // 从Realtime Database快照解析模型 init?(snapshot: DataSnapshot) { guard let valueDict = snapshot.value as? [String: Any] else { return nil } self.key = snapshot.key self.name = valueDict["name"] as? String // 给type设置默认值,避免数据库里没有该字段时出错 self.type = valueDict["type"] as? String ?? "Dynamic" self.progressions = valueDict["progressions"] as? [String] ?? [] // selected默认是false,不需要从数据库读取 } }
2. 从数据库获取数据并存入数组
假设你的数据存放在Realtime Database的exercisePresets节点下,以下是获取数据的方法:
// 初始化数据库引用 let presetsRef = Database.database().reference().child("exercisePresets") // 存储所有预设的数组 var exercisePresets: [ExercisePreset] = [] func fetchAllExercisePresets() { // 监听节点的value变化(实时更新),如果只需要单次获取可以用observeSingleEvent presetsRef.observe(.value) { [weak self] snapshot in guard let self = self else { return } self.exercisePresets.removeAll() // 遍历所有子节点 for childSnapshot in snapshot.children { if let presetSnapshot = childSnapshot as? DataSnapshot, let preset = ExercisePreset(snapshot: presetSnapshot) { self.exercisePresets.append(preset) } } // 数据加载完成,这里可以刷新UI或者执行后续逻辑 print("成功加载\(self.exercisePresets.count)个运动预设") } }
二、Firebase Firestore 版本
如果你的数据是存在Firestore里,模型和获取逻辑会稍有不同,我们可以利用Firebase的Codable支持来简化解析:
1. 定义Swift版模型
用@DocumentID对应Java里的key,@Exclude标记本地状态的selected:
import FirebaseFirestore import FirebaseFirestoreSwift struct ExercisePreset: Codable { // 对应文档ID,相当于Java里的key @DocumentID var id: String? var name: String? var type: String = "Dynamic" var progressions: [String] = [] // 本地状态,不存入Firestore @Exclude var selected: Bool = false init() {} convenience init(name: String, type: String) { self.init() self.name = name self.type = type } }
2. 从Firestore获取数据并存入数组
假设你的数据存放在exercisePresets集合下:
// 初始化Firestore引用 let db = Firestore.firestore() let presetsCollection = db.collection("exercisePresets") // 存储所有预设的数组 var exercisePresets: [ExercisePreset] = [] func fetchAllExercisePresets() { // 单次获取集合所有文档,如果需要实时监听可以用addSnapshotListener presetsCollection.getDocuments { [weak self] snapshot, error in guard let self = self else { return } guard let snapshot = snapshot, error == nil else { print("获取数据失败:\(error?.localizedDescription ?? "未知错误")") return } // 解析所有文档为ExercisePreset对象 self.exercisePresets = snapshot.documents.compactMap { document in do { return try document.data(as: ExercisePreset.self) } catch { print("解析文档失败:\(error)") return nil } } // 数据加载完成,执行后续逻辑 print("成功加载\(self.exercisePresets.count)个运动预设") } }
一些注意事项
- 确保你已经完成iOS项目的Firebase配置:添加
GoogleService-Info.plist文件,在AppDelegate或SceneDelegate里初始化FirebaseApp.configure() - 检查数据库的读写权限,避免因权限不足导致无法获取数据
- 如果需要实时监听数据变化,Realtime Database可以保持
observe(.value),Firestore可以替换getDocuments为addSnapshotListener selected属性是本地状态,不会被同步到数据库,和你Java里的@Exclude效果完全一致
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

