[古いObjective-CからSwift3へ]Swift3のuserDefaultsで苦労したArray
2022.11.10更新
数年間アップデートしていなかったWorkoutTimerをiOS11に対応させる際に、使用言語も変えようと思いSwift3にしました。
Swift自体古いバージョンのものしか使ったことが無かったので、だいぶてこずりました。
中でも一番厄介だったのが、数年前のObjective-CのNSUserDefaultsで保存したNSArray型のデータをSwift3のuserDefsultsで読み出す際に出たエラーの修正です。
問題のコード
古いコード
Objective-Cです。
// 書き込み
[ [NSUserDefaults standardUserDefaults] setObject:NSArray型 forKey:"CountList" ];
// 読み出し
NSArray *array = [ [NSUserDefaults standardUserDefaults] objectForKey:"CountList" ];
[/cpp]
で問題なく使えてました。
新しコード
Swift3です。
// 書き込み
let userDefaults = UserDefaults.standard
userDefaults.set(NSArray型, forKey: "CountList")
// 読み出し
let countList = userDefaults.object(forKey: "CountList") as! [Int]
[/cpp]
読み書きともにSwift3バージョンであれば問題なく動きます。
混ぜるとダメ!
ところが、古いコードで書き込んだデータを新しいコードで読み込むとエラーが起きます。
状態をコードで表すと、
// 書き込み
[ [NSUserDefaults standardUserDefaults] setObject:NSArray型 forKey:"CountList" ];
// 読み出し
let countList = userDefaults.object(forKey: "CountList") as! [Int]
[/cpp]
こういう状態の場合にエラーが出ます。
WorkoutTimerではカウントをarrayで保持して、そのままuserDefaultsで保存しているので、古いバージョンのアプリで保存したデータをアップデート後のアプリで読み込むというのが、まさに上記のような混在した状態になるのでエラーがでるのです。
エラーが出ないように読み込んで、その後新しいバージョンで保存すると、その新しく保存されたデータを読み込む時にエラーが出ます。
ということで、アップデート後初めてアプリを開いた段階でデータを修正するようにしました。
修正方法
エラーを記録してなかったのでうろ覚えですが、「○○stringはNumberにキャストできません」的なエラーでした。
ということで、
let countList = userDefaults.object(forKey: "CountList") as! [String]
// で読み出して、そのまま、
var tmpArray = [Int]()
for i in 0..<tmpCountList.count {
tmpArray.append(Int(tmpCountList[i])!)
}
[/cpp]
としてから保存し直しました。
検索しても出てこなかった現象なので書きましただ、分かりにくいかな。
こんな感じで直してますっていう記事でした。