如何使用 Swift 5 中的路径取消归档 bundle 中的 plist
how to unarchive plists in bundle using a path in Swift 5
简短版本:
如何使用 unarchivedObject(ofClass:from:)
访问捆绑包中的归档文件以取消归档。核心问题是从路径(字符串或 URL)到方法所需的 Data
。
长版:
我有许多包含 SCNNode 层次结构的 plist,它们存储为 bundle 资源中的 plist。
我能够在 Swift 3 中访问它们:
let fileName = MoleName.DNA_ideal_comps // retrieves String
let filePath = getFilePath(fileName)
guard let components = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as? [SCNNode] , components.count >= 4
else { // no value for this key, or not enough nodes
print("Couldn't find molecule (DNA_ideal_comps)")
return
} // [ atoms_A, bonds_A, atoms_B, bonds_B ]
scaleNode_2 = components[0] // DNA A
fixedNode_2 = components[1] // bonds
scaleNode_3 = components[2] // DNA B
fixedNode_3 = components[3] // bonds
// where filePath is:
func getFilePath(_ fileName: String) -> String {
if let path = Bundle.main.path(forResource: fileName, ofType: "plist") {
return path
}
return "path could not be found"
}
此处 fileName
是要检索的 plist
的名称,在本例中为“DNA_ideal_comps”。由于数据量巨大,我独立于活动程序创建了这些;其中一些 plist 包含超过 30,000 个项目,总共大约有 90 个。
上面的取消存档尝试已被弃用,我一直在努力替换它。到目前为止我最好的尝试:
guard let components = NSKeyedUnarchiver.unarchivedObject(ofClass: SCNNode.self, from: moleData), components.count >= 4
但这失败了 无法将类型 'String' 的值转换为预期的参数类型 'Data'。与Swift3中的方法不同,这里似乎没有办法使用对象的路径来检索它。
有没有办法使用这种方法访问这些plists?还有其他更合适的方法吗?
The core issue is going from a path (string or URL) to Data which is required by the method
好吧,这已经足够微不足道了;只需调用从磁盘上的文件读取的数据初始值设定项。然后,您可以通过调用 NSKeyedUnarchiver.unarchivedObject(ofClass: SCNNode.self, from: theData)
.
来解码数据
https://developer.apple.com/documentation/foundation/data/3126626-init
https://developer.apple.com/documentation/foundation/nskeyedunarchiver/2983380-unarchivedobject
但是,我对您为什么要使用 NSKeyedUnarchiver 来读取 plist 文件感到困惑。将使用 PropertyListSerialization 对象读取 plist 文件。
https://developer.apple.com/documentation/foundation/propertylistserialization
简短版本:
如何使用 unarchivedObject(ofClass:from:)
访问捆绑包中的归档文件以取消归档。核心问题是从路径(字符串或 URL)到方法所需的 Data
。
长版: 我有许多包含 SCNNode 层次结构的 plist,它们存储为 bundle 资源中的 plist。
let fileName = MoleName.DNA_ideal_comps // retrieves String
let filePath = getFilePath(fileName)
guard let components = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as? [SCNNode] , components.count >= 4
else { // no value for this key, or not enough nodes
print("Couldn't find molecule (DNA_ideal_comps)")
return
} // [ atoms_A, bonds_A, atoms_B, bonds_B ]
scaleNode_2 = components[0] // DNA A
fixedNode_2 = components[1] // bonds
scaleNode_3 = components[2] // DNA B
fixedNode_3 = components[3] // bonds
// where filePath is:
func getFilePath(_ fileName: String) -> String {
if let path = Bundle.main.path(forResource: fileName, ofType: "plist") {
return path
}
return "path could not be found"
}
此处 fileName
是要检索的 plist
的名称,在本例中为“DNA_ideal_comps”。由于数据量巨大,我独立于活动程序创建了这些;其中一些 plist 包含超过 30,000 个项目,总共大约有 90 个。
上面的取消存档尝试已被弃用,我一直在努力替换它。到目前为止我最好的尝试:
guard let components = NSKeyedUnarchiver.unarchivedObject(ofClass: SCNNode.self, from: moleData), components.count >= 4
但这失败了 无法将类型 'String' 的值转换为预期的参数类型 'Data'。与Swift3中的方法不同,这里似乎没有办法使用对象的路径来检索它。
有没有办法使用这种方法访问这些plists?还有其他更合适的方法吗?
The core issue is going from a path (string or URL) to Data which is required by the method
好吧,这已经足够微不足道了;只需调用从磁盘上的文件读取的数据初始值设定项。然后,您可以通过调用 NSKeyedUnarchiver.unarchivedObject(ofClass: SCNNode.self, from: theData)
.
https://developer.apple.com/documentation/foundation/data/3126626-init
https://developer.apple.com/documentation/foundation/nskeyedunarchiver/2983380-unarchivedobject
但是,我对您为什么要使用 NSKeyedUnarchiver 来读取 plist 文件感到困惑。将使用 PropertyListSerialization 对象读取 plist 文件。
https://developer.apple.com/documentation/foundation/propertylistserialization