1

Je travaille sur un projet de données de base et je suis arrivé une erreur de complier pour la suppression du point d'un TableViewController:Impossible de convertir la valeur de type String type d'argument attendu NSManagedObject

Impossible de convertir la valeur de type String type d'argument attendu NSManagedObject

Voici le code:

var listArr:[String] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 
    let appDelegate = UIApplication.shared.delegate as! AppDelegate 
    let context = appDelegate.persistentContainer.viewContext 
    let request = NSFetchRequest<NSFetchRequestResult>(entityName:"Entity") 
    request.returnsObjectsAsFaults = false 

    do { 
     let results = try context.fetch(request) 

     if results.count > 0 { 
      for result in results as! [NSManagedObject] { 
       if let listName = result.value(forKey: "listName") { 
        listArr.append(listName as! String) 
       } 
      } 
     } 
    } catch { 
     // Handle error 
     print(error) 
    } 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let identifier = "cellID" 
    let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath) 

    // Configure the cell... 

    cell.textLabel?.text = listArr[indexPath.row] 

    return cell 
} 

// Override to support editing the table view. 
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    if editingStyle == .delete { 
     // Delete the row from the data source 
     let appDelegate = UIApplication.shared.delegate as! AppDelegate 
     let context = appDelegate.persistentContainer.viewContext 

     context.delete(listArr[indexPath.row]) //The error is here 
     listArr.remove(at: indexPath.row) 

    } 

    self.tableView.reloadData() 
} 

Que dois-je changer?

Répondre

1

La méthode delete() que vous appelez prend un NSManagedObject comme seul argument. Vous passez un élément de votre tableau listArr, qui est un tableau de chaînes.

Il semble évident de le dire, mais si vous voulez supprimer un objet géré, vous devez indiquer à Core Data celui à supprimer. Il ne sait pas quoi faire avec une chaîne.

Je deviner (puisque vous n'avez pas dit) que votre listArr est composée de chaînes qui sont stockées dans les données de base en tant que propriété d'une entité. Vous récupérez des données quelque part et n'enregistrez que les chaînes. C'est bien tant que votre magasin de données est en lecture seule, au moins dans cette partie de l'application. Vous pouvez afficher les chaînes, mais vous ne pouvez pas revenir en arrière et mettre à jour les données de base car vous ne disposez pas des informations nécessaires. Si cela est vrai, ce que vous devez faire est d'utiliser un tableau d'objets gérés au lieu d'un tableau de chaînes. Lorsque vous avez besoin de la valeur de chaîne, récupérez-la dans l'un des objets gérés. Lorsque vous devez supprimer une entrée, supprimez cet objet géré.

+0

Après avoir modifié le tableau en [NSManagedObject], une autre erreur, qui est passée de NSManagedObject à un type non lié 'string', échoue toujours, elle se trouve dans la méthode cellForRowAt indexPath. –

0

Il existe deux façons de remplir une table à partir de données de base. Soit vous pouvez utiliser un NSFetchedResultsController qui suit les modifications à partir des données de base et maintient vos données en synchronisation. Ou vous pouvez faire un seul chargement et stocker les valeurs que vous voulez afficher dans notre propre source de données (comme un tableau).

Avec un NSFetchedResultsController, vous obtiendrez des mises à jour que vos données changent. Avec ce modèle, la manière correcte de supprimer une ligne est de la supprimer des données de base et d'attendre un rappel du NSFetchedResultsController pour mettre à jour votre vue.

Avec un seul fetch (comme vous le faites) vous n'obtenez pas de mises à jour en tant que changements de données de base. Dans ce modèle, vous pouvez simplement supprimer l'objet de votre tableau et mettre à jour la vue. La mise à jour des données de base est une autre tâche sans rapport avec votre vue ou votre source de données. Dans ce cas, vous devez utiliser persistentContainer pour récupérer l'objet que vous souhaitez supprimer, puis le supprimer en arrière-plan. Pour que cela fonctionne, vous devez avoir un moyen de récupérer le managedObject que vous devez supprimer. Je ne sais pas quel genre de cordes vous stockez - mais si elles sont uniques, vous pouvez les utiliser pour votre recherche. Sinon, vous devrez également stocker un identifiant unique de l'objet tel que objectID.