Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/119.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 确定可以存储在UserDefaults中的Swift类型_Ios_Swift_Macos_Plist_Userdefaults - Fatal编程技术网

Ios 确定可以存储在UserDefaults中的Swift类型

Ios 确定可以存储在UserDefaults中的Swift类型,ios,swift,macos,plist,userdefaults,Ios,Swift,Macos,Plist,Userdefaults,我正处于发展的初级阶段 当我在[String:Any]的字典中添加非数据类型时,遇到了一个问题 我需要能够在提交数据之前检查数据,因为该方法不会抛出任何错误。它只是崩溃了 因此,我想确保我提交的字典是犹太的 我不能只检查它是否是可编码的,因为它有时会说它不是,而结构实际上是好的。(这是一本字典,我可以把各种东西塞进里面) 我需要验证字典是否可以生成plist。如果这是ObjC,我可能会使用其中一种方法来测试字典,但这组方法似乎对Swift不可用 根据,有一组特定的类型和类是“plist stud

我正处于发展的初级阶段

当我在
[String:Any]
字典中添加非数据类型时,遇到了一个问题

我需要能够在提交数据之前检查数据,因为该方法不会抛出任何错误。它只是崩溃了

因此,我想确保我提交的
字典
是犹太的

我不能只检查它是否是可编码的,因为它有时会说它不是,而结构实际上是好的。(这是一本
字典
,我可以把各种东西塞进里面)


我需要验证
字典
是否可以生成plist。如果这是ObjC,我可能会使用其中一种方法来测试
字典
,但这组方法似乎对Swift不可用

根据,有一组特定的类型和类是“plist studly”

我认为测试列表中的每种类型都是不可接受的。我需要看看我是否能找到一种在苹果第一次更新操作系统时不会出错的测试方法


有没有一种好的方法来测试
字典
,看看它是否会呕吐?

UserDefaults的属性列表类型集非常有限。支持的类型包括

  • NSString
    → Swift
    String
  • NSNumber
    → Swift
    Int
    Double
    Bool
  • NSDate
    → Swift
    日期
  • NSData
    → Swift
    数据
  • 包含4种值类型的数组和字典
Any
不受支持,除非它表示4种值或2种集合类型之一

可以使用
PropertyListSerialization
(即使在Swift中)将符合属性列表的集合类型写入
UserDefaults


有两种协议可以将自定义类型序列化为
数据

  • Codable
    可以序列化结构和类
  • NSCoding
    可以序列化
    NSObject
    的子类
结构/类中的所有类型都必须是可编码和可解码的(表示符合协议本身)



PropertyListSerialization
/
PropertyListCoder/-Decoder
NSKeyed(Un)Archiver
的API提供了健壮的错误处理以避免崩溃。

更新[1]:而且,仅仅因为我喜欢分享

更新:。尽管我仔细检查了瓦迪安的优秀答案,但我还是决定变得更挑剔一点

感谢matt指出我在错误的沙发垫下找钥匙,我找到了Swift的变种,我用它来检查树的顶部。我怀疑在我完成之前,我需要将它重构成一个递归爬虫程序,但现在这是可行的

以下是撰写本文时的
\u save()
方法的代码。它的工作原理是:

/* ################################################################## */
/**
 This is a private method that saves the current contents of the _values Dictionary to persistent storage, keyed by the value of the "key" property.

 - throws: An error, if the values are not all codable.
 */
private func _save() throws {
    #if DEBUG
        print("Saving Prefs: \(String(describing: _values))")
    #endif

    // What we do here, is "scrub" the values of anything that was added against what is expected.
    var temporaryDict: [String: Any] = [:]
    keys.forEach {
        temporaryDict[$0] = _values[$0]
    }
    _values = temporaryDict

    if PropertyListSerialization.propertyList(_values, isValidFor: .xml) {
        UserDefaults.standard.set(_values, forKey: key)
    } else {
        #if DEBUG
            print("Attempt to set non-codable values!")
        #endif

        // What we do here, is look through our values list, and record the keys of the elements that are not considered Codable. We return those in the error that we throw.
        var valueElementList: [String] = []
        _values.forEach {
            if PropertyListSerialization.propertyList($0.value, isValidFor: .xml) {
                #if DEBUG
                    print("\($0.key) is OK")
                #endif
            } else {
                #if DEBUG
                    print("\($0.key) is not Codable")
                #endif
                valueElementList.append($0.key)
            }
        }
        throw PrefsError.valuesNotCodable(invalidElements: valueElementList)
    }
}

[String:Any]
从不符合
Codable
,因为
Any
不符合,所以您不需要测试任何东西。也许您应该将数据存储在结构或类中,而不是字典中。问题是它不需要可编码。[String:Any]很容易成为NSDictionary,这很好。我使用这种通用类型是有原因的。我正在创建一个相当通用的基类,它允许子类在值字典中存储他们想要的任何内容。因此,我希望能够做的是,在字典发送之前检查它,这样我就可以在不破坏程序的情况下查找和报告问题。我可以让它崩溃,因为这不太可能是运行时问题,但我能为工具的用户提供的帮助越多越好。“如果这是ObjC,我可能会使用其中一个NSPropertyListSerialization方法来测试字典,但这组方法似乎对Swift不可用。”你能进一步解释吗?在我看来,这些方法不可用。我会检查一下。谢谢我不会做递归兔子洞的事情。我将让顶级键告诉实现者在哪里查找问题。这似乎很有效。