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

Accepted Reply

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)
      }
  • Hello, thank you very much for the help!

    I really appreciate your patience and enthusiasm for supporting me. With great regret I tell you that I do not have enough knowledge in Swift. What I have in the app is based on tutorials that I have seen and that I have learned over time. I will take your recommendations into account as it inspires me to improve my development with Swift.

    Thank you very much for your help. I send you a hug!

  • Thanks. Don't worry, we all have started as Swift beginners.

Add a Comment

Replies

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 ?

  • Hello, I get the error in the class "InteresesViewController.swift" and in this part of the code:

     for index in arr{         selectInteres.append(feedInterests[indexPath.row] as! String)       }

    From that data that is shown to the table, the user must select the data, whatever it is, and the selected data must be stored in an array. The intention is that only the "jsonElement [" interesNombre "]" string are saved in the array. Thanks!

Add a Comment

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)
      }
  • Hello, thank you very much for the help!

    I really appreciate your patience and enthusiasm for supporting me. With great regret I tell you that I do not have enough knowledge in Swift. What I have in the app is based on tutorials that I have seen and that I have learned over time. I will take your recommendations into account as it inspires me to improve my development with Swift.

    Thank you very much for your help. I send you a hug!

  • Thanks. Don't worry, we all have started as Swift beginners.

Add a Comment