7

I'm new to iOS development and was wanting to know which data type I should specify to store multiple strings (array). The app is to do with food and I need to store multiple ingredients as one attribute.

I was thinking of making ingredient as entity, but I just want to make it easy for a starter. I have read about transformable type but people don't seem to recommend using it to store arrays.

Seong Lee
  • 10,314
  • 25
  • 68
  • 106

4 Answers4

14

Warning: opinionated answer ahead.

You don't.

Storing things in an array does not make anything easier for you. On the contrary, it will make things much harder just an hour in. Imagine you want to show all Recipes that contain a selected Ingredient. That wouldn't be easy with your array hack, with a proper model it's only a couple line of code.

I would recommend to use a good old relationship with a "Join-entity".

basic Recipe data model

Yes, this is more complicated than hacking something together that barely works. But it's the correct way.

Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
  • 1
    Thanks for your suggestion. You're right. I should do it properly. – Seong Lee Mar 13 '15 at 10:05
  • Can you please tell me if I need to explicitly create attributes of recipe id and ingredient id in the joint-entity? or does xcode automatically handles it if a relationship is established? – Seong Lee Mar 13 '15 at 10:24
  • I see what you mean about sorting and displaying search results. However, doesnt he now need an array of custom ingrediet objects? My app needs a string array (and wouldnt benefit from a model like the above), and I still dont know how to store the array. any help? – Japes Sep 02 '15 at 05:56
  • it has a list of file paths associated with my main entity, with a max size of 10. So even if I create a new filepath entity, i still need to store an array of filepaths... – Japes Sep 02 '15 at 05:58
  • but where to store these data? – MartianMartian Aug 28 '17 at 13:01
2

What you was thinking of is exactly what you should do. Core Data is made to store values in array like structure. You should create entity Ingredients and connect your Food entity (or whatever you would like to call it) with relationship with Ingredients entity.

Wojtek
  • 1,006
  • 11
  • 30
2

there is a way. You can do each element manually e.g. You have your array:

let employee: NSMutableArray = []

employee.addObject(["name":"Bill","LastName":"Hanks"])
employee.addObject(["name":"Rolex","LastName":"Swarzer"])
employee.addObject(["name":"Clive","LastName":"Martin"])
employee.addObject(["name":"Jimi","LastName":"Hendrix"])

Assuming you have created your coreData with Entity "Employee" and Attributes "name" and "lastname" you do the following to add it in...

let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
let context = appDel.managedObjectContext

for item in employee {
    do {
        let newUser = NSEntityDescription.insertNewObjectForEntityForName("Employee", inManagedObjectContext: context)
        newUser.setValue(item["name"], forKey: "name")
        newUser.setValue(item["LastName"], forKey: "lastname")
        try context.save()
    } catch {
        //do nothing
    }

You can then fetch all elements using your fetch request or the NSFetched Results Controller

0

I have done in Swift 4,

Storing more Arrays into allDataArray (One Array). Fetching array objects from CoreData (AllData) and Displaying in TableView

import UIKit
import Foundation
import CoreData

class ViewController: UIViewController {

    var allTableDataArray : [AllData] = [AllData]()
    let allDataArray : NSMutableArray = []

    var listOfArray1 = ["#849578", "#849302"]
    var listOfArray2 = ["Vasuki Shiv", "Prathap Dusi"]

    override func viewDidLoad() {
        super.viewDidLoad()

        saveAllDataToCoredata()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        fetchAllDataFromCoredata()
    }


    func saveAllDataToCoredata() {

        deleteAllData(entity: "AllData")

            let context = PersistenceSerivce.context
            allDataArray.add(["requestNo" : listOfArray1[0], "vendorName" : listOfArray2[0]])
            allDataArray.add(["requestNo" : listOfArray1[1] , "vendorName" : listOfArray2[1]])

        for item in (allDataArray){
            do {
                let newUser = NSEntityDescription.insertNewObject(forEntityName: "AllData", into: context)

                guard let requestNoNew = item as? [String:Any] else {
                    return
                }
                let requestNoStr = requestNoNew["requestNo"]  as! String
                newUser.setValue(requestNoStr, forKey: "requestNo")

                guard let vendorNameNew = item as? [String:Any] else {
                    return
                }
                let vendorNameStr = vendorNameNew["vendorName"]  as! String
                newUser.setValue(vendorNameStr, forKey: "vendorName")
                PersistenceSerivce.saveContext()
                try context.save()
            } catch {
                //do nothing
            }
        }
    }

    func fetchAllDataFromCoredata(){

        let context = PersistenceSerivce.context
        let fetchRequest = NSFetchRequest<AllData>(entityName: "AllData")
        allTableDataArray.removeAll()
        do {
            allTableDataArray = try context.fetch(fetchRequest)
        } catch {
            print("Unable to fetch from Coredata", error)
        }
    }

    func deleteAllData(entity: String) {

        let managedContext = PersistenceSerivce.context
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
        fetchRequest.returnsObjectsAsFaults = false

        do
        {
            let results = try managedContext.fetch(fetchRequest)
            for managedObject in results
            {
                let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
                managedContext.delete(managedObjectData)
            }
        } catch let error as NSError {
            print("Delete all data in \(entity) error : \(error) \(error.userInfo)")
        }
    }
}

//MARK:- UITableView
extension ViewController : UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView,

                   heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 44
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return (allTableDataArray.count)
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: “TableViewCellID”) as? TableViewCell
        let allData = allTableDataArray[indexPath.row]
        cell?.requestNoLabel.text = allData.requestNo
        cell?.vendorNameLabel.text = allData.vendorName
        return cell!
    }
}
Sreekanth G
  • 658
  • 6
  • 13
  • @SaikumarReddy If you directly update a record you will get memory leaks So to avoid memory leaks It's better to make a SingleTon class and update from SingleTon class itself – Sreekanth G May 28 '20 at 20:03