Как разобрать код JSON для данных представления таблицы Swift 3?

Я создаю приложение ios, используя swift 3 и MySQL и PHP в качестве базы данных. Я хотел вывести данные из базы данных в табличное представление, но у меня постоянно возникала ошибка: Error Domain = NSCocoaErrorDomain Code = 3840 «Текст JSON не начинался с массива или объекта, а параметр, разрешающий фрагменты, не установлен». Я попытался проверить кодировку JSON в PHP, и все было в порядке.

Вот мой быстрый код:

class Roster: UITableViewController {

@IBOutlet weak var rosterbar: UITabBarItem!
var class_id = String()
 var values: Array! = []

override func viewDidLoad() {

}

func SelectClassName(){
    let request = NSMutableURLRequest(url: NSURL(string: "http://localhost/classdbfiles/SelectClass.php")! as URL)
    request.httpMethod = "POST"
    let postString = "class_id=\(Home.ClassVariables.class_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

        }
        print("response=\(response!)")
        let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
        print("reponseString = \(responseString!)")


    }
    task.resume()

    }



func get() {
    guard let url = URL(string: "http://localhost/classdbfiles/SelectClass.php") else { return }

    do {
        let data = try Data(contentsOf: url)
        let deserializedValues = try JSONSerialization.jsonObject(with: data)
        guard let arrayOfDictionaryValues = deserializedValues as? [[String:String]] else { return }
        values = arrayOfDictionaryValues

    } catch {
        //You should separate the different catch blocks to handle the different types of errors that occur
        print("There was an error:\(error)")
    }
    tableView.reloadData()
}

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

        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SpecialCell
    let maindata = values[indexPath.row] as! [String:AnyObject]

    cell.studentname.text = maindata["lastname"] as? String

    return cell
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    SelectClassName()
    get()
    tableView.reloadData()
}

}

и вот файл PHP:

if ($result = $mysqli->query("SELECT lastname from tbl_studentinfo where class_id='".$class_id."'")) {
    $tempArray = array();
    while($row = $result->fetch_object()) {
            $tempArray = $row;
            array_push($myArray, $tempArray);
        }
    echo json_encode($myArray);
    }
$result->close();
$mysqli->close();

person Enrique Jimmar C. Panti    schedule 11.03.2017    source источник
comment
Составьте строку из входящего Data и распечатайте ее. Ошибка 3840 — пустая строка или неверный формат.   -  person vadian    schedule 12.03.2017


Ответы (1)


Допустим, вы получили файл JSON вида:

 {
    "members": [
        {"name": "Sarah"},
        {"name": "David"},
        {"name": "Michael"}
    ]
}

(Обратите внимание, что фигурные скобки обозначают словарь, а квадратные скобки — массив.)

Импортируйте файл JSON в свой пакет. Я назвал свой jsonfile.json

Затем используйте следующий метод, чтобы проанализировать файл JSON и получить элементы, т. е. словарь, содержащий имена элементов:

func getMemeberDictionary()-> [[String: String]]{
        guard let jsonFileURL = Bundle.main.url(forResource: "jsonfile", withExtension: "json") else {fatalError("Failed to get JSON file URl")}
        var jsonData: Data!
        var jsonDictionary: [String: AnyObject]!

        //Getting JSON data from URL
        do {
            jsonData = try Data(contentsOf: jsonFileURL)
        } catch let error as NSError{
            print(error.debugDescription)
            fatalError("Failed to initiate JSON data from URL!")
        }

        //getting top level JSON dictionary i.e. "members"
        do {
            jsonDictionary = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String: AnyObject]
        } catch let error as NSError{
            print(error.debugDescription)
            fatalError("Failed to initiate top level JSON dictionary")
        }

        let memebers: [[String: String]] = jsonDictionary["members"] as! [[String: String]]

        for person in memebers{
            print(person["name"]!)
        }

        return memebers
    } 

Это вернет массив типа [[String: String]], используйте его для настройки представления таблицы.

Этот код импортирует всех членов в табличное представление:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var members: [[String: String]]!

    override func viewDidLoad() {
        super.viewDidLoad()
        members = getMemeberDictionary()
    }

    func getMemeberDictionary()-> [[String: String]]{
        guard let jsonFileURL = Bundle.main.url(forResource: "jsonfile", withExtension: "json") else {fatalError("Failed to get JSON file URl")}
        var jsonData: Data!
        var jsonDictionary: [String: AnyObject]!

        //Getting JSON data from URL
        do {
            jsonData = try Data(contentsOf: jsonFileURL)
        } catch let error as NSError{
            print(error.debugDescription)
            fatalError("Failed to initiate JSON data from URL!")
        }

        //getting top level JSON dictionary i.e. "members"
        do {
            jsonDictionary = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String: AnyObject]
        } catch let error as NSError{
            print(error.debugDescription)
            fatalError("Failed to initiate top level JSON dictionary")
        }

        let memebers: [[String: String]] = jsonDictionary["members"] as! [[String: String]]

        for person in memebers{
            print(person["name"]!)
        }

        return memebers
    }
}


extension ViewController: UITableViewDelegate, UITableViewDataSource{

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return members.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
        if cell == nil {
            let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
            cell.textLabel?.text = members[indexPath.row]["name"]
            return cell
        } else {
            cell?.textLabel?.text = members[indexPath.row]["name"]
            return cell!
        }
    } 
}

Результат:

введите здесь описание изображения

Не стесняйтесь задавать мне любые дополнительные вопросы, которые могут у вас возникнуть.

person fja    schedule 12.03.2017