2017-05-20 3 views
0

私はbillディレクトリのplistファイルにNSKeyedArchiverを使用してドキュメントディレクトリに保存されるいくつかのインスタンスを含むBillクラスを持っています。オブジェクトが既に保存されているときに既存のモデルにパラメータを追加するにはどうすればよいですか?

class Bill: NSObject, NSCoding { 

    required init?(coder aDecoder: NSCoder) { 
    name = aDecoder.decodeObject(forKey: "Name") as! String 
    moPayment = aDecoder.decodeDouble(forKey: "Payment") 
    super.init() 
    } 

    override init() { 
    super.init() 
    } 

    var name = "Bill Name" 
    var moPayment = 0.0 

    func encode(with aCoder: NSCoder) { 
    aCoder.encode(name, forKey: "Name") 
    aCoder.encode(moPayment, forKey: "Payment") 
    } 
} 

func saveBillItems(_ bills: [Bill]) { 
    let data = NSMutableData() 
    let archiver = NSKeyedArchiver(forWritingWith: data) 
    archiver.encode(bills, forKey: "BillItems") 
    archiver.finishEncoding() 
    data.write(to: dataFilePath(), atomically: true) 
} 

func loadBillItems() { 
    let path = dataFilePath() 
    if let data = try? Data(contentsOf: path) { 

     let unarchiver = NSKeyedUnarchiver(forReadingWith: data) 
     bills = unarchiver.decodeObject(forKey: "BillItems") as! [Bill] 
     unarchiver.finishDecoding() 
    } 
} 

これはすべて正常に動作しますが、現在はpaidStatusを記録するためのパラメータを追加しようとしています。原因これを持っていない既存の法案のオブジェクトをロードしようとしていると、「予想外にnilを...」

status = aDecoder.decodeObject(forKey: "Status") as! PaidStatus 

class Bill: NSObject, NSCoding { 

    required init?(coder aDecoder: NSCoder) { 
    ... 
    status = aDecoder.decodeObject(forKey: "Status") as! PaidStatus 
    super.init() 
    } 

    ... 

    var status = PaidStatus.unpaid 

    enum PaidStatus { 
    case overdue 
    case upcoming 
    case unpaid 
    case paid 
    } 

    ... 

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

func saveBillItems(_ bills: [Bill]) { 
    ... 
} 

func loadBillItems() { 
    ... 
} 

私は今のアプリを実行しようとすると、私はエラーを取得しますパラメータ。

既存のオブジェクトにこのパラメータを追加する方法はありますか?削除してゼロから再作成する必要はありませんか?

+0

強制ダウンキャストは使用しないでください。 nil coalescing operatorで条件付きダウンキャストを使用可能にする – Paulw11

+0

これを行うと、状態がオプションの値をとることができないため、コンパイルエラーが発生します。 – Hutch

答えて

3

オブジェクトに値がない可能性があるため、強制ダウンキャストではなくオプションのダウンキャストを使用する必要があります。 statusはオプションではないため、nil合体演算子を使用してデフォルト値を提供することができます。

status = aDecoder.decodeObject(forKey: "Status") as? PaidStatus ?? .unpaid 
+0

これは動作するようですが、私は認識できないセレクタをインスタンスencodeWithCoderに送るようになっています。私はこれがenumをエンコードすることと別の質問に関連するかもしれないと信じています。 – Hutch

関連する問題