How to save Array to CoreData?

IosArraysSwiftCore DataMagicalrecord

Ios Problem Overview


I need to save my array to Core Data.

let array = [8, 17.7, 18, 21, 0, 0, 34]

The values inside that array, and the number of values are variable.

1. What do I declare inside my NSManagedObject class?

class PBOStatistics: NSManagedObject, Equatable {
    @NSManaged var date: NSDate
    @NSManaged var average: NSNumber
    @NSManaged var historicAverage: NSNumber
    @NSManaged var total: NSNumber
    @NSManaged var historicTotal: NSNumber
    @NSManaged var ordersCount: NSNumber
    @NSManaged var historicOrdersCount: NSNumber
    @NSManaged var values: [Double]  //is it ok?

    @NSManaged var location: PBOLocation

}

2. What do I declare inside my .xcdatamodel?

enter image description here

3. How do I save this in my Entity? (I use MagicalRecord)

let statistics = (PBOStatistics.MR_createInContext(context) as! PBOStatistics)
statistics.values = [8, 17.7, 18, 21, 0, 0, 34] //is it enough?

Ios Solutions


Solution 1 - Ios

Ok, I made some research and testing. Using Transformable type, solution is simple:

1. What do I declare inside my NSManagedObject class?

@NSManaged var values: [NSNumber]  //[Double] also works

2. What do I declare inside my .xcdatamodel?

Transformable data type.

3. How do I save this in my Entity?

statistics!.values = [23, 45, 567.8, 123, 0, 0] //just this

>“You can store an NSArray or an NSDictionary as a transformable attribute. This will use the NSCoding to serialize the array or dictionary to an NSData attribute (and appropriately deserialize it upon access)” - Source

Or If you want to declare it as Binary Data then read this simple article:

Solution 2 - Ios

Swift 3 As we don't have the implementation files anymore as of Swift 3, what we have to do is going to the xcdatamodeld file, select the entity and the desired attribute (in this example it is called values). Set it as transformable and its custom class to [Double]. Now use it as a normal array.

Setting custom class to array of Double

Solution 3 - Ios

Convert Array to NSData

let appDelegate =
    UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity =  NSEntityDescription.entityForName("Device",
                                                inManagedObjectContext:managedContext)
let device = NSManagedObject(entity: entity!,
                             insertIntoManagedObjectContext: managedContext)
let data = NSKeyedArchiver.archivedDataWithRootObject(Array)

device.setValue(data, forKey: "dataOfArray")
do {
    try managedContext.save()
    devices.append(device)
} catch let error as NSError  {
    print("Could not save \(error), \(error.userInfo)")
}

Select Binary Data

Convert NSData to Array

let appDelegate =
    UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Device")

do {
    let results =
        try managedContext.executeFetchRequest(fetchRequest)
    
    if results.count != 0 {
        
        for result in results {
            
                let data = result.valueForKey("dataOfArray") as! NSData
                let unarchiveObject = NSKeyedUnarchiver.unarchiveObjectWithData(data)
                let arrayObject = unarchiveObject as AnyObject! as! [[String: String]]
                Array = arrayObject
        }
        
    }
    
} catch let error as NSError {
    print("Could not fetch \(error), \(error.userInfo)")
}

For Example : https://github.com/kkvinokk/Event-Tracker

Solution 4 - Ios

If keeping it simple and store an array as a string

Try this:

// Array of Strings
let array: [String] = ["red", "green", "blue"]
let arrayAsString: String = array.description
let stringAsData = arrayAsString.data(using: String.Encoding.utf16)
let arrayBack: [String] = try! JSONDecoder().decode([String].self, from: stringAsData!)

For other data types respectively:

// Set of Doubles
let set: Set<Double> = [1, 2.0, 3]
let setAsString: String = set.description
let setStringAsData = setAsString.data(using: String.Encoding.utf16)
let setBack: Set<Double> = try! JSONDecoder().decode(Set<Double>.self, from: setStringAsData!)

Solution 5 - Ios

Make entity attribute type as "Binary Data"

NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:TheArray];
myEntity.arrayProperty = arrayData;
[self saveContext]; //Self if we are in the model class

Retrive original array as:

NSMutableArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:anEntity.arrayProperty];

That's all.

Solution 6 - Ios

Following code works for me to store array of JSON in CoreData

func saveLocation(model: [HomeModel],id: String){
        
    let newUser = NSEntityDescription.insertNewObject(forEntityName: "HomeLocationModel", into: context)

    do{
        var dictArray = [[String: Any]]()
        for i in 0..<model.count{
            let dict = model[i].dictionaryRepresentation()
            dictArray.append(dict)
        }
        let data = NSKeyedArchiver.archivedData(withRootObject: dictArray)
        newUser.setValue(data, forKey: "locations")
        newUser.setValue(id, forKey: "id")
        try context.save()
    }catch {
       print("failure")
    }

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBartłomiej SemańczykView Question on Stackoverflow
Solution 1 - IosBartłomiej SemańczykView Answer on Stackoverflow
Solution 2 - IosHola Soy Edu Feliz NavidadView Answer on Stackoverflow
Solution 3 - IosVinoth AnandanView Answer on Stackoverflow
Solution 4 - IosAlexey ChekanovView Answer on Stackoverflow
Solution 5 - IosAvijit NagareView Answer on Stackoverflow
Solution 6 - IosRahul GusainView Answer on Stackoverflow