如何使用 Swift 删除 coredata 中的特定记录?
Posted
技术标签:
【中文标题】如何使用 Swift 删除 coredata 中的特定记录?【英文标题】:how to delete particular record in coredata using Swift? 【发布时间】:2020-01-07 09:49:26 【问题描述】:我的场景是,我将 JSON 数据加载到 CoreData 中,然后我将其提取到 Tableview 中。现在,每个表格视图单元格都可以使用Delete
和Edit
按钮进行滑动。如果我点击删除,我需要从 coredata 和 tableview 这两个地方删除数据。
我的 JSON 结构
class displyDataClass
var name : String
var username : String
var email : String
init(name : String,username : String,email :String)
self.name = name
self.username = username
self.email = email
JSON 加载到 CoreData
import UIKit
import CoreData
class ViewController: UIViewController ,UITableViewDelegate,UITableViewDataSource
var displayDatasssss = [displyDataClass]()
var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad()
super.viewDidLoad()
print("hai")
// Do any additional setup after loading the view, typically from a nib.
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func numberOfSections(in tableView: UITableView) -> Int
return 1
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return displayDatasssss.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell1") as! TableViewCell1
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "User")
cell.label.text = displayDatasssss[indexPath.row].email
let _:AppDelegate = (UIApplication.shared.delegate as! AppDelegate)
let context:NSManagedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let newUser = NSEntityDescription.insertNewObject(forEntityName: "User", into: context) as NSManagedObject
newUser.setValue(cell.label.text, forKey: "name")
do
try context.save()
catch
print(newUser)
print("Object Saved.")
let myStringValue = cell.label.text
request.predicate = NSPredicate (format: "name == %@", myStringValue!)
do
let result = try context.fetch(request)
if result.count > 0
let nameData = (result[0] as AnyObject).value(forKey: "name") as! String
print(nameData)
catch
//handle error
print(error)
return cell
@IBAction func tap(_ sender: Any)
let url = "http://jsonplaceholder.typicode.com/users"
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "GET"
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request)(data, response,error)in
if (error != nil)
print("Error")
else
do
// Array of Data
let fetchData = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! NSArray
for eachData in fetchData
let eachdataitem = eachData as! [String : Any]
let name = eachdataitem["name"]as! String
let username = eachdataitem["username"]as! String
let email = eachdataitem["email"]as! String
self.displayDatasssss.append(displyDataClass(name: name, username: username,email : email))
self.tableView.reloadData()
catch
print("Error 2")
task.resume()
class displyDataClass
var name : String
var username : String
var email : String
init(name : String,username : String,email :String)
self.name = name
self.username = username
self.email = email
以下代码用于删除
// delete action two
let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: (action, indexPath) in
print("Delete tapped")
// remove the deleted item from the model
let appDel:AppDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDel.persistentContainer.viewContext
managedObjectContext.delete(self.displayDatasssssindexPath.row])
self.milestoneTitles.remove(at: indexPath.row)
do
try managedObjectContext.save()
catch _
self.tableView.deleteRows(at: [indexPath], with: .automatic)
return [editAction, deleteAction]
【问题讨论】:
请更准确地解释您的问题。 @dahiya_boy 我在managedObjectContext.delete(self.displayDatasssssindexPath.row])
收到错误Cannot convert value of type 'displyDataClass' to expected argument type 'NSManagedObject'
如果您是 ios 新手或对核心数据了解较少,我建议您参考此 -> code.tutsplus.com/tutorials/… ,会有更多帖子可用。之后,如果您仍有任何问题,我们很乐意为您提供帮助。
目前,错误是说displyDataClass
不是NSManageObject
。 NSManageObject
是您在架构中创建实体的对象。 Xcode 在内部管理NSManageObject
,您只需要对该对象进行查询。还有一个提示,在从 tableView 中删除单元格时,您需要先删除数据源。 reference
@dahiya_boy 我将 JSON 数据存储到 displayDatasssss = [displyDataClass]()
并将值存储到 coredata 现在如何使用 Swift 从 coredata 中删除特定数据
【参考方案1】:
不要使用自定义类。仅使用提供的 User
类。
首先声明一个数据源数组(替换displayDatasssss
)
var users = [User]()
在tap
方法中加载数据并在核心数据堆栈中插入新项目。考虑每次点击按钮都会将重复的项目插入数据库。旧条目不会被删除。
因为User
只有name
和id
属性,所以email
被分配给id
。
项目被附加到数据源数组并保存在上下文中。
@IBAction func tap(_ sender: Any)
let url = "http://jsonplaceholder.typicode.com/users")!
let task = session.dataTask(with: url) [unowned self] (data, response,error)in
if let error = error print(error); return
do
// Array of Data
let fetchData = try JSONSerialization.jsonObject(with: data!) as! [[String:Any]]
for eachDataItem in fetchData
let name = eachdataitem["name"] as! String
let email = eachdataitem["email"] as! String
let newUser = User(context: self.context)
newUser.name = name
newUser.id = email
self.users.append(newUser)
DispatchQueue.main.async
self.tableView.reloadData()
try self.context.save()
catch
print("Error 2", error)
task.resume()
在viewDidLoad
中从CoreData
获取数据并重新加载表格视图
override func viewDidLoad()
super.viewDidLoad()
do
let request : NSFetchRequest<User> = User.fetchRequest()
users = try context.fetch(request)
tableView.reloadData()
catch print(error)
在cellForRow
中将属性值分配给标签,仅此而已
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell1") as! TableViewCell1
let user = users[indexPath.row]
cell.label.text = user.name
return cell
delete方法和你的很像
let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: [unowned self] (action, indexPath) in
print("Delete tapped")
// remove the deleted item from the model
let objectToDelete = self.users.remove(at: indexPath.row)
self.context.delete(objectToDelete)
do
try self.context.save()
self.tableView.deleteRows(at: [indexPath], with: .automatic)
catch
print(error)
return [editAction, deleteAction]
注意:总是打印错误,不要忽略它们或只打印无意义的文字字符串
【讨论】:
你是一位伟大的程序员大师。惊人的。我很想向你学习。 :) 而不是JSONSerialization
如果我使用JSONDecoder
那么如何附加值let result = try JSONDecoder().decode(User.self, from:data) let status = result.status if status == true let item = result.data let newUser = User(context: self.context) newUser.id = ?? newUser.milestone = ??
要将 JSON 直接解码为 User
,您必须在类中采用 Decodable
。这不是微不足道的,另一个问题。无论如何,JSON 中没有密钥 status
。根对象是用户数组。
我有点困惑。我所做的一切。但是let result = try JSONDecoder().decode(User, from:data)
如果我这样做会显示错误。如何更新这个let result = try JSONDecoder().decode(User.self, from:data) let status = result.status if status == true let item = result.data let newUser = User(context: self.context) newUser.id = newUser.name = self.users.append(newUser)
这段代码不能工作有 3 个原因:#1) User
不符合 Decodable
, #2) 如果它确实解码的对象实际上是 [User].self
和 #3) 一次同样在给定 URL 的 JSON 中没有键 status
以上是关于如何使用 Swift 删除 coredata 中的特定记录?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中从 Core Data 中删除数据时删除 UITableView 行?