2016-12-31 91 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