2016-12-31 92 views
1

不寻找代码(不会伤害,虽然)只是想知道我应该如何去做这件事。我有一个应用程序,就像博客阅读器一样。我有一个MYSQL数据库中的信息与JSON一起被放置在一个jsonArray中,然后放在一个数组中以显示在一个表视图中。在该表格视图中,我通常在1部分中包含所有对象。每行/对象单击时都有一个按钮,它将该行移动到另一个节中。我还有一个搜索控制器来搜索主要部分(第1部分)。Swift的核心数据指导3

如何将行的顺序或位置保存到核心数据?

例如:我在0部分有0行,在部分1有5行,我点击了第1部分其中一行的按钮,它将该行移动到部分0,现在部分0有1行,而部分1有4排。如何将这个新的tableview命令保存到核心数据?我只想保存行的位置,因此该应用程序会记住所选行的哪一部分位于其中。

是否将该行的indexPath保存在节中? 添加实体和属性时,我用什么来保存?

另外,它是一个MySQL阅读器,所以当tableview被重新加载并添加一个新的内容时,它仍然会显示,因为tableview将从核心数据读取?

我正在学习Core Data(Swift 3代码),但在使用此应用程序时遇到了麻烦。

谢谢你的帮助!

回答

1

如果您不需要保存MySQL数据库中的全部数据,请使用UserDefaults保存排序数据。定义一个类只包含数据ID和indexPath:

class DataOrdering: NSObject, NSCoding { 

    var indexPath: IndexPath? 
    var dataId: String? 

    init(dataId: String, indexPath: IndexPath) { 
     super.init() 
     self.dataId = dataId 
     self.indexPath = indexPath 
    } 

    required init(coder aDecoder: NSCoder) { 

     if let dataId = aDecoder.decodeObject(forKey: "dataId") as? String { 
      self.dataId = dataId 
     } 

     if let indexPath = aDecoder.decodeObject(forKey: "indexPath") as? IndexPath { 
      self.indexPath = indexPath 
     } 

    } 

    func encode(with aCoder: NSCoder) { 
     aCoder.encode(dataId, forKey: "dataId") 
     aCoder.encode(indexPath, forKey: "indexPath") 
    } 

    func save(defaults key: String) -> Bool { 

     let defaults = UserDefaults.standard 
     let savedData = NSKeyedArchiver.archivedData(withRootObject: self) 
     defaults.set(savedData, forKey: key) 
     return defaults.synchronize() 

    } 

    convenience init?(defaults key: String) { 

     let defaults = UserDefaults.standard 
     if let data = defaults.object(forKey: key) as? Data, 
      let obj = NSKeyedUnarchiver.unarchiveObject(with: data) as? DataOrdering, 
      let dataId = obj.dataId, 
      let indexPath = obj.indexPath { 
      self.init(dataId: dataId, indexPath: indexPath) 
     } else { 
      return nil 
     } 

    } 

    class func allSavedOrdering(_ maxRows: Int) -> [Int: [DataOrdering]] { 

     var result: [Int: [DataOrdering]] = [:] 
     for section in 0...1 { 
      var rows: [DataOrdering] = [] 
      for row in 0..<maxRows { 
       let indexPath = IndexPath(row: row, section: section) 
       if let ordering = DataOrdering(defaults: indexPath.defaultsKey) { 
        rows.append(ordering) 
       } 
       rows.sort(by: { $0.indexPath! < $1.indexPath! }) 
      } 
      result[section] = rows 
     } 

     return result 

    } 

} 

游乐场样本:

let data = DataOrdering(dataId: "1", indexPath: IndexPath(row: 0, section: 0)) 

let savedData = NSKeyedArchiver.archivedData(withRootObject: data) 
let obj = NSKeyedUnarchiver.unarchiveObject(with: savedData) as? DataOrdering 
obj?.dataId // print: "1" 
obj?.indexPath // print: [0,0] 

使用保存功能,用“钥匙”保存并DataOrdering读回(默认:“钥匙”)

修订

为一个视图控制器添加代码使用这个类:

extension IndexPath { 
    var defaultsKey: String { return "data_ordering_\(section)_\(row)" } 
} 

class ViewController: UITableViewController { 

    var data: [Any]? 
    var items: [[Any]]? 

    func fetchData() { 

     // request from remote or local 
     data = [1, 2, 3, "a", "b", "c"] // sample data 

     // Update the items to first section has 0 elements, 
     // and place all data in section 1 
     items = [[], data ?? []] 

     // apply ordering 
     applySorting() { "\($0)" } 

     // save ordering 
     saveSorting() { "\($0)" } 

     // refresh the table view 
     tableView.reloadData() 

    } 

    func applySorting(_ dataIdBlock: (Any) -> String) { 

     // get all saved ordering 
     guard let data = self.data else { return } 
     let ordering = DataOrdering.allSavedOrdering(data.count) 

     var result: [[Any]] = [[], []] 

     for (section, ordering) in ordering { 
      guard section <= 1 else { continue } // make sure the section is 0 or 1 
      let rows = data.filter({ obj -> Bool in 
       return ordering.index(where: { $0.dataId == .some(dataIdBlock(obj)) }) != nil 
      }) 
      result[section] = rows 
     } 

     self.items = result 

    } 

    func saveSorting(_ dataIdBlock: (Any) -> String) { 

     guard let items = self.items else { return } 

     for (section, rows) in items.enumerated() { 
      for (row, item) in rows.enumerated() { 
       let indexPath = IndexPath(row: row, section: section) 
       let dataId = dataIdBlock(item) 
       let ordering = DataOrdering(dataId: dataId, indexPath: indexPath) 
       ordering.save(defaults: indexPath.defaultsKey) 
      } 
     } 

    } 

    @IBAction func buttonMoveToSectionTapped(_ sender: UIButton) { 

     // if the sender's tag is row index 
     // or you can get indexPath by tableView.indexPath(for: cell) function too 
     let row = sender.tag 

     // move this item from section 1 to section 0 (last position) 
     if let item = items?[1].remove(at: row) { 
      items?[0].append(item) 
     } 

     // Save all sorting 
     saveSorting() { "\($0)" } 

     tableView.reloadData() // refresh table view 

    } 

    override func numberOfSections(in tableView: UITableView) -> Int { 
     return self.items?.count ?? 0 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return self.items?[section].count ?? 0 
    } 


} 
+0

谢谢!出于某种原因,我认为我需要核心数据,但你是对的NSUserDefaults是正确的方式,因为我只需要保存tableview的顺序。快速问题:您向我展示的代码是保存indexPath,但保存工作如何?我在哪里保存该行所在的部分? – BroSimple

+1

我更新了答案,添加代码如何使用类为你@BroSimple – bubuxu

+0

嘿抱歉,但代码不工作,表视图回来空,我用saveSorting(){“\($ 0)”}保存并在ViewDidLoad我使用fetchData() – BroSimple