我的主要类是一个UITableViewController。
我正在使用ConnectionManager
类获取一些JSON数据并使用ItemManager
类进行解析。类之间的通信使用NotificationCenter
完成。每当有ConnectionManager
的响应时,它会向ItemManager
发送通知,然后对其进行解析。
ConnectionManager发布通知,ItemManager正确接收通知。我想使用相同的方法来更新我的表视图。问题在于我的主要课程。完成解析后,它不会收到来自ItemManager
的通知。
一些代码:
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)"
}
}
答案 0 :(得分:1)
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()
}
...
现在效果很好: - )