使用可编码和静态变量的 Plist 结构类

Posted

技术标签:

【中文标题】使用可编码和静态变量的 Plist 结构类【英文标题】:Plist to struct class with codable and static variables 【发布时间】:2018-01-23 07:44:52 【问题描述】:

我有一个 Plist,其中包含端点 URL。我想在应用程序打开后阅读该 Plist 并将其写入我的 URL 结构,并且我想在任何地方访问这些 URL。因此,变量需要是静态的。但是,当我做 var's static 我得到以下错误;

'static var' 声明需要初始化表达式或 getter/setter 说明符。

struct URLs: Codable 
        static let urlBaseURL: String
        static let urlCheckCMS: String
        static let urlJSON: String

        enum CodingKeys: String, CodingKey 
            case urlBaseURL = "url_base_url"
            case urlCheckCMS = "url_check_cms"
            case urlJSON = "url_json"
        
    

    // MARK: Convenience initializers

    extension URLs 
        init?(data: Data) 
            guard let me = try? PropertyListDecoder().decode(URLs.self, from: data) else  return nil 
            self = me
        

        init?(_ plist: String, using encoding: String.Encoding = .utf8) 
            guard let data = plist.data(using: encoding) else  return nil 
            self.init(data: data)
        

        init?(fromURL url: String) 
            guard let url = URL(string: url) else  return nil 
            guard let data = try? Data(contentsOf: url) else  return nil 
            self.init(data: data)
        

        var plistData: Data? 
            return try? JSONEncoder().encode(self)
        

        var plist: String? 
            guard let data = self.plistData else  return nil 
            return String(data: data, encoding: .utf8)
        

编辑:除了下面的答案,我用下面的代码更改数据初始化类以摆脱可选。使用下面的代码,我检查 plist 并且如果在创建初始化类应用程序时返回 nil 将无法继续工作;

    init?(data: Data) 
    guard let me = try? PropertyListDecoder().decode(URLs.self, from: data) else  return nil 
    self = me
    URLs.instance = me

static var instance: URLs!

但我仍然不确定这是否是最好的方法。如下文所述;

Loading Configurations from plist into singleton

【问题讨论】:

【参考方案1】:

要修复你的编译器错误,你应该为你的静态成员提供一个默认值:

static let urlBaseURL: String = ""

但是,您的代码存在一些主要问题。在可编码结构中使用静态成员不会像您想象的那样工作,因为编码/编码总是在结构的 instances 上运行,而不是在结构类型本身上运行。

您应该从您的变量中删除static,而是提供一个URLs 的单例实例,然后可以从您应用的所有组件中读取该实例:

struct URLs: Codable 
  static var instance? = nil
  let urlBaseURL: String
  let urlCheckCMS: String
  let urlJSON: String

在您的启动代码中,您可以设置值:

URLs.instance = URLs(data: yourData)

稍后您可以通过以下方式访问这些值:

let urlBaseURL = URLs.instance?.urlBaseURL

请注意,单例模式经常受到批评,这是有充分理由的;在你的情况下,首先我认为没关系。

【讨论】:

我编辑我的问题。请你再检查一次。谢谢你:) 关于您添加的链接:他们主要讨论您是否应该为您的设置命名和键入访问属性(在您的情况下:urlBaseURLurlCheckCMS,...),或者更确切地说,使用通用的value(forKey:) 样式,调用者负责知道值的名称和类型。在您的情况下,IMO 不是一个问题——您的设置对象中目前只有三个 URL,而 Swift 的 Codable 系统消除了手动保持名称、查找键和类型同步的大部分痛苦。所以我认为你很高兴:)

以上是关于使用可编码和静态变量的 Plist 结构类的主要内容,如果未能解决你的问题,请参考以下文章

static 关键字

28-关键字:static

Java关键字-static

工具类使用@Value将信息注入到静态变量中

在 C++ 中的 python 类中指定静态变量

java的静态内部类中定义的变量是全局的么?