0

I have the following methods in my "ViewController" class to populate custom cells in a UITableView from a GET API call. This works fine when app first loads.

//ViewController    
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    loadDataInUITableViewCell()
}

func loadDataInUITableViewCell() {
        apiCentral.sharedInstance.fetchData() {
        result in
        guard result.error == nil else {
            self.handleError(result.error!)
            return
        }
        if let fetchedData = result.value {
            self.data = fetchedData
        }
        self.messagesTableView.reloadData()
    }
}

How do I refresh the data when the app comes to the foreground? Well, I added the following to AppDelegate to run the "loadDataInUITableViewCell" method so that the data reloads.

//AppDelegate
let mainViewController = ViewController()

func applicationWillEnterForeground(_ application: UIApplication) {
    mainViewController.loadDataInUITableViewCell()
}

ISSUE: The above mechanism works fine however, I get the following error when the app comes to the foreground.

"fatal error: unexpectedly found nil while unwrapping an Optional value"

The issue seems to be happening at "self.messagesTableView.reloadData()" line of code. I'm using Xcode 8.3 and coding in Swift 3. Any guidance would be appreciated. Thank you.

TLK
  • 1
  • 1
  • In your AppDelegate, you have another `mainViewController` which is not associated with your current `mainViewController` – Twitter khuong291 Mar 30 '17 at 02:08
  • 2
    There is no need to add any code for this in your app delegate. Listen for the `UIApplicationWillEnterForeground` notification in your table view controller. – rmaddy Mar 30 '17 at 02:52

3 Answers3

2
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: .UIApplicationWillEnterForeground, object: nil)

Write this above line in viewWillAppear()

func willEnterForeground() {
   tableView.reloadData()
}

Used this above code in your ViewController where there is UITableView

rmaddy
  • 314,917
  • 42
  • 532
  • 579
devang bhatt
  • 460
  • 2
  • 15
0

Solutions 1. In appdelegate:

   //AppDelegate
    let mainViewController : ViewController?

    func applicationWillEnterForeground(_ application: UIApplication) {
        mainViewController.loadDataInUITableViewCell()
    }

And in Your viewcontroller:

//ViewController    
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    (UIApplication.sharedApplication().delegate as! AppDelegate).mainViewController  = self
    loadDataInUITableViewCell()
}

Solutions 2.

listen in viewcontroller:

    //ViewController    
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(ViewController.loadDataInUITableViewCell(), name: UIApplicationWillEnterForegroundNotification, object: nil)
    loadDataInUITableViewCell()
}
Nguyen Hoan
  • 1,583
  • 1
  • 11
  • 18
  • Neither of these solutions are good. Solution 1 is a terrible design. Solution 2 should be replaced with using the standard `UIApplicationWillEnterForeground` notification provided by iOS. There is no need to do anything in the app delegate. – rmaddy Mar 30 '17 at 04:11
0

UIApplicationWillEnterForeground Notification

Posted shortly before an app leaves the background state on its way to becoming the active app.

Discussion

The object of the notification is the UIApplication object. There is no userInfo dictionary.

Declaration

static let UIApplicationWillEnterForeground: NSNotification.Name

From Apple's Documentation.

It's super easy to use:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(self.handler), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
}


func handler() {
    // self.tableView.reloadData()
}

Hope it helps!

Mannopson
  • 2,634
  • 1
  • 16
  • 32