ushiyaDevLog

iPhoneとかMacとか、家電とか、筋トレとか、なんか色々になりました

[古いObjective-CからSwift3へ]Swift3のuserDefsultsで苦労したArray

      2017/10/14

数年間アップデートしていなかったWorkoutTimeriOS11に対応させる際に、使用言語も変えようと思いSwift3にしました。
Swift自体古いバージョンのものしか使ったことが無かったので、だいぶてこずりました。

中でも一番厄介だったのが、数年前のObjective-CNSUserDefaultsで保存したNSArray型のデータをSwift3のuserDefsultsで読み出す際に出たエラーの修正です。

問題のコード

古いコード

Objective-Cです。

// 書き込み
[ [NSUserDefaults standardUserDefaults] setObject:NSArray型 forKey:"CountList" ];

// 読み出し
NSArray *array = [ [NSUserDefaults standardUserDefaults] objectForKey:"CountList" ];

で問題なく使えてました。

新しコード

Swift3です。

// 書き込み
let userDefaults = UserDefaults.standard
userDefaults.set(NSArray型, forKey: "CountList")

// 読み出し
let countList = userDefaults.object(forKey: "CountList") as! [Int]

読み書きともにSwift3バージョンであれば問題なく動きます。

混ぜるとダメ!

ところが、古いコードで書き込んだデータを新しいコードで読み込むとエラーが起きます。
状態をコードで表すと、

// 書き込み
[ [NSUserDefaults standardUserDefaults] setObject:NSArray型 forKey:"CountList" ];

// 読み出し
let countList = userDefaults.object(forKey: "CountList") as! [Int]

こういう状態の場合にエラーが出ます。

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])!)
}

としてから保存し直しました。

検索しても出てこなかった現象なので書きましただ、分かりにくいかな。

こんな感じで直してますっていう記事でした。

 - iOS, Programming, Xcode ,