0

I have a problem and I do not know how to solve it, I have a json that I keep in a variable and I would like to list it in a TableView. So far I have learned how to do it by downloading the json but never locally. I attach my code:

CoreDataViewController.swift (here is my table)

import UIKit

class CoreDataViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, DatosModeloProtocol {

    var itemStruct: NSArray = NSArray()
    var selectPersona: DetalleJSON = DetalleJSON()
    @IBOutlet weak var listaTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

    self.listaTableView.delegate = self
    self.listaTableView.dataSource = self

    let datosModelo = DatosModelo()
    datosModelo.delegate = self
    datosModelo.downloadItems()


        // Do any additional setup after loading the view.
    }

    func itemsJSON(items: NSArray) {
        itemStruct = items
        self.listaTableView.reloadData()
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CoreDataTableViewCell
        let item: DetalleJSON = itemStruct[indexPath.row] as! DetalleJSON
      //  cell.lblID!.text = item.id
        cell.lblNombre!.text = item.nombre
        cell.lblAlias!.text = item.alias
        cell.lblFechaNac!.text = item.fechaNac
        cell.lblPosicion!.text = item.posicion

        return cell
    }
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}

DatosModelo.swift (the protocol)

import UIKit
protocol DatosModeloProtocol: class{
    func itemsJSON (items: NSArray)
}

class DatosModelo: NSObject {

    weak var delegate: DatosModeloProtocol!

    let urlPath = "{
     "respuestas": [
            {
              "id": 1,
              "nombre": "Miguel Cervantes",
              "fechaNac": "8/Dic/1990",
              "posicion": "Desarrollador",
              "alias": "preg1"
            },
            {
              "id": 2,
              "nombre": "Juan Morales",
              "fechaNac": "03/Jul/1990",
              "posicion": "Diseñador",
              "alias": "preg2"
            },
            {
              "id": 3,
              "nombre": "Roberto Méndez",
              "fechaNac": "14/Dic/1990",
              "posicion": "Desarrollador",
              "alias": "preg3"
            },
            {
              "id": 4,
              "nombre": "Miguel Cuevas",
              "fechaNac": "08/Dic/1990",
              "posicion": "Programador",
              "alias": "preg4"
            }
      ]
}"

func downloadItems() {
        let url: URL = URL (string: urlPath)!
        let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
        let task = defaultSession.dataTask(with: url){
            (data, response, error) in
            if error != nil{
                print("Error al descargar datos")
            }else{
                print("Datos descargados")
                self.parseJSON(data!)
            }
        }
        task.resume()
    }


    func parseJSON(_ data:Data){
        var jsonResult = NSArray()
        do{
            jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! NSArray
        }catch let error as NSError{
            print(error)
    }
    var jsonElement = NSDictionary()
    let detalles = NSMutableArray()
    for i in 0 ..< jsonResult.count
    {
        jsonElement = jsonResult[i] as! NSDictionary
        let detalle = DetalleJSON()
        let id = jsonElement["id"]
        let nombre = jsonElement["nombre"]
        let fechaNac = jsonElement["fechaNac"]
        let posicion = jsonElement["posicion"]
        let alias = jsonElement["alias"]

        detalle.id = id as? Int
        detalle.nombre = nombre as? String
        detalle.fechaNac = fechaNac as? String
        detalle.posicion = posicion as? String
        detalle.alias = alias as? String
        detalles.add(detalle)
        }
        DispatchQueue.main.async(execute: { () -> Void in
            self.delegate.itemsJSON(items: detalles)
        })
    }
}

DetalleJSON.swift

import UIKit

class DetalleJSON: NSObject {

    var id: Int?
    var nombre: String?
    var fechaNac: String?
    var posicion: String?
    var alias: String?

    override init() {

    }

    init(id: Int, nombre: String, fechaNac: String, posicion: String, alias: String){

        self.id = id
        self.nombre = nombre
        self.fechaNac = fechaNac
        self.posicion = posicion
        self.alias = alias
    }

    override var description: String{
        return "id: \(id), nombre: \(nombre), fechaNac: \(fechaNac), posicion: \(posicion), alias: \(alias)"
    }
}

CoreDataTableViewCell.swift

import UIKit

class CoreDataTableViewCell: UITableViewCell {

    @IBOutlet weak var lblNombre: UILabel!
    @IBOutlet weak var lblFechaNac: UILabel!
    @IBOutlet weak var lblID: UILabel!
    @IBOutlet weak var lblAlias: UILabel!
    @IBOutlet weak var lblPosicion: UILabel!
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

Thank you very much for reading my question, and for the support.

Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
Rodrigo
  • 19
  • 6
  • keep it simple, where you got error, which value cause of crash ? – Muhammad Shauket Feb 12 '19 at 06:34
  • 2
    Can we assume that you read (all of) [What does “fatal error: unexpectedly found nil while unwrapping an Optional value” mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) ? – Martin R Feb 12 '19 at 06:45
  • yep. tell us in which line the error occurs. Btw: you double force unwrap your labels from CoreDataTableViewCell. From CoreDataTableViewCell.swift it looks like these labels are linked via storyboard but in `cellForRowAt:indexPath` you force unwrap these labels (again?) – Teetz Feb 12 '19 at 06:46
  • The error occurs in let url: URL = URL (string: urlPath)! – Rodrigo Feb 12 '19 at 19:29

1 Answers1

0

urlPath should be a String representing a URL address, not a JSON ! So here: let url: URL = URL (string: urlPath)! will crass Because of the !. It can not initialize a URL from a json and you forced it. So it will crash.

Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278