Wraith
Wraith

Reputation: 501

How save model after pass as param ? or get as function ? core data

Problem 1.

I have a tableViewController

var stocksResults: [Any] = []

override func viewDidLoad() {
    super.viewDidLoad()        
    loadList()
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "toTrade" {
        let indexPath = self.stockTableView.indexPathForSelectedRow
        let vc = segue.destination as! StockTradeController
        vc.stockResults = stocksResults[indexPath!.row] as AnyObject
    }    
}

func loadList() {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext

    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Stocks")
    fetchRequest.returnsObjectsAsFaults = false

    do {stocksResults = try context.fetch(fetchRequest)}
    catch {print("Error")}

   stockTableView.reloadData()
}

code is simple, i show data from CoreData entity Stocks and when iIclick on row i will pass model to another viewController as

vc.stockResults = stocksResults[indexPath!.row] as AnyObject

in other view i can modify this model

(stockResults as AnyObject).setValue(345, forKey: "own")

And the question is how can i save model after modification ?


Problem 2

I created class

class UserAccount {
    
    func getData() -> Array<Any> {
        
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Account")
        fetchRequest.returnsObjectsAsFaults = false
        
        do {
            let accountUser = try context.fetch(fetchRequest)
            return accountUser
        }
        catch {print("Error")}
        
        return []
        
    }
}

i can get and change model in any VC

(UserAccount().getData()[0] as AnyObject).setValue(433, forKey: "cash")

I can run this function from any VC and the same question how can i save changes ? Should i pass context in both cases some how ? or what is the best way ?

Upvotes: 0

Views: 36

Answers (1)

vadian
vadian

Reputation: 285079

If you have the standard implementation of the Core Data stack in AppDelegate (it seems so) you can save the context from everywhere with

let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.saveContext()

There are many bad practices in your code.

  • Declare the data source array with the specific entity type

      var stocksResults: [Stocks] = []
    

    This avoids the ugly type cast to AnyObject

  • In the second view controller you are dealing with a single object so declare

     var stock : Stocks!
    

    and assign

     vc.stock = stocksResults[indexPath!.row] 
    
  • By the way it's recommended to name also an entity in singular form (Stock)

  • In loadList() specify the fetch request and print the real error

    func loadList() {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
    
        let fetchRequest = NSFetchRequest<Stocks>(entityName: "Stocks")
        fetchRequest.returnsObjectsAsFaults = false
    
        do {
           stocksResults = try context.fetch(fetchRequest)
        } catch {print(error)}
    
        stockTableView.reloadData()
    }
    
  • Rather than KVC use dot notation

    stock.own = 345
    
  • In UserAccount do the same: Take advantage of the generic fetch request and return the Entity

    func getData() -> Array<Account> { ...
    

Upvotes: 1

Related Questions