Swift 在运行时为项目创建类别(类 + 属性)

Swift Create Categories for Items (Classes + Attributes) at runtime

我有一个问题,我自己无法弄清楚或找不到任何答案:

我正在为我的公司创建一个 inventar 应用程序,我希望人们能够为新项目创建类别,如本例所示:

Create category at runtime (German Inventar Program)

我的问题是我使用 firebase 作为后端 - 当然 - 上传存储项目的所有属性,而每个项目都属于具有预定义属性的类别。当我想使用这些项目时,我从 firebase 下载该项目并从我在编译时硬编码的 class 创建一个具有这些特定属性的对象。

我不想在编译时对 class 进行硬编码并更改所有函数和 if-else 块,我正在检查项目的实际类别。现在 - 添加新类别时 - 我必须更改代码中的至少 50 个位置才能使其正常工作...

为了更好地理解,这里是一个类别的函数,它从 firebase 下载所有项目:

func downloadMiscsFromFirebase(handler: @escaping (_ miscs: [Miscellaneous]) -> ()) {
    var miscs = [Miscellaneous]()
    DataService.instance.hardwareRef.child(category).observeSingleEvent(of: .value) { (snapshot) in
        if let snapshots = snapshot.children.allObjects as? [DataSnapshot] {
            for snap in snapshots {
                let description = snap.childSnapshot(forPath: FirebaseIDs.Item.description).value as! String
                let category = snap.childSnapshot(forPath: FirebaseIDs.Item.category).value as! String
                let lfdNr = snap.childSnapshot(forPath: FirebaseIDs.Item.lfdNr).value as! Int
                let fromTeam = snap.childSnapshot(forPath: FirebaseIDs.Item.fromTeam).value as! String

                let hw = snap.childSnapshot(forPath: FirebaseIDs.Miscellaneous.hw).value as! String
                let sw = snap.childSnapshot(forPath: FirebaseIDs.Miscellaneous.sw).value as! String
                let other = snap.childSnapshot(forPath: FirebaseIDs.Miscellaneous.other).value as! String
                let givenOut = snap.childSnapshot(forPath: FirebaseIDs.Item.givenOut).value as? Bool
                let givenTo = snap.childSnapshot(forPath: FirebaseIDs.Item.givenTo).value as? String
                let givenAt = snap.childSnapshot(forPath: FirebaseIDs.Item.givenAt).value as? String
                let givenUntil = snap.childSnapshot(forPath: FirebaseIDs.Item.givenUntil).value as? String
                let storageLocation = snap.childSnapshot(forPath: FirebaseIDs.Item.storageLocation).value as? String

                let misc = Miscellaneous(UID: snap.key,
                                          lfdNr: lfdNr,
                                          description: description,
                                          category: category,
                                          fromTeam: fromTeam,
                                          hw: hw,
                                          sw: sw,
                                          other: other,
                                          givenOut: givenOut,
                                          givenTo: givenTo,
                                          givenAt: givenAt,
                                          givenUntil: givenUntil,
                                          storageLocation: storageLocation)

                // Only add item if from the same team.
                if fromTeam == self.fromTeam {
                    miscs.append(misc)
                }

            }
            handler(miscs)
        }
    }
}

提前致谢!

我会创建一个通用的 CategoryDe​​finition class/struct 和一个类似于

的类别 class/struct
class CategoryDefinition {
    var categoryName: String
    var fields: [String: FieldType] //Dictionary with field definitions
}

class Category {
    var values: [String: Any?] //Dictionary with field values
}

然后两个函数将 Firebase 格式转换为 Firebase 格式。

为了更灵活地使用它,我将有一个具有我提到的属性和功能的协议。让 Factory class 从 CategoryDe​​finition 生成 Category 实例是有意义的。

上面的 FieldType 是我编造的枚举,因为我假设您有 pre-defined 组数据类型-