处理应用程序创建的一次性不可变数据
Handling one-time immutable data created by app
我正在重写我的应用程序以合并 SceneKit 来显示分子。我大约 60% 的代码致力于将这些分子创建为存储在字典中的 SCNNode
数组。另外 20% 创建了一个 String
字典用于文本显示。理想情况下,这些词典只需要创建一次。
目前,我正在通过来自 viewDidLoad
的调用在我的主(和初始)VC 中创建这些词典。然后我存档字典:
NSKeyedArchiver.archiveRootObject(moleculeDictionary, toFile: filePath)
然后我将存档的字典读回到应用程序使用的本地字典中:
moleculeDictionary = Molecules.readFile() as! [String: [SCNNode]]
// and in Molecules, the readFile() function:
let dictionary = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as? NSDictionary ?? NSDictionary()
return dictionary
我从存档中读取它以防本地版本不再存在。我仍然需要检查字典是否存在。
我的问题:这是最好的方法吗?当然,这是许多程序的共同方面。我倾向于在开发过程中使用这些词典创建永久文件,并将它们包含在发布的包中。但是没有人回应我关于这方面的帖子,所以我认为每个人都以其他方式来做。我祈祷我不必了解 CoreData 但如果是这样,请告诉我。
您可以单独使用场景档案和节点档案,将它们嵌入您的二进制文件中,而不是 archiving/loading 多个节点树的字典数组。
如果是完整场景,请将其放入 Xcode 项目中的 art.scnassets 文件夹中,然后使用
加载它
let scene = SCNScene(named: "art.scnassets/oneMolecule.scn")!
如果您存档了整个场景,包括节点、灯光、相机和动作,那么这是合适的。
您可以使用
仅归档一个节点树
let documentDirURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
if let gizmoNode = gameView.scene?.rootNode.childNodeWithName("Gizmo", recursively:true) {
let gizmoData = NSKeyedArchiver.archivedDataWithRootObject(gizmoNode)
let gizmoURL = documentDirURL.URLByAppendingPathComponent("Gizmo").URLByAppendingPathExtension("plist")
print("gizmo path:", gizmoURL.path)
if (!gizmoData.writeToURL(gizmoURL, atomically: true)) {
return false
}
}
如果您使用辅助 iOS 程序来生成资产,它们将位于模拟器文件层次结构中的 Documents 文件夹中。如果这些是由您的最终产品即时生成的,它们属于缓存或临时文件夹,以便在需要时可以清除它们并且不会备份。
如果您要发布预建节点,请将其像 PNG 一样放入您的项目中。使用
获取
let path = NSBundle.mainBundle().pathForResource("Gizmo", ofType: "plist")
print(path)
let gizmoNode = NSKeyedUnarchiver.unarchiveObjectWithFile(path!) as! SCNNode
print (gizmoNode)
scene.rootNode.addChildNode(gizmoNode)
还有一件事:构建和归档 SCNScenes 和 SCNNode 不需要 SCNView。您可以将节点生成代码提取到独立的命令行 Mac 程序中。构建你的节点树,单独归档它们。然后将它们放入场景中,将其存档,并使用场景编辑器进行预览。您可以自动化整个生成 molecules/copy/build iOS 应用程序的过程。
我正在重写我的应用程序以合并 SceneKit 来显示分子。我大约 60% 的代码致力于将这些分子创建为存储在字典中的 SCNNode
数组。另外 20% 创建了一个 String
字典用于文本显示。理想情况下,这些词典只需要创建一次。
目前,我正在通过来自 viewDidLoad
的调用在我的主(和初始)VC 中创建这些词典。然后我存档字典:
NSKeyedArchiver.archiveRootObject(moleculeDictionary, toFile: filePath)
然后我将存档的字典读回到应用程序使用的本地字典中:
moleculeDictionary = Molecules.readFile() as! [String: [SCNNode]]
// and in Molecules, the readFile() function:
let dictionary = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as? NSDictionary ?? NSDictionary()
return dictionary
我从存档中读取它以防本地版本不再存在。我仍然需要检查字典是否存在。
我的问题:这是最好的方法吗?当然,这是许多程序的共同方面。我倾向于在开发过程中使用这些词典创建永久文件,并将它们包含在发布的包中。但是没有人回应我关于这方面的帖子,所以我认为每个人都以其他方式来做。我祈祷我不必了解 CoreData 但如果是这样,请告诉我。
您可以单独使用场景档案和节点档案,将它们嵌入您的二进制文件中,而不是 archiving/loading 多个节点树的字典数组。
如果是完整场景,请将其放入 Xcode 项目中的 art.scnassets 文件夹中,然后使用
加载它 let scene = SCNScene(named: "art.scnassets/oneMolecule.scn")!
如果您存档了整个场景,包括节点、灯光、相机和动作,那么这是合适的。
您可以使用
仅归档一个节点树let documentDirURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
if let gizmoNode = gameView.scene?.rootNode.childNodeWithName("Gizmo", recursively:true) {
let gizmoData = NSKeyedArchiver.archivedDataWithRootObject(gizmoNode)
let gizmoURL = documentDirURL.URLByAppendingPathComponent("Gizmo").URLByAppendingPathExtension("plist")
print("gizmo path:", gizmoURL.path)
if (!gizmoData.writeToURL(gizmoURL, atomically: true)) {
return false
}
}
如果您使用辅助 iOS 程序来生成资产,它们将位于模拟器文件层次结构中的 Documents 文件夹中。如果这些是由您的最终产品即时生成的,它们属于缓存或临时文件夹,以便在需要时可以清除它们并且不会备份。
如果您要发布预建节点,请将其像 PNG 一样放入您的项目中。使用
获取let path = NSBundle.mainBundle().pathForResource("Gizmo", ofType: "plist")
print(path)
let gizmoNode = NSKeyedUnarchiver.unarchiveObjectWithFile(path!) as! SCNNode
print (gizmoNode)
scene.rootNode.addChildNode(gizmoNode)
还有一件事:构建和归档 SCNScenes 和 SCNNode 不需要 SCNView。您可以将节点生成代码提取到独立的命令行 Mac 程序中。构建你的节点树,单独归档它们。然后将它们放入场景中,将其存档,并使用场景编辑器进行预览。您可以自动化整个生成 molecules/copy/build iOS 应用程序的过程。