Right-click on your project's folder in the project navigator and then New File… In the new window, type “data” in the top right corner, select Data Model, and press Next. Give it a name, and save it. Now, let's add all the necessary code to connect Core Data with our project.
There are two steps to storing an array of a custom struct or class in Core Data. The first step is to create a Core Data entity for your custom struct or class. The second step is to add a to-many relationship in the Core Data entity where you want to store the array.
Open Xcode and create a new iOS project based on the Single View App template. Name the app HitList and make sure Use Core Data is checked. Checking the Use Core Data box will cause Xcode to generate boilerplate code for what's known as an NSPersistentContainer in AppDelegate.
The next time you need to store data, you should have a better idea of your options. Core Data is unnecessary for random pieces of unrelated data, but it's a perfect fit for a large, relational data set. The defaults system is ideal for small, random pieces of unrelated data, such as settings or the user's preferences.
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:
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.
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)")
}
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
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!)
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.
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")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With