Ios 如何更新已保存在Swift中的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

我不确定我在这里做错了什么,但是当我第一次保存到coredata中时,它工作得很好。当我试图覆盖它时,它不会

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中处理错误。 最后I
context.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