Reputation: 4413
I'm using Xcode 10.2.1, iOS 12.1+, Swift 5
The function below is supposed to read an archived value and return it. You can see the previous code that worked (unarchiveObject) until it was deprecated.
The code works as long as the returned value for 'data' is not nil - meaning that a value has previously been saved. However, in a new installation of the app, this crashes since the value had not been previously saved.
Fatal error: Unexpectedly found nil while unwrapping an Optional value
Since I do not want to preload values, what is the correct way to write this function so that it does not crash?
(It also appears that NSKeyedUnarchiver.unarchiveTopLevelObjectWithData is now deprecated as well with iOS 12+. What would be the correct replacement?)
func color(forKey defaultName: String) -> UIColor? {
var color: UIColor?
// Working code prior to Swift 5 and iOS 12
// if let colorData = data(forKey: defaultName) {
// color = NSKeyedUnarchiver.unarchiveObject(with: colorData) as? UIColor
// }
// Works unless NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data(forKey: defaultName)!) returns nil
do {
if let colorData = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data(forKey: defaultName)!) as? UIColor {
color = colorData
}
} catch {
//print("Couldn't read file.")
}
return color
}
Upvotes: 0
Views: 1461
Reputation: 285064
First of all the replacement of unarchiveObject(with:)
for this case is unarchivedObject(ofClass:from:)
.
Second of all just do the same optional binding like in Working code prior to Swift 5 and iOS 12:
func color(forKey defaultName: String) -> UIColor? {
guard let colorData = data(forKey: defaultName) else { return nil }
return try? NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: colorData)
}
Upvotes: 2