I am working on Xcode 12 and Swift 5 environment to build an iOS application.
I need to store an OpaquePointer type variable("self.loggers" in the code below) before the view disappears(or before the app closes) and retrieve it when the view appears( when the app runs). I tried to use UserDefault as below,
// Storing(In viewWillDisappear)
do {
encodedData = try NSKeyedArchiver.archivedData(withRootObject: self.loggers, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "accelLoggerID")
} catch {
print("archiving error")
}
...
// Retrieving(In viewDidLoad)
if let decodedData = UserDefaults.standard.object(forKey: "acceleration") as? Data {
do {
self.loggers = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as? [String:OpaquePointer] ?? [:]} catch {
print("unarchiving error")
}
} else {
self.loggers = [:]
print("No value in Userdefault. [viewDidLoad]")
}
However, NSKeyedArchiver failed to encode such type. After that, I made a class that wraps the variable.
class LoggerWrapper {
var loggers: [String : OpaquePointer]
init(loggerDic: [String : OpaquePointer]) {
loggers = loggerDic
}
}
And changed my code like
self.loggers = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decodedData) as? LoggerWrapper ?? LoggerWrapper(loggerDic: [:])} catch {
print("unarchiving error")
}
However, this gives SIGABRT when NSKeyedArchiver.archivedData is called. Is there any way to store Opaquepointer type in UserDefaults? If not, can using core data solve this problem?
Thank you.
You probably need to convert the pointers to
Int
bitPatterns. There is an initializer onInt
for that:let intBitPattern = Int(bitPattern: opaquePointer)
. There is also an initializer onOpaquePointer
that takes anInt
bitPattern:let opaquePointer = OpaquePointer(bitPattern: intBitPattern)
. So you would need to convert the values in your dictionary (e.g. usingcompactMapValues
) before storing and after reading it.With a
Dictionary<String, Int>
, you should be able to store it directly in UserDefaults, without the need forNSKeyedArchiver
andNSKeyedUnarchiver
.Sidenote: Pointers aren't "long-lived". So storing it in UserDefaults is only valid during the lifetime of your app. Once your app restarts, the pointers might no longer be valid.