Ios 如何更新已保存在Swift中的CoreData条目?
我不确定我在这里做错了什么,但是当我第一次保存到coredata中时,它工作得很好。当我试图覆盖它时,它不会Ios 如何更新已保存在Swift中的CoreData条目?,ios,core-data,swift,Ios,Core Data,Swift,我不确定我在这里做错了什么,但是当我第一次保存到coredata中时,它工作得很好。当我试图覆盖它时,它不会 func testStuff() { var token = loadLoginData() println("Token \(token)") saveLoginData("New Token") var newToken = loadLoginData() println("Token \(newToken)") } func saveLog
func testStuff() {
var token = loadLoginData()
println("Token \(token)")
saveLoginData("New Token")
var newToken = loadLoginData()
println("Token \(newToken)")
}
func saveLoginData(accessToken: String) {
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context: NSManagedObjectContext = appDel.managedObjectContext!
// save data to core data
var loginData = NSEntityDescription.insertNewObjectForEntityForName("LoginData", inManagedObjectContext: context) as NSManagedObject
loginData.setValue(accessToken, forKey: "accessToken")
context.save(nil)
println("Done saving user")
}
/* Output
Token Optional("12345")
Done saving user
Token Optional("12345")
*/
加载登录数据函数
调用saveLogin数据的函数
func loadLoginData() -> String? {
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context: NSManagedObjectContext = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "LoginData")
request.returnsObjectsAsFaults = false
var results: NSArray = context.executeFetchRequest(request, error: nil)!
if (results.count > 0) {
var userData: NSManagedObject = results[0] as NSManagedObject
var accessToken: String = userData.valueForKey("accessToken") as String
return accessToken.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
} else {
println("0 results returned, potential error")
return nil
}
}
有一个新功能叫做批量更新 我认为本文将帮助您: 基本操作是使用
NSBatchUpdateRequest
而不是NSFetchRequest
,使用NSPredicate
过滤结果,更改结果中的值,然后保存数据
swift中的另一个教程:
您正在创建多个新的
LoginData
对象,但您的loadLoginData
方法总是返回同一个对象,即从获取请求结果返回的第一个对象
您希望不断更新同一对象,因此需要更改saveLoginDetails
方法
使用loadLoginDetails
方法获取现有对象,并更改其中的属性,而不是创建新对象(这就是insertNewObjectForEntityName
)
var context: NSManagedObjectContext = appDel.managedObjectContext!
var en = NSEntityDescription.entityForName("ENTITIES_NAME", inManagedObjectContext: context)
let batchUpdateRequest = NSBatchUpdateRequest(entity: en!)
batchUpdateRequest.resultType = NSBatchUpdateRequestResultType.UpdatedObjectIDsResultType
batchUpdateRequest.propertiesToUpdate = ["OBJECT_KEY": "NEWVALUE"]
var batchUpdateRequestError: NSError?
context.executeRequest(batchUpdateRequest, error: &batchUpdateRequestError)
if let error = batchUpdateRequestError {
println("error")
}
祝你好运因为batchupdate在更大的数据块中更有用,所以我认为这是一种更微妙的方法
func saveLoginData(accessToken: String, userName: String) {
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context: NSManagedObjectContext = appDel.managedObjectContext!
var fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "LoginData")
fetchRequest.predicate = NSPredicate(format: "userName = %@", userName)
if let fetchResults = appDel.managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [NSManagedObject] {
if fetchResults.count != 0{
var managedObject = fetchResults[0]
managedObject.setValue(accessToken, forKey: "accessToken")
context.save(nil)
}
}
}
func saveloginanda(accessToken:String,userName:String){
var appDel:AppDelegate=(UIApplication.sharedApplication().delegate作为AppDelegate)
变量上下文:NSManagedObjectContext=appDel.managedObjectContext!
var fetchRequest=NSFetchRequest(entityName:“LoginData”)
fetchRequest.predicate=NSPredicate(格式:“userName=%@”,userName)
如果让fetchResults=appDel.managedObjectContext!.executeFetchRequest(fetchRequest,错误:nil)作为?[NSManagedObject]{
如果fetchResults.count!=0{
var managedObject=fetchResults[0]
managedObject.setValue(accessToken,forKey:“accessToken”)
context.save(无)
}
}
}
如果我没弄错的话,我试着把它翻译成你的情况,但还没有测试过
fetchRequest.predicate
基本上设置实体loginda
中属性userName
上的过滤器,以及调用函数时输入的(用户名)。假设在本例中,您只有一个同名的用户名。然后,它使用给定的过滤器执行fetchrequest
,因此您可以使用调用函数时输入的accesToken
更改它的值。以下代码:如果fetchResults.count!=0
,仅当用户名
存在时执行 Swift>=2该方法现在返回一个非可选值,并在错误情况下抛出一个错误,必须使用try-catch进行处理:
let context = self.fetchedResultsController.managedObjectContext
let entity = self.fetchedResultsController.fetchRequest.entity!
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
fetchRequest.predicate = NSPredicate(format: "notificationId = 13")
do {
let list = try context.executeFetchRequest(fetchRequest) as? [NSManagedObject]
// Check notificationId available then not save
if list!.count == 0 {
let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName(entity.name!, inManagedObjectContext: context)
newManagedObject.setValue("This is first message13", forKey: "message")
newManagedObject.setValue(1, forKey: "appId")
newManagedObject.setValue(13, forKey: "notificationId")
newManagedObject.setValue("First one", forKey: "tital")
}
// success ...
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
let context=self.fetchedResultsController.managedObjectContext
让entity=self.fetchedResultsController.fetchRequest.entity!
让fetchRequest=NSFetchRequest(entityName:entity.name!)
fetchRequest.predicate=NSPredicate(格式:“notificationId=13”)
做{
let list=try context.executeFetchRequest(fetchRequest)as?[NSManagedObject]
//检查notificationId是否可用,然后不保存
如果列表!.count==0{
让newManagedObject=NSEntityDescription.insertNewObjectForEntityForName(entity.name!,inManagedObjectContext:context)
setValue(“这是第一条消息13”,forKey:“消息”)
setValue(1,forKey:“appId”)
setValue(13,forKey:“notificationId”)
setValue(“第一个”,forKey:“tital”)
}
//成功。。。
}将let错误捕获为NSError{
//失败
打印(“提取失败:\(错误。localizedDescription)”)
}
为Swift 4和XCode 9.2更新
要回答你的问题
如何更新已保存在Swift中的CoreData条目
首先需要获取对AppDelegate
和viewContext
的引用。然后,您需要为要更新的实体设置一个NSFetchRequest
,在我的示例中,它将是“警报”。然后设置fetch以查找您要查找的结果。在本例中,我的结果根据警报的创建日期和警报类型找到了警报
进一步阅读如何使用谓词进行查询。
&
然后我context.fetch(fetchRequest)
,将结果设置为我想要更新的值,并在try-catch中处理错误。
最后Icontext.save()
让appDelegate=UIApplication.shared.delegate为!AppDelegate
让上下文=appDelegate.persistentContainer.viewContext
let fetchRequest=NSFetchRequest(entityName:“警报”)
fetchRequest.predicate=NSPredicate(格式:“creationDate=%@和alertType=%&”,
argumentArray:[creationDate,alertType])
做{
let results=try context.fetch(fetchRequest)as?[NSManagedObject]
如果结果为?.count!=0{//至少返回了一个
//在我的例子中,我只更新了结果中的第一项
结果[0]。设置值(YourValueToSet,forKey:“yourCoreDataAttribute”)
}
}抓住{
打印(“提取失败:\(错误)”)
}
做{
尝试context.save()
}
抓住{
打印(“保存核心数据失败:\(错误)”)
}
这对我很有效,你应该试试这个:
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return}
let managedContext = appDelegate.persistentContainer.viewContext
// if object nil is checked if new entity will be created or created one will be updated
if object == nil {
// create new entity:
let entityObj = NSEntityDescription.entity(forEntityName: "EntityName", in: managedContext)!
let entity = NSManagedObject(entity: entityObj, insertInto: managedContext)
entity("new value", forKeyPath: "entityValue")
do {
try managedContext.save()
entities.append(entity)
self.navigationController?.popViewController(animated: true)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
else {
// the created entity will be updated selected object is entity -> came from previous view controller:
self.entity?.setValue("updated value", forKey: "entityValue")
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
self.navigationController?.popViewController(animated: true)
}
let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Students", in: managedContext)
let request = NSFetchRequest<NSFetchRequestResult>()
request.entity = entity
let predicate = NSPredicate(format: "(name = %@)", txtName.text!)
request.predicate = predicate
do {
var results =
try managedContext.fetch(request)
let objectUpdate = results[0] as! NSManagedObject
objectUpdate.setValue(txtName.text!, forKey: "name")
objectUpdate.setValue(txtPhone.text!, forKey: "phone")
objectUpdate.setValue(txt_Address.text!, forKey: "address")
do {
try managedContext.save()
txtName.text = ""
txtPhone.text = ""
txt_Address.text = ""
labelStatus.text = "Updated"
}catch let error as NSError {
labelStatus.text = error.localizedFailureReason
}
}
catch let error as NSError {
labelStatus.text = error.localizedFailureReason
}
这对我很有用你应该试试这个:
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return}
let managedContext = appDelegate.persistentContainer.viewContext
// if object nil is checked if new entity will be created or created one will be updated
if object == nil {
// create new entity:
let entityObj = NSEntityDescription.entity(forEntityName: "EntityName", in: managedContext)!
let entity = NSManagedObject(entity: entityObj, insertInto: managedContext)
entity("new value", forKeyPath: "entityValue")
do {
try managedContext.save()
entities.append(entity)
self.navigationController?.popViewController(animated: true)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
else {
// the created entity will be updated selected object is entity -> came from previous view controller:
self.entity?.setValue("updated value", forKey: "entityValue")
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
self.navigationController?.popViewController(animated: true)
}
let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Students", in: managedContext)
let request = NSFetchRequest<NSFetchRequestResult>()
request.entity = entity
let predicate = NSPredicate(format: "(name = %@)", txtName.text!)
request.predicate = predicate
do {
var results =
try managedContext.fetch(request)
let objectUpdate = results[0] as! NSManagedObject
objectUpdate.setValue(txtName.text!, forKey: "name")
objectUpdate.setValue(txtPhone.text!, forKey: "phone")
objectUpdate.setValue(txt_Address.text!, forKey: "address")
do {
try managedContext.save()
txtName.text = ""
txtPhone.text = ""
txt_Address.text = ""
labelStatus.text = "Updated"
}catch let error as NSError {
labelStatus.text = error.localizedFailureReason
}
}
catch let error as NSError {
labelStatus.text = error.localizedFailureReason
}
让managedContext=(UIApplication.shared.delegate为!AppDelegate)。persistentContainer.viewContext
让entity=NSEntityDescription.entity(在:managedContext中,名为“学生”)
let request=NSFetchRequest()
request.entity=实体
let predicate=NSPredicate(格式:“(name=%@)”,txtName.text!)
request.predicate=谓词
做{
var结果=
尝试managedContext.fetch(请求)
将objectUpdate=results[0]设为!NSManagedObject
import UIKit
class UserCell: UITableViewCell {
@IBOutlet var lblName: UILabel!
@IBOutlet var lblEmail: UILabel!
@IBOutlet var lblPost: UILabel!
@IBOutlet var lblPhone: UILabel!
@IBOutlet var imageData: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
self.imageData.layer.cornerRadius = self.imageData.frame.height / 2
self.imageData.layer.borderWidth = 1.0
self.imageData.layer.borderColor = UIColor.lightGray.cgColor
self.imageData.layer.masksToBounds = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
import UIKit
import CoreData
class AddUser_VC: UIViewController ,UIImagePickerControllerDelegate ,UINavigationControllerDelegate {
var dictObj: NSManagedObject!
var isEdit:Bool = false
@IBOutlet var imageData: UIImageView!
@IBOutlet var txtName: UITextField!
@IBOutlet var txtEmail: UITextField!
@IBOutlet var txtPost: UITextField!
@IBOutlet var txtPhone: UITextField!
@IBOutlet var btnAddUser: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
self.imageData.layer.cornerRadius = self.imageData.frame.height / 2
self.imageData.layer.borderWidth = 1.0
self.imageData.layer.borderColor = UIColor.lightGray.cgColor
self.imageData.layer.masksToBounds = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
self.imageData.isUserInteractionEnabled = true
self.imageData.addGestureRecognizer(tapGestureRecognizer)
if (self.isEdit == true)
{
self.txtName.text = dictObj.value(forKey: "name") as? String ?? ""
self.txtEmail.text = dictObj.value(forKey: "email") as? String ?? ""
self.txtPost.text = dictObj.value(forKey: "post") as? String ?? ""
self.txtPhone.text = String(dictObj.value(forKey: "phone") as? Int ?? 0)
self.imageData?.image = UIImage(data: dictObj?.value(forKey: "image") as? Data ?? Data())
self.btnAddUser.setTitle("UPDATE", for: .normal)
}
}
//MARK: - btnAddUserAction Method -
@IBAction func btnAddUserAction(_ sender: Any) {
let arrData = [self.txtName,self.txtEmail,self.txtPost,self.txtPhone]
for txt in arrData
{
if (txt?.text == "")
{
let alert = UIAlertController(title: "Alert", message: "Please Enter All Fields", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
}
self.createData()
}
//MARK: - Image Tap Method -
@objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
let alert = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { _ in
self.openCamera()
}))
alert.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { _ in
self.openGallery()
}))
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
func openCamera()
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerController.SourceType.camera
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func openGallery()
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have permission to access gallery.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard (info[.originalImage] as? UIImage) != nil else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
self.imageData.image = info[.originalImage] as? UIImage
picker.dismiss(animated: true, completion: nil)
}
//MARK: - createData
func createData(){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let userEntity = NSEntityDescription.entity(forEntityName: "UserTable", in: managedContext)!
var user = NSManagedObject()
if(isEdit == true)
{
user = self.dictObj
}
else
{
user = NSManagedObject(entity: userEntity, insertInto: managedContext)
}
let image = self.imageData.image!.jpegData(compressionQuality: 0.5)as NSData?
user.setValue(self.txtName.text, forKeyPath: "name")
user.setValue(self.txtEmail.text, forKey: "email")
user.setValue(self.txtPost.text, forKey: "post")
user.setValue(Int(self.txtPhone.text!), forKey: "phone")
user.setValue(image, forKey: "image")
do {
try managedContext.save()
self.navigationController?.popViewController(animated: true)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
}
//MARK: - CoreData Methods -
func createData(){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let userEntity = NSEntityDescription.entity(forEntityName: "Movie", in: managedContext)!
for obj in self.MoviewList.arrMovieData{
let user = NSManagedObject(entity: userEntity, insertInto: managedContext)
user.setValue(obj.id, forKey: "id")
user.setValue(obj.title, forKey: "title")
user.setValue(obj.overview, forKey: "overview")
let url = API.IMAGE_BASE_URL + obj.poster_path
user.setValue(url, forKey: "poster_path")
}
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
func retrieveData() {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Movie")
do {
let result = try managedContext.fetch(fetchRequest)
var arr = [[String:AnyObject]]()
for data in result as! [NSManagedObject] {
var obj = [String:AnyObject]()
obj["id"] = data.value(forKey: "id") as AnyObject
obj["title"] = data.value(forKey: "title") as AnyObject
obj["overview"] = data.value(forKey: "overview") as AnyObject
obj["poster_path"] = data.value(forKey: "poster_path") as AnyObject
arr.append(obj)
}
self.MoviewList = MovieDataList(data: arr)
self.tableView.reloadData()
} catch {
print("Failed")
}
}
func deleteAllRecords() {
let delegate = UIApplication.shared.delegate as! AppDelegate
let context = delegate.persistentContainer.viewContext
let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Movie")
let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
do {
try context.execute(deleteRequest)
try context.save()
self.createData()
} catch {
}
}
func updateTaskStatus(status: Bool){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<Task> = Task.fetchRequest()
let predicate = NSPredicate(format: "(taskName = %@)", (task?.taskName)!)
fetchRequest.predicate = predicate
do {
let result = try managedContext.fetch(fetchRequest)
task = result[0] as NSManagedObject as? Task
task?.setValue(status, forKey: "status")
do {
try managedContext.save()
}catch let error as NSError {
print("\(error)")
}
}catch let error as NSError {
print("\(error)")
}
}
func update(accessToken:String,username:String){
//1
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
//2
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "LoginData")
// 3
let predicate = NSPredicate(format: "%K == %@", "username", username)
fetchRequest.predicate = predicate
//3
do {
let rs = try managedContext.fetch(fetchRequest)
for result in rs as [NSManagedObject] {
// update
do {
var managedObject = rs[0]
managedObject.setValue(accessToken, forKey: "accessToken")
try managedContext.save()
print("update successfull")
} catch let error as NSError {
print("Could not Update. \(error), \(error.userInfo)")
}
//end update
}
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
var isNewRecord = false
let aNewContact: Contact!
let fetchContact: NSFetchRequest<Contact> = Contact.fetchRequest() as! NSFetchRequest<Contact>
fetchContact.predicate = NSPredicate(format: "record_id == %@", contactRemoteModel.contacts[i].record_id as CVarArg)
let results = try? managedObjectContext.fetch(fetchContact)
if results?.count == 0 {
// here you are inserting
aNewContact = Contact(context: managedObjectContext)
aNewContact.id = UUID()
isNewRecord = true
print("Insert")
} else {
// here you are updating
aNewContact = results?.first
print("UpDate")
}
#Update Data in #CoreData #iOS #swift
Simply follow below steps to update data in CoreData which you already saved
#Step1 :- refer to persistent container & create object of viewContext
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let viewContext = appDelegate.persistentContainer.viewContext
#Step2 :- create FetchRequest
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "User") // here User is entity name
//Step3 :- add predicate to fetch request by passing attribute and value
fetchRequest.predicate = NSPredicate(formate: "userName = %@","XYZ")
//Step4 :- fetch record using viewContext by passing fetchRequest and set new value in it
do {
let results = try viewContext.fetch(fetchRequest) as? [NSManagedObject]
if result?.count !=0 {
result?[0].setValue("ABC",forKey: "userName")
}
} catch {
print("failed to fetch record from CoreData")
}
//Step5 :- finally call save method of viewcontext so new value get reflect in CoreData
do {
viewContext.save()
} catch {}
Note :- in predicate the value "XYZ" can be value of attribute and format will contain name of attribute such like username , age password ....etc , in result?[0].setValue you can set new value for particular attribute by passing value and keynote , you can skip step5 and can execute save method inside step4 after Line where we setting new value