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 on Int
for that: let intBitPattern = Int(bitPattern: opaquePointer)
.
There is also an initializer on OpaquePointer
that takes an Int
bitPattern: let opaquePointer = OpaquePointer(bitPattern: intBitPattern)
.
So you would need to convert the values in your dictionary (e.g. using compactMapValues
) before storing and after reading it.
With a Dictionary<String, Int>
, you should be able to store it directly in UserDefaults, without the need for NSKeyedArchiver
and NSKeyedUnarchiver
.
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.