在我的iOS应用中暂时自定义对象的最佳方法是什么?通过“暂时”,我的意思是当应用程序关闭时,对象“消失”。
还有其他选择吗?
CoreData的苹果文档似乎是一个很好的起点,如果这是可行的方法,但在查看这些示例后,我甚至无法编译它们。
*更新的解决方案* 毕竟我决定选择一个单身人士......
// Where userDto inherits NSObject, NSCoding and provides "func encode(with aCoder: NSCoder)" and "init?(coder aDecoder: NSCoder)" methods per the NSCoding protocol.
// Store
PersistenceManager.instance.store(userDto)
PersistenceManager.instance.storeTemporary(userDto)
// Retrieve
if let dto:UserDto = PersistenceManager.instance.retrieve() {
// Do something..
}
if let dto:UserDto = PersistenceManager.instance.retrieveTemporary() {
// Do something..
}
import Foundation
import CoreData
final class PersistenceManager {
static let instance = PersistenceManager()
private var localStore = Dictionary<String, NSCoding?>()
private init() {
}
// MARK: -- Store
public func store<T>(_ data:T) where T: NSCoding {
let key = getKey(for: T.self)
let archivedNSCoding:NSData = archive(data)
let userDefaults = UserDefaults.standard
userDefaults.set(archivedNSCoding, forKey: key)
userDefaults.synchronize()
}
public func storeTemporary<T>(_ data:T) where T: NSCoding {
let key = getKey(for: T.self)
localStore[key] = data
}
// MARK: -- Retrieve
public func retrieve<T>() -> T? where T: NSCoding {
let key = getKey(for: T.self)
if let data = UserDefaults.standard.object(forKey: key) as? NSData {
if let unarchived = unarchive(with: data) as? T {
return unarchived
}
}
return nil
}
public func retrieveTemporary<T>() -> T? where T: NSCoding {
let key = getKey(for: T.self)
return localStore[key] as? T
}
// MARK: -- Remove
public func remove<T>(_ type: T.Type) -> T? where T: NSCoding {
if let data:T = retrieve() {
let key = getKey(for: type)
let userDefaults = UserDefaults.standard
userDefaults.removeObject(forKey: key)
userDefaults.synchronize()
return data
} else {
return nil
}
}
public func removeTemporary<T>(_ type: T.Type) -> T? where T: NSCoding {
let key = getKey(for: type)
let data:T? = localStore[key] as? T
localStore.removeValue(forKey: key)
return data
}
// MARK: -- Miscellaneous
public func exists<T>(_ type: T.Type) -> Bool where T: NSCoding {
let key = getKey(for: type)
return UserDefaults.standard.object(forKey: key) != nil
}
private func storeTemporary(data:NSCoding, forKey key: String) {
localStore[key] = data
}
// MARK: -- Helper methods
private func getKey<T>(for type: T.Type) -> String where T: NSCoding {
return String(describing: T.self)
}
private func archive(_ data: NSCoding) -> NSData {
return NSKeyedArchiver.archivedData(withRootObject: data) as NSData
}
private func unarchive(with data: NSData) -> NSCoding? {
if let unarchivedNSCoding = NSKeyedUnarchiver.unarchiveObject(with: data as Data) as? NSCoding {
return unarchivedNSCoding
} else {
return nil
}
}
}
答案 0 :(得分:0)
这取决于你想要达到的目标。如果您的数据集非常小且不会增加太多,那么一旦升级到Swift4,您总是可以尝试使用JSONSerialization
或新的Codable
协议写入JSON文件。
如果你的数据集随着时间的推移而增加,想要在CoreData,SQLite或Realm上做一些更高级的逻辑。我建议看一下Realm,这是一个非常友好的数据库,他们声称它的性能比SQLite好,因此CoreData也是如此。 CoreData使用了SQLite。
使用领域,您可以轻松编写一个对象,并通过简单的调用领域编写,您就完成了。 如果您没有任何SQL经验,那么Realm或CoreData就是您的最佳选择。
我自己不喜欢CoreData,因为我更喜欢访问SQL而且我不喜欢不得不围绕一个全新的系统来解决它有自己的怪癖和想法来处理。它确实可以很好地集成到iOS和Xcode中,这对你来说也是一个很大的优势。
Realm自己的数据库浏览器很好,但是缺乏足够的功能,并且不支持解密加密的Realm数据库(这对我来说真的很奇怪)。 Realm在代码大小方面也相当沉重,但是你可以通过在构建期间运行剥离脚本来摆脱它。
答案 1 :(得分:0)
经过一番说服,我确实决定选择一个单身人士。
在我的特定情况下,我只需要在临时存储中存储几个特定对象类型中的任何一个的1个版本(因此类名作为键)。我还决定可能需要在UserDefaults中存储这些相同对象的选项,所以我也添加了该代码。
<强>用法强>
// Where userDto inherits NSObject, NSCoding and provides "func encode(with aCoder: NSCoder)" and "init?(coder aDecoder: NSCoder)" methods per the NSCoding protocol.
// Store
PersistenceManager.instance.store(userDto)
PersistenceManager.instance.storeTemporary(userDto)
// Retrieve
if let dto:UserDto = PersistenceManager.instance.retrieve() {
// Do something..
}
if let dto:UserDto = PersistenceManager.instance.retrieveTemporary() {
// Do something..
}
import Foundation
import CoreData
final class PersistenceManager {
static let instance = PersistenceManager()
private var localStore = Dictionary<String, NSCoding?>()
private init() {
}
// MARK: -- Store
public func store<T>(_ data:T) where T: NSCoding {
let key = getKey(for: T.self)
let archivedNSCoding:NSData = archive(data)
let userDefaults = UserDefaults.standard
userDefaults.set(archivedNSCoding, forKey: key)
userDefaults.synchronize()
}
public func storeTemporary<T>(_ data:T) where T: NSCoding {
let key = getKey(for: T.self)
localStore[key] = data
}
// MARK: -- Retrieve
public func retrieve<T>() -> T? where T: NSCoding {
let key = getKey(for: T.self)
if let data = UserDefaults.standard.object(forKey: key) as? NSData {
if let unarchived = unarchive(with: data) as? T {
return unarchived
}
}
return nil
}
public func retrieveTemporary<T>() -> T? where T: NSCoding {
let key = getKey(for: T.self)
return localStore[key] as? T
}
// MARK: -- Remove
public func remove<T>(_ type: T.Type) -> T? where T: NSCoding {
if let data:T = retrieve() {
let key = getKey(for: type)
let userDefaults = UserDefaults.standard
userDefaults.removeObject(forKey: key)
userDefaults.synchronize()
return data
} else {
return nil
}
}
public func removeTemporary<T>(_ type: T.Type) -> T? where T: NSCoding {
let key = getKey(for: type)
let data:T? = localStore[key] as? T
localStore.removeValue(forKey: key)
return data
}
// MARK: -- Miscellaneous
public func exists<T>(_ type: T.Type) -> Bool where T: NSCoding {
let key = getKey(for: type)
return UserDefaults.standard.object(forKey: key) != nil
}
private func storeTemporary(data:NSCoding, forKey key: String) {
localStore[key] = data
}
// MARK: -- Helper methods
private func getKey<T>(for type: T.Type) -> String where T: NSCoding {
return String(describing: T.self)
}
private func archive(_ data: NSCoding) -> NSData {
return NSKeyedArchiver.archivedData(withRootObject: data) as NSData
}
private func unarchive(with data: NSData) -> NSCoding? {
if let unarchivedNSCoding = NSKeyedUnarchiver.unarchiveObject(with: data as Data) as? NSCoding {
return unarchivedNSCoding
} else {
return nil
}
}
}