Plist 使用可编码和静态变量构造 class
Plist to struct class with codable and static variables
我有一个 Plist,其中包含端点 URL。我想在应用程序打开后读取该 Plist 并将其写入我的 URL 结构,并且我想在任何地方访问这些 URL。因此,变量需要是静态的。但是,当我执行 var's static 时,出现以下错误;
'static var' declaration requires an initializer expression or getter/setter specifier.
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)
}
编辑:除了下面的答案之外,我用下面的代码更改数据初始化 class 以摆脱可选。使用下面的代码,我检查了 plist 和 If return nil when creating init class app won't continue to work;
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!
但我仍然不确定这是否是最佳方法。如下所述 post;
要修复编译器错误,您应该只为静态成员提供一个默认值:
static let urlBaseURL: String = ""
但是,您的代码存在一些主要问题。在可编码结构中使用静态成员不会像您想象的那样工作,因为 coding/encoding 总是在结构的 实例 上运行,而不是在结构类型本身上运行。
您应该从您的变量中删除 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
请注意,单例模式经常受到批评,而且有充分的理由;对于你的情况,首先我认为没关系。
我有一个 Plist,其中包含端点 URL。我想在应用程序打开后读取该 Plist 并将其写入我的 URL 结构,并且我想在任何地方访问这些 URL。因此,变量需要是静态的。但是,当我执行 var's static 时,出现以下错误;
'static var' declaration requires an initializer expression or getter/setter specifier.
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)
}
编辑:除了下面的答案之外,我用下面的代码更改数据初始化 class 以摆脱可选。使用下面的代码,我检查了 plist 和 If return nil when creating init class app won't continue to work;
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!
但我仍然不确定这是否是最佳方法。如下所述 post;
要修复编译器错误,您应该只为静态成员提供一个默认值:
static let urlBaseURL: String = ""
但是,您的代码存在一些主要问题。在可编码结构中使用静态成员不会像您想象的那样工作,因为 coding/encoding 总是在结构的 实例 上运行,而不是在结构类型本身上运行。
您应该从您的变量中删除 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
请注意,单例模式经常受到批评,而且有充分的理由;对于你的情况,首先我认为没关系。