【发布时间】:2020-12-13 14:16:22
【问题描述】:
我有一个应用程序和一个Share Extension。他们之间我通过UserDefaults 共享数据。但它突然停止工作。现在只能在Share Extension 中检索bools 或Strings,但是当尝试检索Custom Struct 时,它总是返回nil。
UserDefaults 中的自定义结构 getter/setter:
//MARK: dataSourceArray
func setDataSourceArray(data: [Wishlist]?){
set(try? PropertyListEncoder().encode(data), forKey: Keys.dataSourceKey)
synchronize()
}
func getDataSourceArray() -> [Wishlist]? {
if let data = self.value(forKey: Keys.dataSourceKey) as? Data {
do {
_ = try PropertyListDecoder().decode(Array < Wishlist > .self, from: data) as [Wishlist]
} catch let error {
print(error)
}
if let dataSourceArray =
try? PropertyListDecoder().decode(Array < Wishlist > .self, from: data) as[Wishlist] {
return dataSourceArray
}
}
return nil
}
我在我的Extension 以及我的主应用程序中这样称呼它:
if let defaults = UserDefaults(suiteName: UserDefaults.Keys.groupKey) {
if let data = defaults.getDataSourceArray() {
print("working")
} else {
print("error getting datasourceArray")
}
}
这是在主应用程序中打印“工作”,但在我的Extension 中打印“错误获取 datasourceArray”。我不明白这个问题,特别是因为简单的Bool-Getter 也可以从我的共享扩展中工作,所以问题只在于Custom Struct。
我在这里错过了什么?
Wishlist Struct:
import UIKit
enum PublicState: String, Codable {
case PUBLIC
case PUBLIC_FOR_FRIENDS
case NOT_PUBLIC
}
struct Wishlist: Codable {
var id: String
var name: String
var image: UIImage
var wishes: [Wish]
var color: UIColor
var textColor: UIColor
var index: Int
var publicSate: PublicState
enum CodingKeys: String, CodingKey {
case id, name, image, wishData, color, textColor, index, isPublic, isPublicForFriends, publicSate
}
init(id: String, name: String, image: UIImage, wishes: [Wish], color: UIColor, textColor: UIColor, index: Int, publicSate: PublicState) {
self.id = id
self.name = name
self.image = image
self.wishes = wishes
self.color = color
self.textColor = textColor
self.index = index
self.publicSate = publicSate
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decode(String.self, forKey: .id)
name = try values.decode(String.self, forKey: .name)
wishes = try values.decode([Wish].self, forKey: .wishData)
color = try values.decode(Color.self, forKey: .color).uiColor
textColor = try values.decode(Color.self, forKey: .textColor).uiColor
index = try values.decode(Int.self, forKey: .index)
publicSate = try values.decode(PublicState.self, forKey: .publicSate)
let data = try values.decode(Data.self, forKey: .image)
guard let image = UIImage(data: data) else {
throw DecodingError.dataCorruptedError(forKey: .image, in: values, debugDescription: "Invalid image data")
}
self.image = image
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
try container.encode(wishes, forKey: .wishData)
try container.encode(Color(uiColor: color), forKey: .color)
try container.encode(Color(uiColor: textColor), forKey: .textColor)
try container.encode(index, forKey: .index)
try container.encode(image.pngData(), forKey: .image)
try container.encode(publicSate, forKey: .publicSate)
}
}
更新
这是失败的部分:
if let data = self.value(forKey: Keys.dataSourceKey) as? Data
有什么办法可以catch 和error?
我还发现这个功能实际上也适用于其他用户。该应用已上线:https://apps.apple.com/de/app/wishlists-einfach-w%C3%BCnschen/id1503912334
但这对我不起作用?我卸载了应用程序,从 App Store 下载了它,但它仍然无法运行。
【问题讨论】:
-
不相关但为什么要对属性列表进行两次解码?制作方法
throw那么这就足够了:func getDataSourceArray() throws -> [Wishlist] { guard let data = self.data(forKey: Keys.dataSourceKey) else {return [] } return try PropertyListDecoder().decode([Wishlist].self, from: data) } -
@vadian 好点谢谢,但就像你说的,与这里的主要问题无关:(
标签: ios swift nsuserdefaults ios8-share-extension