2016-07-15 5 views
3

したがって、カスタムオブジェクトの配列があります。 NSUserDefaultsに配列を保存しようとすると、それらをアーカイブする必要があります。ここで私は私のカスタムオブジェクトの配列をアーカイブするためにやっているものです:Swift - NSKeyedArchiverを使用してユーザーデータを保存し、NSArrayへの変換時にエラーが発生する

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

    //3 

    var allMessages = defaults.objectForKey(UserDefaultsMesssageKey) as! [AddMessageViewController.harassText] 
    var aMessage = AddMessageViewController.harassText(phoneNumber: 0, message: "1", frequency: 1, active: 1) 
    allMessages.append(aMessage) 
    saveMessage(allMessages) 


    return (allMessages.count) 
} 

func archiveMessage(message:[AddMessageViewController.harassText]) -> NSData { 
    let archivedObject = NSKeyedArchiver.archivedDataWithRootObject(message as NSArray) 
    return archivedObject 
} 
func saveMessage(messages: [AddMessageViewController.harassText]) { 
    let archivedObject = archiveMessage(messages) 
    defaults.setObject(archivedObject, forKey: UserDefaultsMesssageKey) 
    defaults.synchronize() 
} 
func retrieveData()-> [AddMessageViewController.harassText]? { 
    if let unarchiveObject = NSUserDefaults.standardUserDefaults().objectForKey(UserDefaultsMesssageKey) as? NSData { 
     return NSKeyedUnarchiver.unarchiveObjectWithData(unarchiveObject) as? [AddMessageViewController.harassText] 
    } 
    return nil 
} 

フローは次のとおりです。saveMessageコールで

  1. 、中にアーカイブを取得するためのカスタム配列を渡します。配列はGDBに似ています。配列であることがわかります。配列には1つのクラスオブジェクトが含まれています。

    ([Harass_Your_Kate.AddMessageViewController.harassText]) $R0 = 1 value { [0] = 0x00007fa5ab409600 { ObjectiveC.NSObject = { isa = Harass_Your_Kate.AddMessageViewController.harassText } phoneNumber = 0 message = "1" frequency = 1 active = 1 } }

  2. アレイはarchiveMessageに渡されます。コードは、NSKeyedArchiverメソッドですぐに失敗します。エラーメッセージは次のとおりです:

    [_TtCC16Harass_Your_Kate24AddMessageViewController10harassText encodeWithCoder:]: unrecognized selector sent to instance 0x7fa5ab409600 
    

    2016年7月15日16:31:は、* - [NSKeyedArchiverのdealloc]:26.019あなたのケイト[7847495 5858]:嫌がらせ警告:NSKeyedArchiverが呼び出さ-finishEncodingいなくても、割り当て解除をその上に。 2016年7月15日16:31:キャッチされない例外により 'NSInvalidArgumentException'、理由にアプリを終了*:26.023あなたケイト[7847495 5858]を:嫌がらせ「 - [_ TtCC16Harass_Your_Kate24AddMessageViewController10harassText encodeWithCoder:]:認識されないセレクターインスタンス0x7fa5ab409600に送信

私はすべての助けをありがとう、あらかじめありがとう!

EDIT:

class Text : NSObject { 
    var phoneNumber = 0    //Text address to send to 
    var message: String = ""  //Message to be sent 
    var frequency = 24    //Number of hours between messages (usually a multiple of 24 - 24 = daily) 
    var active = 0     // 0 if cancelled, 1 if active 

    init(phoneNumber: Int, message: String, frequency: Int, active: Int){ 
     self.phoneNumber = phoneNumber 
     self.message = message 
     self.frequency = frequency 
     self.active = active 
    } 
} 
+2

カスタムオブジェクトのNSCodingメソッドを確認する必要があります。 ( 'initWithCoder'と' encodeWithCoder')です。 –

+0

私はこれらの事のどちらも持っていません。 – Ryan

+1

これは問題です。カスタムクラスの定義を表示してください。 –

答えて

3

NSKeyedArchiverはあなたがNSCodingプロトコルに準拠することにより、提供する必要が方法を利用することによって、オブジェクトをシリアライズ:ここに私のオブジェクトの定義があります。カスタムクラスの保存方法を自動的に推測することはできません。

class Text : NSObject, NSCoding { 
    var phoneNumber = 0    //Text address to send to 
    var message: String = ""  //Message to be sent 
    var frequency = 24    //Number of hours between messages (usually a multiple of 24 - 24 = daily) 
    var active = 0     // 0 if cancelled, 1 if active 

    init(phoneNumber: Int, message: String, frequency: Int, active: Int){ 
     self.phoneNumber = phoneNumber 
     self.message = message 
     self.frequency = frequency 
     self.active = active 
    } 

    required init?(coder aDecoder: NSCoder) { 
     phoneNumber = aDecoder.decodeInteger(forKey: "phoneNumber") 
     message = aDecoder.decodeObject(forKey: "message") as! String 
     frequency = aDecoder.decodeInteger(forKey: "frequency") 
     active = aDecoder.decodeInteger(forKey: "active") 
    } 

    func encode(with aCoder: NSCoder) { 
     aCoder.encode(phoneNumber, forKey: "phoneNumber") 
     aCoder.encode(message, forKey: "message") 
     aCoder.encode(frequency, forKey: "frequency") 
     aCoder.encode(active, forKey: "active") 
    } 
} 

をあなたが見ることができるようにencode方法は、コーダに関連する情報を保存し、一方、初期化子は、コーダからの読み取りと作成し、インスタンス:あなたは次のようにすることを自分で実装する必要があります。このようなシンプルなクラスでは、実装が明白に見えるかもしれませんが、より複雑なカスタムタイプでは、簡単にエンコーディングを決定する必要があります。

+0

ありがとうございました!これは素晴らしいです。 CoreDataを使って実装していますが、これはカスタム情報を保存する方がずっと簡単です – Ryan

関連する問題