The MainViewController is not receiving any notifications from the NSNotificationCenter

In my application, my main class is a UITableViewController. The JSON data is fetched using a ConnectionManager class and parsed with an ItemManager class. Inter-class communication is facilitated by the NotificationCenter. When there's a response from ConnectionManager, it sends a notification to ItemManager for parsing.

While ConnectionManager successfully posts notifications that are received by ItemManager, I'm facing an issue with my main class as it doesn't receive notifications from ItemManager after parsing completion.

  • ConnectionManager -> posts, ItemManager -> receives -- OK
  • ItemManager -> posts, UITableViewController -> receives -- NOK

Here's some code snippet:

class ConnectionManager {

  private let URL = "http://foo.json"
  private var response: Data?

  init () {
    getData()
  }

  func getData() {
    let req = NSMutableURLRequest(url: NSURL(string: URL)! as URL)
    req.httpMethod = "GET"
    URLSession.shared.dataTask(with: req as URLRequest) { data, response, error in
      if error != nil {
        //HTTP request failed
        NSLog(error?.localizedDescription ?? "Unknown Error")
        NotificationCenter.default.post(name: Notification.Name(NotificationCenterKeys.NOK), object: nil)
      } else {
        //HTTP request succeeded
        self.response = data
        NotificationCenter.default.post(name: Notification.Name(NotificationCenterKeys.OK), object: nil)
      }
      }.resume()
  }
}

class ItemManager {
  private var cm: ConnectionManager
  private var items = [Item]()

  init() {
    self.cm = ConnectionManager()
    NotificationCenter.default.addObserver(self, selector: #selector(self.parseResponse), name: Notification.Name(NotificationCenterKeys.OK), object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.noData), name: Notification.Name(NotificationCenterKeys.NOK), object: nil)
  }

  @objc private func noData() {
    NSLog("No data to parse")
  }

  @objc private func parseResponse() {
    do {
      if let data = cm.getResponse() {
        let items: NSDictionary = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
        let rawItems = items["numbers"] as! [Int]
        
        self.items = parseItems(rawItems: rawItems)
        
        NotificationCenter.default.post(name: Notification.Name(NotificationCenterKeys.PARSED), object: nil)

      }
    } catch {
      print("Error deserializing JSON: \(error)")
    }
  }

Now, let's take a look at my UITableViewController:

class MainViewTableViewController: UITableViewController {

  var items = [Item]()
  var dataAvailable = false
  var im = ItemManager()
  var dataLabel = "Loading Data..."

  override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(self.updateTable), name: Notification.Name(NotificationCenterKeys.PARSED), object: nil)
    setTable()
  }

  @objc func updateTable() {
    if im.getItems()?.count != 0 {
      items = im.getItems()!
      dataAvailable = true
    } else {
      dataAvailable = false
      dataLabel = "No Data Available"
    }
    self.tableView.reloadData()
  }

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

  func setTable() {
    title = "Test"
    tableView.rowHeight = 40
  }

  // MARK: - Table view data source

  override func numberOfSections(in tableView: UITableView) -> Int {
    var numOfSections = 0
    if dataAvailable {
      numOfSections = 4
      return numOfSections
    } else {
      let noDataLabel: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.bounds.size.height))
      noDataLabel.text = dataLabel
      noDataLabel.textColor = UIColor.black
      noDataLabel.textAlignment = .center
      tableView.backgroundView = noDataLabel
      tableView.separatorStyle = .none
    }
    return numOfSections
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return getNumOfItemsPerSection(section: section)
  }

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
    guard let sectionNumber = SectionNumber(rawValue: indexPath.section) else { return cell }
    let elements = self.items.filter({ $0.sectionNumber == sectionNumber })
    cell.nameLabel?.text = elements[indexPath.row].itemNumber?.description
    if elements[indexPath.row].checkmark {
      cell.accessoryType = .checkmark
    } else { cell.accessoryType = .none }
    return cell
  }

  func getNumOfItemsPerSection(section: Int) -> Int {
    guard let sectionNumber = SectionNumber(rawValue: section) else { return 0 }
    return self.items.filter({ $0.sectionNumber == sectionNumber }).count
  }

  override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "Section \(section + 1)"
  }
}

Answer №1

Ah ha! The issue has been identified. I mistakenly added the observer after receiving the notification (oops)

class MainViewTableViewController: UITableViewController {

  var items = [Item]()
  var dataAvailable = false
  var im: ItemManager? = nil

  override func viewDidLoad() {
    super.viewDidLoad()
    setTable()
    NotificationCenter.default.addObserver(self, selector: #selector(self.updateTable),
                                           name: Notification.Name(NotificationCenterKeys.END), object: nil)
    im = ItemManager()
  }

...

All is working perfectly now :-)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dealing with null JSON objects in ReactJS

When fetching data from the backend using an API, I need to verify if a domain is valid. The challenge arises when the domain is not valid (i.e. it does not exist in the backend), resulting in an empty array [] being returned. To handle this situation, I ...

