Could not cast value of type (0x10ca9be10) to 'NSString' (0x7fff86d8bbb0)

Hello good afternoon to everyone. I hope you are doing very well despite the situation we are going through. I tell you my problem. I am trying to save in an array, a series of data that is selected from a tableView through a JSON. That is, the tableView shows some data available to select, the ones that are selected I want to save them in an array but when I select a data in the tableView my app crashes and shows me a breakpoint "Thread 1: signal SIGABRT" And in the console I get this: Could not cast value of type 'MallConcierge.DetallesIntereses' (0x10ca9be10) to 'NSString' (0x7fff86d8bbb0). I hope you can help me, I attach the classes from where I download the data, the details and the class where I connect the tableView.

InteresesModelo.swift (in this class is where I download the data in JSON)

import UIKit

protocol InteresesModeloProtocol: class{
    func interesesDownload (interest: NSArray)
}

class InteresesModelo: NSObject {
    
    weak var delegate: InteresesModeloProtocol!
    
    let urlPath = "http://localhost:8888/mallconcierge/API-movil/interests.php"
    
    func interestDownload(){
        
        let url: URL = URL(string: urlPath)!
        let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.ephemeral)
        URLCache.shared.removeAllCachedResponses()
        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 = DetallesIntereses()
            
            let idInteres = jsonElement["idInteres"]
            let nombreInteres = jsonElement["interesNombre"]
            
            detalle.idInteres = idInteres as? String
            detalle.nombreInteres = nombreInteres as? String
            
            detalles.add(detalle)
            
        }
        
        DispatchQueue.main.async(execute: { ()-> Void in
            
            self.delegate.interesesDownload(interest: detalles)
        })
            
        
    }

}

DetallesIntereses.swift

import UIKit

class DetallesIntereses: NSObject {
    
    var idInteres: String?
    var nombreInteres: String?
    
    override init() {
        
    }
    
    init(idInteres: String, nombreInteres:String) {
        
        self.idInteres = idInteres
        self.nombreInteres = nombreInteres
        
    }
    
    override var description: String{
        
        return "idInteres: \(idInteres), nombreInteres: \(nombreInteres)"
        
    }

}

InteresesViewController.swift

import UIKit

class InteresesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource,   InteresesModeloProtocol {
    
    var selectIntereses = [String]()
    
    var feedInterests: NSArray = NSArray()
    
   // var selectInterests: DetallesIntereses = DetallesIntereses()
    
    var items=[String]()
    
    @IBOutlet var listaInteresesTableView: UITableView!

    func interesesDownload(interest: NSArray) {
        
        feedInterests = interest
        self.listaInteresesTableView.reloadData()
        
    }
    
    
    override func viewDidLoad() {
        
        self.listaInteresesTableView.isEditing = true
        self.listaInteresesTableView.allowsMultipleSelectionDuringEditing = true

        self.listaInteresesTableView.delegate = self
        self.listaInteresesTableView.dataSource = self
        
        let interesesModelo = InteresesModelo()
        interesesModelo.delegate = self
        interesesModelo.interestDownload()
        
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return feedInterests.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "celInterests", for: indexPath) as! InteresesTableViewCell
        
        let interest: DetallesIntereses = feedInterests[indexPath.row] as! DetallesIntereses
        
        cell.lblNombreIntereses!.text = interest.nombreInteres
        
        return cell
        
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        

        
        self.selectDeselectCell(tableView: listaInteresesTableView, indexPath: indexPath)
        print("Seleccionado")
        
    }
    
    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        self.selectDeselectCell(tableView: listaInteresesTableView, indexPath: indexPath)
        print("Deseleccionado")
    }
    
    func selectDeselectCell(tableView: UITableView, indexPath: IndexPath){
        self.selectIntereses.removeAll()
        
        if let arr = listaInteresesTableView.indexPathsForSelectedRows{
     
            
            for index in arr{
                selectIntereses.append(feedInterests[indexPath.row] as! String)
            }
        }
        print(selectIntereses)
    }
    
    @IBAction func seleccionarIntereses(_ sender: Any){
        
        print(selectIntereses)

    }
    
    /*
    // 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.
    }
    */

}

The JSON

