我有一个从JSON请求中检索的字典,我想用这些值填充表。我认为一切都还可以,但是我在Type SubjectsViewController does not conform to protocol 'UITableViewDataSource'
我正在使用故事板的类声明中收到错误,并且我在UI上将表格视图添加到datasource
和delegate
以及据我所知,我正在正确实现这些功能。我在下面添加了代码的相关部分。
查看this这可能是有用的,这是我发布的问题,以了解我使用回调的原因。提前谢谢!
class SubjectsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
getSubjects(callback: {(resultValue)-> Void in
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return resultValue.count
}
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
cell.textLabel?.text = resultValue[indexPath.row] as! String?
return cell
}
})
}
// Initialise components of the view
let UserDetails = UserDefaults.standard.stringArray(forKey: "UserDetailsArray") ?? [String]()
@IBOutlet weak var tableView: UITableView!
// Function to retrieve the subjects for the user
func getSubjects(callback: @escaping (NSDictionary)-> Void){
let myUrl = NSURL(string: "www.mydomain.com/retrieveSubjects.php");
let request = NSMutableURLRequest(url:myUrl as! URL)
let user_id = UserDetails[0]
request.httpMethod = "POST";
let postString = "user_id=\(user_id)";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
if error != nil {
print("error=\(error)")
return
}
var err: NSError?
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let resultValue: NSDictionary = parseJSON["subjects"] as! NSDictionary
callback(resultValue)
}
} catch let error as NSError {
err = error
print(err!);
}
}
task.resume();
}
}
编辑:在解包可选值时,CLASS意外发现nil
class SubjectsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var dataDict: [String:AnyObject]?
@IBOutlet var tableView: UITableView!
let userDetails: [String] = UserDefaults.standard.stringArray(forKey:"UserDetailsArray")!
override func viewDidLoad() {
super.viewDidLoad()
self.dataDict = [String:AnyObject]()
self.tableView.delegate = self
self.tableView.dataSource = self
self.getSubjects()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataDict!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: "cell")
let array = self.dataDict?[String(indexPath.row)] as! [String]
print(array)
cell.textLabel?.text = array[0]
cell.detailTextLabel?.text = array[1]
return cell
}
func getSubjects() {
let myUrl = NSURL(string: "www.mydomain/retrieveSubjects.php");
let request = NSMutableURLRequest(url:myUrl as! URL)
let user_id = userDetails[0]
request.httpMethod = "POST";
let postString = "user_id=\(user_id)";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
var err: NSError?
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let resultValue = parseJSON["subjects"] as! [String:AnyObject]
self.dataDict = resultValue
self.tableView.reloadData()
}
} catch let error as NSError {
err = error
print(err!);
}
}
task.resume();
}
}
答案 0 :(得分:2)
以下是您需要做的事情:
首先,为您的数据创建一个类变量。把它放在你的班级声明之下:
var dataDict: [String:AnyObject]?
然后,为了保持组织有序,将tableView属性和userDetails属性直接放在dataDict下。
@IBOutlet var tableView: UITableView!
let userDetails: [String] = UserDefaults.standard.stringArray(forKey:"UserDetailsArray")
现在,您的viewDidLoad方法应如下所示:
override func viewDidLoad() {
super.viewDidLoad()
self.dataDict = [String:AnyObject]()
self.tableView.delegate = self
self.tableView.dataSource = self
self.getSubjects()
}
在此之下,您需要处理UITableViewDataSource方法:
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataDict.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: "cell")
if let array = self.dataDict[String(indexPath.row)] as? [String] {
cell.textLabel?.text = array[0]
cell.detailTextLabel?.text = array[1]
}
return cell
}
最后,您需要实施getSubjects()
方法:
func getSubjects() {
let myUrl = NSURL(string: "www.mydomain.com/retrieveSubjects.php");
let request = NSMutableURLRequest(url:myUrl as! URL)
let user_id = UserDetails[0]
request.httpMethod = "POST";
let postString = "user_id=\(user_id)";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
var err: NSError?
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let resultValue = parseJSON["subjects"] as! [String:AnyObject]
self.dataDict = resultValue
self.tableView.reloadData()
}
} catch let error as NSError {
err = error
print(err!);
}
}
task.resume();
}
总而言之,您的代码应如下所示:
class SubjectsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var dataDict: [String:AnyObject]?
@IBOutlet var tableView: UITableView!
let userDetails: [String] = UserDefaults.standard.stringArray(forKey:"UserDetailsArray")
override func viewDidLoad() {
super.viewDidLoad()
self.dataDict = [String:AnyObject]()
self.tableView.delegate = self
self.tableView.dataSource = self
self.getSubjects()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataDict.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: "cell")
if let array = self.dataDict[String(indexPath.row)] as? [String] {
cell.textLabel?.text = array[0]
cell.detailTextLabel?.text = array[1]
}
return cell
}
func getSubjects() {
let myUrl = NSURL(string: "www.mydomain.com/retrieveSubjects.php");
let request = NSMutableURLRequest(url:myUrl as! URL)
let user_id = UserDetails[0]
request.httpMethod = "POST";
let postString = "user_id=\(user_id)";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
var err: NSError?
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let resultValue = parseJSON["subjects"] as! [String:AnyObject]
self.dataDict = resultValue
self.tableView.reloadData()
}
} catch let error as NSError {
err = error
print(err!);
}
}
task.resume();
}
}
答案 1 :(得分:1)
以下是您班级的最小结构:
class SubjectsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { /* ... */ }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { /* ... */ }
}
如果它看起来不像,那就不符合UITableViewDataSource,也不会编译。如果它不能用作UITableViewDataSource,那么您的表将不会显示任何单元格。