2017-02-24 30 views
1

通用对象根本能保存为默认值吗?我知道自定义对象需要进行编码,但我希望编写图形以便可以通过plist编辑器进行操作。在我的情况下,我的“对象”是一个“通用”类型的字典数组。将“通用”对象图(字典,数组,字符串等)保存为默认值而不进行编码?

这就是我想要沟(播放列表模式)

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

根将是我的“播放列表”数组。我是正确,我可以只保存/读取整个播放列表数组作为

NSUserDefaults.standardUserDefaults().setObject(playlists, forKey: "playlists") 
playlists = NSUserDefaults.standardUserDefaults().arrayForKey: "playlists") 
+0

你可以尝试[NSObject-ObjectMap](https://github.com/uacaps/NSObject-ObjectMap) – Winter

+0

那么,这似乎并没有处理数组字典,所以我决定坚持我所拥有的目前。毕竟主要的焦点是plist用户编辑。 – slashlos

回答

0

因此,这里是我的解决方案 - 让内部自定义对象,但发布通用的。在这里我们有一个数组控制器和每个播放列表和播放项目的tableview - 控制器绑定到播放列表控制器选择“列表”和一个中央播放列表数组对象。

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动作进行编辑,当Cancel时,将简单地使用playCache恢复播放列表数组 - 最初在编辑前捕获。播放列表通过用户操作明确保存或恢复。

相关问题