2017年11月1日水曜日

enumをエンコード/デコードしようとするとエラーになる

地図のタイプ(MKMapType)をファイルに保存すべく、

func encode(with aCoder: NSCoder) {
    aCoder.encode(mapType, forKey: "mapType")
}

などと書いたのだが、以下のようなエラーが出て落ちてしまった。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x1c4242e80'

有効じゃないselectorがインスタンスに送られた…ってことらしいが、さっぱりわからん。
調べたところ、要はMKMapTypeがenum(列挙型)のため、そのままじゃencode、decodeできんのだと。
中身(RawValue)はUIntなので、
aCoder.encode(mapType.rawValue, forKey: "mapType")
でうまくいった。

decode側も、以下のように対処。
mapType = MKMapType(rawValue: UInt(aDecoder.decodeInteger(forKey: "mapType")))!
decodeInteger(forKey:)でIntとしてデコードして、それをUIntにキャストしてる。

mapType = MKMapType(rawValue: aDecoder.decodeInteger(forKey: "mapType")) as! UInt)!
としたかったけど、このやり方はできなかったので、UInt()で囲んだ。

グチ

カスタムクラスでも構造体でも列挙型でも、そのまんまファイルやUserdefaultsに読み書きできるように作らないのかねえ? めんどうだよね。

0 件のコメント:

コメントを投稿