Search code examples
iosswiftuitableviewfile-manager

Reordering rows in TableView would reset to default after data refresh


I implement a table view which it shows a list of documents

enter image description here

I implement reordering feature on it with this code

var documents = [PDFDocument]()
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {

    let movedObject = self.documents[sourceIndexPath.row]

    let fileManager = FileManager.default

    documents.remove(at: sourceIndexPath.row)

    documents.insert(movedObject, at: destinationIndexPath.row)

    NSLog("%@", "\(sourceIndexPath.row) => \(destinationIndexPath.row) \(documents)")



    do {


        let document = documents[sourceIndexPath.row]
        let documentURL = document.documentURL?.absoluteString


        let document_Dest = documents[destinationIndexPath.row]
        let documentURL_Dest = document_Dest.documentURL?.absoluteString

        try fileManager.moveItem(atPath: documentURL!, toPath: documentURL_Dest!)
    }
    catch let error as NSError {
        print("Ooops! Something went wrong: \(error)")
    }




    // To check for correctness enable: self.tableView.reloadData()
   refreshData()

}


  private func refreshData() {
    let fileManager = FileManager.default
    let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let contents = try! fileManager.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
    documents = contents.flatMap { PDFDocument(url: $0) }

    tableView.reloadData()
}

It works completely fine in reordering but the problem is when I close the application and start it again(any time refresh data function runs), rows comes back to their default places. while I need to have saved the changes in reordering.


Solution

  • Reordering in tableView is specific to tableView only. This reordering doesn't effect the original data source. Once you close the app and run again the method to reload data get the original data from document directory. You need to change the order from this original file as and when this order change in tableView.

    1. Get data from Document Directory.

      private func refreshData() 
      {
          let fileManager = FileManager.default
          let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
          let contents = try! fileManager.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
          documents = contents.flatMap { PDFDocument(url: $0) }
      }
      
    2. Create a dictionary with key as document directory file or folder name and value as index.

      private func refreshData() 
      {
          let fileManager = FileManager.default
          let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
          let contents = try! fileManager.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
          documents = contents.flatMap { PDFDocument(url: $0) 
      
      
          let index = 0
          let documentDic = NSMutableDictionary()
          for element in documents
          {
               documentDic.setValue(index, forKey: element.documentURL?.absoluteString) 
               index = index + 1
          }  
      
      }
      
    3. Save this in user Defaults

      private func refreshData() 
      {
          let fileManager = FileManager.default
          let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
          let contents = try! fileManager.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
          documents = contents.flatMap { PDFDocument(url: $0) 
      
          let index = 0
          let documentDic = NSMutableDictionary()
          for element in documents
          {
               documentDic.setValue(index, forKey: element.documentURL?.absoluteString) 
               index = index + 1
          }  
      
      
          NSUserDefaults.standardUserDefaults().setObject(documentDic, forKey: "ReorderingFormat")
      }
      
    4. Once user reorder change the value in dictionary corresponding to each url.

      //Read data from User Defaults
      let dic = NSUserDefaults.standardUserDefaults().objectForKey("Reordering Format")
      for element in documents
      {
          //This way you get the order or index number for any directory.
          dic.objectForKey(element)
      }
      
    5. When user get into app again manage your array according to this dictionary value stored in nsuserdefaults.