Short version:
How to access an archived file in the bundle for unarchiving with unarchivedObject(ofClass:from:)
. The core issue is going from a path (string or URL) to Data
which is required by the method.
Long version: I have many plists containing SCNNode hierarchies stored as plists in bundle resources.
I was able to access them in Swift 3 with:
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"
}
Here fileName
is the name of the plist
to retrieve, "DNA_ideal_comps" in this example. I created these independently of the active program due to the sheer volume of data; some of these plists contain over 30,000 items and there are about 90 total.
The above attempt to unarchive is deprecated and I've struggled to replace it. My best try so far:
guard let components = NSKeyedUnarchiver.unarchivedObject(ofClass: SCNNode.self, from: moleData), components.count >= 4
But this fails with Cannot convert value of type 'String' to expected argument type 'Data'. Unlike the method in Swift 3, there appears no way here to use the path of the object to retrieve it.
Is there a way to access these plists using this method? Is there another method more appropriate?
The core issue is going from a path (string or URL) to Data which is required by the method
Well, that's trivial enough; just call the Data initializer that reads from a file on disk. You would then decode the Data by calling 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
However, I'm confused as to why you're using NSKeyedUnarchiver to read a plist file. A plist file would be read using a PropertyListSerialization object.
https://developer.apple.com/documentation/foundation/propertylistserialization