2014-11-22 2 views
2

У меня есть простое приложение iOS, написанное в Swift, которое загружает данные JSON, загружаемые через Интернет, и отображает их в UITableView. Когда я запускаю приложение в первый раз, все работает правильно, и в таблице отображается правильная информация.Данные перезагрузки UITableView не работают

В моем приложении у меня есть кнопка, которая запускает обновление, когда я хочу перезагрузить данные. Поэтому я вызываю метод displayTable() при нажатии кнопки обновления, которая снова загружает данные, а затем вызывает метод tableView.reloadData() в основном потоке для обновления данных, но перезагрузка не работает. Я вручную изменяю данные на сервере и нажимаю обновление, но у меня все еще есть старые данные, кэшированные в моем приложении. Я могу выйти/убить приложение, и старые данные остаются «застрявшими» навсегда, если я не удалю приложение и не переустановить.

Я приложил код для своего ViewController ниже. Я потратил слишком много часов на это, и я не могу найти, почему reloadData не работает. Любые идеи, подсказки будут высоко оценены.

благодаря

--Vinny

class ViewController: UITableViewController { 

    var tableData = [] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func viewWillAppear(animated: Bool) { 
     println("viewWillAppear was just called") 
     super.viewWillAppear(true) 

     self.displayTable() 
    } 

    func displayTable() { 
     getJSONData("http://www.example.com/data.json") { (results, resultError) in 

      if (resultError == nil) { 
       if var results = results { 
        dispatch_async(dispatch_get_main_queue(), { 
         self.tableData = [] //create out data on subsequent refreshes 
         self.tableData = results 
         self.tableView.reloadData() //This doesn't appear to be working! 
        }) 
       } else { 
        self.displayErrorPopup() 
       } 
      } else { 
       self.displayErrorPopup() 
      } 
     } 
    } 

    func displayErrorPopup() { 
     let alertViewController = UIAlertController(title: "Error", message: "Couldn't connect to API", preferredStyle: .Alert) 
     let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil) 
     let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil) 
     alertViewController.addAction(okButton) 
     alertViewController.addAction(cancelButton) 
     self.presentViewController(alertViewController, animated: true, completion: nil) 
    } 

    //todo - extract this method into it's own class 
    func getJSONData(ttAPIURL : String, completion: (resultsArray: NSArray?, resultError: NSError?) ->()){ 
     let mySession = NSURLSession.sharedSession() 
     let url: NSURL = NSURL(string: ttAPIURL)! 

     let networkTask = mySession.dataTaskWithURL(url, completionHandler : {data, response, error -> Void in 
      var err: NSError? 
      if (error == nil) { 
       var theJSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSMutableDictionary 
       let results : NSArray = theJSON["list"]!["times"] as NSArray 
       completion(resultsArray: results, resultError: error) 
      } else { 
       completion(resultsArray: nil, resultError: error) 
      } 
     }) 
     networkTask.resume() 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return tableData.count 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("ttCell", forIndexPath: indexPath) as UITableViewCell 
     let timesEntry = self.tableData[indexPath.row] as NSMutableDictionary 
     cell.textLabel.text = (timesEntry["routeName"] as String) 
     return cell 
    } 

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return 1 
    } 

    @IBAction func refreshButtonTap(sender: AnyObject) { 
     self.displayTable() 
    }  
} 

ответ

0

Благодаря drewag и Jirom за ваши ответы. Замечательные комментарии, которые были очень полезными. Я только что нашел свою проблему и ее то, о чем я должен был подумать раньше. Области, в которой размещаются мои динамические данные JSON, защищаются CloudFlare, и, похоже, мои правила для отключения кэширования для определенного каталога не работают. Таким образом, все содержимое JSON было кэшировано, и именно по этой причине мое приложение не показывало новые данные.

Еще раз спасибо за ваши ответы.

--Vinny

PS: За предложение Drewag, я добавил экземпляр NSURLSessionConfiguration, который определяет поведение и политику, чтобы использовать при загрузке данных с помощью объекта NSURLSession и установить свойство Urlcache всухую, чтобы отключить кэширование.

let config = NSURLSessionConfiguration.defaultSessionConfiguration() 
config.URLCache = nil 
let mySession = NSURLSession(configuration: config) 
4

Итак, вы говорите, что reloadData не работает, но это почти наверняка не ваша проблема. Для отладки это необходимо:

  1. Убедитесь, что reloadData фактически называют (или точки останова println)
  2. Проверьте, если UITableViewDataSource методы вызывается после вызова reloadData (точки останова или Println)
  3. Проверить на results массив, который вы возвращаете из сетевого запроса (возможно, println(results))

Я предполагаю, не имеет ничего общего с reloadData. Возможно, включено общее кэширование NSURLSession? Попробуйте установить mySession.URLCache на номер nil.

+0

Hi drewag and thanks. Я проверил, что reloadData вызывается с помощью println, а также отладчика. Я также распечатал массив результатов и подтвердил, что вернутся правильные данные. Мне нужно проверить, что вызываются методы UITableViewDataSources. Будет отчитываться –

1

Попробуйте заменить его

override func viewWillAppear(animated: Bool) { 
    println("viewWillAppear was just called") 
    super.viewWillAppear(true) 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {() -> Void in 
     self.displayTable() 
    }) 
} 
Смежные вопросы