首页 > 解决方案 > 简化 Swift 数据结构

问题描述

有关如何简化此数据结构的任何建议?数据将保存为用户驱动器上的字典,当我从驱动器读取数据时,我必须将它们转换回Member以便轻松访问属性。

我想让它类型安全。

struct Member {
    var id: Int
    var firstname: String
    var lastname: String
    var address: String?
    var zipCode: Int?
    var city: String?

    enum Value: String {
        case id = "id"
        case firstname = "firstname"
        case lastname = "lastname"
        case address = "address"
        case zipCode = "zipCode"
        case city = "city"
    }

    var member: [String:Any] {
        return [
            Value.id.rawValue:Int(),
            Value.firstname.rawValue:firstname,
            Value.lastname.rawValue:lastname,
            Value.address.rawValue:address ?? String(),
            Value.zipCode.rawValue:zipCode ?? Int(),
            Value.city.rawValue:city ?? String()
        ]
    }
}

func memberToDic(member: Member) -> [String:Any] {
    return [
        Member.Value.firstname.rawValue:member.firstname,
        Member.Value.lastname.rawValue:member.lastname,
        Member.Value.address.rawValue:member.address ?? String(),
        Member.Value.zipCode.rawValue:member.zipCode ?? Int(),
        Member.Value.city.rawValue:member.city ?? String()
    ]
}

func dicToMember(dic: [String:Any]) -> Member {
    return Member(
        id: dic[Member.Value.id.rawValue] as! Int,
        firstname: dic[Member.Value.firstname.rawValue] as! String,
        lastname: dic[Member.Value.lastname.rawValue] as! String,
        address: dic[Member.Value.address.rawValue] as? String,
        zipCode: dic[Member.Value.zipCode.rawValue] as? Int,
        city: dic[Member.Value.city.rawValue] as? String
    )
}

标签: swiftstruct

解决方案


几乎可以肯定,这是正确的实现:

struct Member: Codable {
    var id: Int
    var firstName: String // "first name" is two words, so capitalize "name"
    var lastName: String
    var address: String   // "No address" should be empty, not nil
    var zipCode: String   // ZIP codes are not integers
    var city: String      // "No city" should be empty, not nil
}

为了将其保存为 plist,请使用 PropertyListEncoder:

let data = try PropertyListEncoder().encode(member)

要阅读它,请使用 PropertyListDecoder。

Codable 会自动为您的属性创建键映射,因此不需要 Value。

您应该强烈避免创建或使用[String: Any]字典。这些存在主要是由于 Objective-C 接口无法生成强类型。

如果address,zipCodecityall 应该设置在一起,或者不设置在一起,那么您应该将它们收集到一个结构中:

struct Address: Codable {
    var streetAddress: String
    var zipCode: String
    var city: String
}

struct Member: Codable {
    var id: Int
    var firstName: String // "first name" is two words, so capitalize "name"
    var lastName: String
    var address: Address?
}

在这种情况下,Optional 是有意义的,因为“空”与“缺失”不同。


推荐阅读