2017-02-24 7 views
1

汎用オブジェクトルートをネイティブにデフォルトに保存できますか?私は、カスタムオブジェクトをエンコードする必要があることを知っていますが、plistエディタで操作できるようにグラフを書きたいと思っています。私の場合、私の "オブジェクト"は、 "ジェネリック"タイプの辞書の配列です。これは私が(プレイリストモデルを)捨てるしようとしているものです"generic"オブジェクトグラフ(辞書、配列、文​​字列など)をエンコードせずにデフォルトに保存しますか?

class PlayItem : NSObject,NSCoding { 
    var name : String = "item" 
    var link : NSURL = NSURL.init(string: "http://")! 
    var rank = 0 

    override init() { 
     name = "item" 
     link = NSURL.init(string: "http://")! 
     super.init() 
    } 
    init(name:String, link:NSURL, rank:Int) { 
     self.name = name 
     self.link = link 
     self.rank = rank 
     super.init() 
    } 
    required init(coder aDecoder: NSCoder) { 
     self.name = aDecoder.decodeObjectForKey("name") as! String 
     self.link = aDecoder.decodeObjectForKey("link") as! NSURL 
     self.rank = aDecoder.decodeObjectForKey("rank") as! Int 
    } 
    func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeObject(name, forKey: "name") 
     aCoder.encodeObject(link, forKey: "link") 
     aCoder.encodeObject(rank, forKey: "rank") 
    } 
} 

class PlayList: NSObject { 
    var name : String = "list" 
    var list : Array <PlayItem> = Array() 

    override init() { 
     name = "list" 
     list = Array <PlayItem>() 
     super.init() 
    } 

    init(name:String, list:Array <PlayItem>) { 
     self.name = name 
     self.list = list 
     super.init() 
    } 
    required init(coder aDecoder: NSCoder) { 
     self.name = aDecoder.decodeObjectForKey("name") as! String 
     self.list = aDecoder.decodeObjectForKey("link") as! Array 
    } 
    func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeObject(name, forKey: "name") 
     aCoder.encodeObject(list, forKey: "list") 
    } 
} 

ので、私は溝のプレイリストやプレイアイテムのカスタムオブジェクトを使用し、保存することができると言うことなど配列、辞書、文字列を、使用しますこのようなもの enter image description here

ルートは私の "プレイリスト"の配列になります。

+0

あなたは[NSObject-ObjectMap](https://github.com/uacaps/NSObject-ObjectMap)を試すことができます – Winter

+0

それは配列の辞書の配列を扱うようには見えなかったので、私が持っていたものにこだわることにしました今のところ。結局のところ主な焦点はユーザーの編集だった。 – slashlos

答えて

0

ここで私の解決策は - カスタムオブジェクトを内部的に保持するが、一般的なものを公開することです。ここでは、プレイリストとプレイアイテムごとにアレイコントローラーとテーブルビューがあります。コントローラーは、「list」のプレイリストコントローラー選択と中央のプレイリストアレイオブジェクトにバインドされています。

struct k { 
    static let play = "play" 
    static let item = "item" 
    static let name = "name" 
    static let list = "list" 
    static let link = "link" 
    static let rank = "rank" 
} 

// cache playlists read and saved to defaults 
var defaults = NSUserDefaults.standardUserDefaults() 
var playlists = [PlayList]() 
var playCache = [PlayList]() 

override func viewDidLoad() { 
    self.restorePlaylists(restoreButton) 
} 

override func viewWillAppear() { 
    // cache our list before editing 
    playCache = playlists 
} 

@IBOutlet weak var restoreButton: NSButton! 
@IBAction func restorePlaylists(sender: NSButton) { 
    if let playArray = defaults.arrayForKey(UserSetting.Playlists.userDefaultsKey) { 

playlistArrayController.removeObjects(playlistArrayController.arrangedObjects as! [AnyObject]) 
     for playlist in playArray { 
      let play = playlist as! Dictionary<String,AnyObject> 
      let items = play[k.list] as! [Dictionary <String,AnyObject>] 
      var list : [PlayItem] = [PlayItem]() 
      for playitem in items { 
       let item = playitem as Dictionary <String,AnyObject> 
       let name = item[k.name] as! String 
       let path = item[k.link] as! String 
       let link = NSURL.init(string: path) 
       let rank = item[k.rank] as! Int 
       let temp = PlayItem(name:name, link:link!, rank:rank) 
       list.append(temp) 
      } 
      let name = play[k.name] as! String 
      let temp = PlayList(name: name, list: list) 
      playlistArrayController.addObject(temp) 
     } 
     dispatch_async(dispatch_get_main_queue()) { 
      self.playlistTableView.reloadData() 
     } 
    } 
} 

@IBOutlet weak var saveButton: NSButton! 
@IBAction func savePlaylists(sender: AnyObject) { 
    let playArray = playlistArrayController.arrangedObjects as! [PlayList] 
    var temp = Array<AnyObject>() 
    for playlist in playArray { 
     var list = Array<AnyObject>() 
     for playitem in playlist.list { 
      let item : [String:AnyObject] = [k.name:playitem.name, k.link:playitem.link.absoluteString, k.rank:playitem.rank] 
      list.append(item) 
     } 
     temp.append([k.name:playlist.name, k.list:list]) 
    } 
    defaults.setObject(temp, forKey: UserSetting.Playlists.userDefaultsKey) 
    defaults.synchronize() 
} 

私は、保存または復元するときに明示的に各値を解明する必要があるようです。シートはdismissControllerアクションで編集するために使用されます。このアクションは、キャンセルすると、最初に編集前にキャプチャされたplayCacheでプレイリスト配列を復元します。プレイリストは、ユーザー操作によって明示的に保存または復元されます。

関連する問題