[
{
    "idInteres": "1",
    "interesNombre": "Moda Mujer"
},
{
    "idInteres": "3",
    "interesNombre": "Moda Hombre"
},
{
    "idInteres": "4",
    "interesNombre": "Belleza"
},
{
    "idInteres": "5",
    "interesNombre": "Relojes y Joyería"
},
{
    "idInteres": "6",
    "interesNombre": "Hogar/Interiorismo"
},
{
    "idInteres": "7",
    "interesNombre": "Gastronomía"
},
{
    "idInteres": "8",
    "interesNombre": "Entretenimiento"
},
{
    "idInteres": "9",
    "interesNombre": "Wellness"
}
]

I hope you can help me, please. I thank you all

Answered by Claude31 in 682913022

So, the error is here :

    func selectDeselectCell(tableView: UITableView, indexPath: IndexPath) {
        self.selectIntereses.removeAll()
        
        if let arr = listaInteresesTableView.indexPathsForSelectedRows {
            for index in arr {
                selectIntereses.append(feedInterests[indexPath.row] as! String)
            }
        }
        print(selectIntereses)
    }

I don't understand your code:

  • you loop for index, but index is nowhere used !
  • did you mean:
                selectIntereses.append(feedInterests[index.row] as! String)
  • Now, feedInterests is set here:
    func interesesDownload(interest: NSArray) {
        feedInterests = interest
        self.listaInteresesTableView.reloadData()
    }

when called by:

            self.delegate.interesesDownload(interest: detalles)
  • So, feedInterests is an array (NSArray) of DetallesIntereses
  • Hence, each item is DetallesIntereses, not a String.

So, you probably want to call:

                selectIntereses.append(feedInterests[index.row].nombreInteres as! String)

or

        if let interest = feedInterests[index.row] as? DetallesIntereses, let nombre =  interest.nombreInteres {
                selectIntereses.append(nombre)
        }

Note: there are several issues with your code:

  • why use NSMutableArray, NSArray, … and not simply Array ?
  • nombreInteres is a String? why test for String ?
  • forcing a downcast (as!) as you do all over the code is risky (crash if JSON returns a nil).

You'd better do :

      if let nombre = feedInterests[index.row].nombreInteres {
            selectIntereses.append(nombre)
      }

That would help if you told exactly where you get the error. We have to search in your code to find it…

Is it in this part ? Which line ?

1.         for i in 0 ..< jsonResult.count{
2.             
3.             jsonElement = jsonResult[i] as! NSDictionary
4.             let detalle = DetallesIntereses()
5.             
6.             let idInteres = jsonElement["idInteres"]
7.              let nombreInteres = jsonElement["interesNombre"]
8.             
9.             detalle.idInteres = idInteres as? String
10.            detalle.nombreInteres = nombreInteres as? String
11.             
12.            detalles.add(detalle)
13.             
14.         }

Could you show also how MallConcierge is defined ?

Accepted Answer

So, the error is here :

    func selectDeselectCell(tableView: UITableView, indexPath: IndexPath) {
        self.selectIntereses.removeAll()
        
        if let arr = listaInteresesTableView.indexPathsForSelectedRows {
            for index in arr {
                selectIntereses.append(feedInterests[indexPath.row] as! String)
            }
        }
        print(selectIntereses)
    }

I don't understand your code:

  • you loop for index, but index is nowhere used !
  • did you mean:
                selectIntereses.append(feedInterests[index.row] as! String)
  • Now, feedInterests is set here:
    func interesesDownload(interest: NSArray) {
        feedInterests = interest
        self.listaInteresesTableView.reloadData()
    }

when called by:

            self.delegate.interesesDownload(interest: detalles)
  • So, feedInterests is an array (NSArray) of DetallesIntereses
  • Hence, each item is DetallesIntereses, not a String.

So, you probably want to call:

                selectIntereses.append(feedInterests[index.row].nombreInteres as! String)

or

        if let interest = feedInterests[index.row] as? DetallesIntereses, let nombre =  interest.nombreInteres {
                selectIntereses.append(nombre)
        }

Note: there are several issues with your code:

  • why use NSMutableArray, NSArray, … and not simply Array ?
  • nombreInteres is a String? why test for String ?
  • forcing a downcast (as!) as you do all over the code is risky (crash if JSON returns a nil).

You'd better do :

      if let nombre = feedInterests[index.row].nombreInteres {
            selectIntereses.append(nombre)
      }
Could not cast value of type (0x10ca9be10) to 'NSString' (0x7fff86d8bbb0)
 
 
Q