0
我的主類是一個UITableViewController。 我使用ConnectionManager
類獲取一些JSON數據,並使用ItemManager
類對其進行解析。類之間的通信使用NotificationCenter
完成。每當有來自ConnectionManager
的響應時,它會向ItemManager
發送通知,然後解析它。MainViewController不會從NSNotificationCenter獲取通知
ConnectionManager發佈通知,ItemManager正確接收它們。我想用同樣的方法來更新我的表格視圖。問題出在我的主班上。分析完成後,它不會收到來自ItemManager
的通知。
- 的ConnectionManager - >帖子,ItemManager - >接收 - OK
- ItemManager - >帖子,UITableViewController中 - >接收 - NOK
一些代碼:
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)")
}
}
而且最後我的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)"
}
}