The div will not receive the JSON response

I am currently working with a <script> that includes functions for autocompletion and item selection: // autocomplet : this function will be executed every time we change the text function autocomplet() { var min_length = 0; // minimum character ...

Extract an array segment from a JSON document and convert it into a list

In my JSON file, there is a valid list/Array of databases structured as follows: { "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug" } }, "settings": { ...

What is the best way to extract a particular key value from a JSON object?

I am completely new to the world of APIs and just starting out with JavaScript. My goal is to retrieve the status of a server from a server hosting panel using an API. In order to achieve this, I need to log in by making a request to /API/Core/Login, extra ...

I would like to know the best way to compare two JSON data sets, filter out any matching data, and then store the remaining results

To efficiently extract all Post Titles from a JSON API, I am utilizing another JSON API of users to further retrieve the count of comments for each Post. Here are the APIs being used: API for USERS: http://jsonplaceholder.typicode.com/users API for POSTS ...

Tips on saving JSON response data to EditText in Android

Hey there! I am currently trying to retrieve the reg_no array value from the database and display it in an EditText without the need for any button clicks. I would appreciate some guidance on how to achieve this in my class file. String RegNo = Database ...

extract the picture from the web address

Having trouble displaying an image from the server. I am using a query and can see the response in Logcat, but the image is not showing up. Below is my Json response and code snippet. Any assistance would be appreciated! [ { "b_card":"http: ...

What could be the reason Angular is not refreshing with a JSON file update?

Having trouble using a basic Angular JS app to load data from a JSON file onto a website. The JSON file contains: {"a": "a"} The Angular application setup is as follows: var app = angular.module("app", []) .controller("ctrl", ["ser", function(ser) { ...

Revamp intricate JSON array with Jolt for optimum transformation

When working with an external API, I am receiving a complex JSON structure that needs to be transformed into a simpler JSON format according to our requirements. Although Jolt has the capability to transform JSON, I'm struggling to devise the appropri ...

Mastering the Art of Integrating API and JSON!

I've developed a bot using botkit and the Zendesk API to retrieve information. There's a function in my bot that prompts the user for a search term, searches for relevant information using the Zendesk API, and displays the result. I'm faci ...

Add a fresh key to a pre-existing array within an object

I have a JSON array that I need to modify by adding a new key. Here is the current structure: stdClass Object ( [set] => Array ( [0] => stdClass Object ( [name] => agenda ...

I have successfully converted an SQL Join query into JSON, but now I am unsure of how to interact with the

I recently ran an SQL Join on two tables and obtained the following results: _____People_____ name: "Jane" age: 35 job_id: 1 _____Professions_____ job_id: 1 title: "Teacher" "SELECT * FROM People INNER JOIN Professions ON People.job_id = Professions.job ...

An ASMX web service encountering an unescaped double quote within a parameter while processing JSON data

Within my HTTP REQUEST, a valid JSON string is present with a double quote in the middle of the name "jo\"hn" escaped. This was captured by Fiddler Web Debugger. {"name":"firstName","value":"jo\"hn"}, It's important to note that the reques ...

PHP API Integration for XBox

Check out this demo link: http://davidwalsh.name/xbox-api I decided to create a php file with the following content.. <?php // Customizations $gamertag = 'RyanFabbro'; $profileUrl = 'http://www.xboxleaders.com/api/profile/'.$gamert ...

My webpage is experiencing issues with function calls not functioning as expected

I have created a select menu that is integrated with the Google Font API. To demonstrate how it works, I have set up a working version on JSBIN which you can view here. However, when I tried to replicate the code in an HTML page, I encountered some issues ...

Can JSON be used to perform mathematical operations and calculations?

Utilizing the amazing json-server as my application's backend has been incredibly beneficial for custom data retrieval. However, it would be even more valuable if it supported calculations and expressions to mimic backend behavior. Consider this data ...

Substitute data in json

I'm currently working on displaying data from a JSON file and I need to replace certain values for translation purposes. Here is the code snippet I am dealing with: <li ng-repeat="childrens in data.children track by $index"> <a& ...

Node.js is having trouble locating the JSON file for Ajax requests

Currently, I've developed a fun little game using the p5.js library and wanted to integrate a Leaderboard feature that pulls data from a JSON file acting as a database to store Usernames and scores. To achieve this, I've utilized a Node.js server ...

Transform into dynamic types in Java

Today, I'm facing a challenge with JSON data that consists of an array of objects. Each object in the array contains two properties: type and value. [{ "type": "Boolean", "value": false }, { "type": "String[]", "value": ["one", "two", ...

When using QML, functions like Object.keys, Object.values, and JSON.stringify may return unexpected empty results

I have written a code that exposes a C++ object to QML, and I want to verify the declared properties of the object using native JS methods. However, they are not working as expected. I created a method called FizzBuzzDerived.properties, which functions cor ...