2017-05-25 10 views
0

私はすでにいくつかの記事を読み、すべての解決策を試しましたが、私の場合は何も動作しません。エンコード複合オブジェクトswift 3.0

私はこの複雑なデータ構造を使用しており、DrawnObjectの配列をファイルに格納する必要があります。しかし、構造体型の配列である変数を最初にエンコードするときにクラッシュしました。どんな助け?

[_SwiftValue encodeWithCoder:]:認識されていないセレクタは、あなたが箱から出しスウィフト構造体をエンコードすることはできませんインスタンスに0x1702668c0

enum ArchiverKeys : String 
{ 
    case imageView = "ImageView" 
    case stateArray = "StateArray" 
    case bezierPathArray = "BezierPathArray" 
    case reactangleArray = "ReactangleArray" 
    case deleted = "Deleted" 
} 
    struct RectanglePath { 
     var point1: CGPoint 
     var point2: CGPoint 
     var point3: CGPoint 
     var point4: CGPoint 
    } 

    struct StateObject { 
     var isAdd = true 
     var path = String() 
    } 

    class DrawObject: NSObject , NSCoding { 

     var ImageView = UIImageView() 
     var arrStates = [StateObject]() 
     var arrBezierPaths = [UIBezierPath]() 
     var rects = [RectanglePath]() 
     var deleted = false 


     override init() { 
      ImageView = UIImageView() 
      arrStates = [] 
      arrBezierPaths = [] 
      rects = [] 
      deleted = false 
     } 

     func encode(with archiver: NSCoder) { 
      archiver.encode(self.ImageView, forKey:ArchiverKeys.imageView.rawValue) 
      archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue) 
      archiver.encode(self.arrBezierPaths, forKey:ArchiverKeys.bezierPathArray.rawValue) 
      archiver.encode(self.rects, forKey: ArchiverKeys.reactangleArray.rawValue) 
      archiver.encode(self.deleted, forKey: ArchiverKeys.deleted.rawValue) 
     } 

     required convenience init(coder unarchiver: NSCoder) { 

      self.init() 

      self.ImageView  = unarchiver.decodeObject(forKey: ArchiverKeys.imageView.rawValue) as! UIImageView 
      self.arrStates  = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [StateObject] 
      self.arrBezierPaths = unarchiver.decodeObject(forKey: ArchiverKeys.bezierPathArray.rawValue) as! [UIBezierPath] 
      self.rects   = unarchiver.decodeObject(forKey: ArchiverKeys.reactangleArray.rawValue) as! [RectanglePath] 
      self.deleted  = (unarchiver.decodeObject(forKey: ArchiverKeys.deleted.rawValue) != nil) 
     } 
    } 

    func saveArrayTo(_ directoryName: String , arrayToSave: NSArray) { 

    // let encodedData = NSKeyedArchiver.archivedData(withRootObject: arrayToSave) 
     NSKeyedArchiver.archiveRootObject(arrayToSave, toFile: directoryName) 
    } 

    func loadArrayFrom(_ directoryName: String) -> NSArray? { 
     let result = NSKeyedUnarchiver.unarchiveObject(withFile: directoryName) 
     return result as? NSArray 
    } 

答えて

3

を送った、あなたが計算されたプロパティを追加する必要がありますし、作るinit方法あなたは、配列をアーカイブすることができます今すぐ

struct StateObject { 
    var isAdd = true 
    var path = "" 

    init(propertyList : [String:Any]) { 
     self.isAdd = propertyList["isAdd"] as! Bool 
     self.path = propertyList["path"] as! String 
    } 

    var propertyListRepresentation : [String:Any] { 
     return ["isAdd" : isAdd, "path" : path] 
    } 
} 

準拠した構造体のプロパティリスト

archiver.encode(self.arrStates.map{$0.propertyListRepresentation}, forKey: ArchiverKeys.stateArray.rawValue) 

とは、それが

let states = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [[String:Any]] 
self.arrStates = states.map { StateObject(propertyList: $0) } 

またと交換encode(withにライン

archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue) 

をそのままStateObject

  • を残して、アーカイブさ

    let arrStatesAsPlist = unarchiver.decodeObject(forKey: ArchiverKeys.stateArray.rawValue) as! [[String:Any]] 
    arrStates = arrStatesAsPlist.map { StateObject(isAdd: $0["isAdd"] as! Bool, path: $0["path"] as! String) } 
    

ノートでライン

archiver.encode(self.arrStates, forKey: ArchiverKeys.stateArray.rawValue) 

を交換init(coder

let arrStatesAsPlist = arrStates.map { return ["isAdd" : $0.isAdd, "path" : $0.path] } 
archiver.encode(arrStatesAsPlist, forKey:ArchiverKeys.stateArray.rawValue) 
    • すべてのプロパティにデフォルト値を割り当てるので、init()メソッドとinit()メソッド全体を削除することができます(init(coder)。

    • スウィフトではNSArrayを使用しないでください。ネイティブを使用する

    • UIImageViewのようなUI要素をアーカイブすることはお勧めできません。画像データをアーカイブします。

  • +0

    私はこれを試してみましょう。 – ChanWarde

    +0

    OMG、それは働いた。 @ vadianありがとう。今私はイメージビューの代わりにイメージを保存するために取り組んでいます。 – ChanWarde