Insert element at index 0, NSManagedObject - ios

I am having trouble inserting an element at the first index to CoreData
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Thing",
inManagedObjectContext:managedContext)
let thing = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext: managedContext)
thing.setValue(name, forKey: "name")
thing.setValue(category, forKey: "category")
do {
try managedContext.save()
} catch let error as NSError {
}
How do I insert thing at index 0? Is it possible or do I have to rewrite all the data? Thanks!

You cannot insert a new NSManagedObject at a particular index. The order things are held in the store is for CoreData and SQLite to manage. You should instead ensure that you fetch the objects in the order that you want. This is done by specifying a sort descriptor (NSSortDescriptor) for your fetch request. So if you want things ordered by name, you would use:
let nameSort = NSSortDescriptor(key:"name", ascending:true)
fetchRequest.sortDescriptors = [nameSort]
If you want some other sort order, if necessary add an attribute to your Entity to represent that sort order, and set the appropriate values for each object you create.

Related

How can I edit my data in Core Data Swift 5?

I'm developing an iOS contacts app. I don't know how to use Core Data but I learned a little bit and was able to create data and display it on a tableview. But now I need some help. I'm looking for code that queries a Contact name in Core Data to check if this contact already exists. If it does, I need to edit this data, if not I need to create this data. Can someone help me?
I'm using this simple code to create data:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Contact", in: context)
let newEventWithTickets = NSManagedObject(entity: entity!, insertInto: context)
var name = contact.name
var email = contact.email
newEventWithTickets.setValue(name, forKey: "name")
newEventWithTickets.setValue(email, forKey: "email")
do {
try context.save()
} catch {
print("Failed saving")
}
An approach that you can consider is using NSPredicate. Essentially, you create conditions (name & email) to check in your managedContext to find entities that much the specific query.
Here is a rough draft on how to approach it:
let fetchRequest = NSFetchRequest<>(entityName: )
fetchRequest.predicate = NSPredicate(format:)
do {
data = try coreDataStack.managedContext.fetch(fetchRequest)
} catch {
print ("Did not fetch")
}
Once you get the data, use a conditional to compare what was inputed and what your query sends back.

Core Data Merge policy

I've implemented core data in my application successfully. Everything was working fine but I got an issue. I'm using merge policy to update records.
I've two Entities name Issues and Members with relation one to many. One issue has many members.
Data comes from the server and saved in these two Entities:
Object A
Object B
Object C
This data comes first time and save in coredata. Data updates on server and when fetching second time , this data comes:
Object A
Object B
It should update and remove the Object C, but Object C still in coredata.
Please help me what i'm doing wrong here. Thanks in advance.
This is my code:
private class func getContext() -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}
class func saveIssues(with json: JSON)
{
let context = getContext()
let entity = NSEntityDescription.entity(forEntityName: "Issues", in: context)
let issue = NSManagedObject(entity: entity!, insertInto: context) as! Issues
issue.setValue(json["Id"].stringValue, forKey: "id")
issue.setValue(json["Name"].stringValue, forKey: "name")
issue.setValue(json["CreatedByName"].stringValue, forKey:"createdByName")
for issueMembers in json["Members"].arrayValue
{
let members = NSEntityDescription.insertNewObject(forEntityName: "Members", into: context) as! Members
members.setValue(issueMembers["FullName"].stringValue, forKey: "fullName")
members.setValue(issueMembers["PictureUrl"].stringValue, forKey: "picture_Url")
members.setValue(issueMembers["LoginId"]. stringValue, forKey: "loginId")
issue.addToIssueMembers(members)
}
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
do{
try context.save()
}catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
I investigated it a little bit and found that no one merge policy suites your needs: in case of uniqueness constraints, both NSRollbackMergePolicy and NSOverwriteMergePolicy save only old (existed on persistent store) set of objects in relationship, and both NSMergeByPropertyStoreTrumpMergePolicy and NSMergeByPropertyObjectTrumpMergePolicy save all objects in relationship the object had in two versions (on disk and in memory). So seems like you have to manage the relationship yourself...

only saving last item while saving in core data swift [duplicate]

This question already has answers here:
Core Data in Swift: Only saving last object in a for loop
(4 answers)
Closed 6 years ago.
With this function I want to add attributes in core-data entity but it saves only last item repeatedly.
what am I doing wrong?
func SetFeaturedValues(Array : NSArray){
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("FeaturedJob",
inManagedObjectContext:managedContext)
let FeaturedJob = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext: managedContext)
print("array is \(Array)")
for i in Array{
if let rowData :NSDictionary = i as? NSDictionary{
FeaturedJob.setValue(rowData["company"], forKey: "company")
FeaturedJob.setValue(rowData["city"], forKey: "city")
FeaturedJob.setValue(rowData["id"], forKey: "id")
FeaturedJob.setValue(rowData["user_logo"], forKey: "user_logo")
FeaturedJob.setValue(rowData["title"], forKey: "title")
do {
try managedContext.save()
self.Featured.append(FeaturedJob)
print("featured job is \(FeaturedJob)")
// people.append(person)
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
}
}
Ok, so this could still do with some tidying up but...
What's going wrong is that you are creating only one singleNSManagedObject instance called FeaturedJob. Every time you iterate through the array you append its value and save it. But its the same instance! That's why only one instance gets saved.
So put the line with let let FeaturedJob = ... inside the if block just before you start assigning values. That way you're going to get a new one each time.
PS: You are saving the context with every iteration. You probably only want to do that once at the end of the function.

What is the right way to save an array as data in core data?

As title, I have an array of multiple objects and I wish to store them in core data(I understand that we can't save array into core data so I break my code into json[0][i]["ID"].int format), perhaps you will be clearer after reading my code
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext
let newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject
socket.on("reply") {data, ack in
let json = JSON(data)
print("database replied")
print(json[0].count)
for var i=0; i<json[0].count; ++i{
newUser.setValue(json[0][i]["ID"].int, forKey: "patientID")
newUser.setValue(json[0][i]["Name"].string, forKey: "patientName")
newUser.setValue(json[0][i]["Mileage"].double, forKey: "patientMileAge")
do{
try context.save()
}catch{
print("Could not save data")
}
}
}
This is what my data would look like
Here comes the troubles, i only get [ID:4, Name:'hung', Mileage:'0.23'] as the result, the former 2 arrays have been replaced.
Why can't I save them as I intended?
let newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject
should be inside the loop, because otherwise you create one object and then repeatedly update it and save the change (so the old value is overwritten)
Move this line of code into your loop:
let newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject
This should work, write me if it didn't
because you're not adding 3 entries, you're only updating the values for one.
you need to move
let newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject
inside your for loop

Core data object not appending to array

I am having a small issue with appending my Core Data object to an array. Everything is being saved correctly in Core Data, but when I checked the array, it was empty. The code looks as follows:
func saveQA(question: String, answer: String) {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Card", inManagedObjectContext: managedContext)
let newQA = Card(entity: entity!, insertIntoManagedObjectContext: managedContext)
newQA.question = question
newQA.answer = answer
do {
try managedContext.save()
playerCards.append(newQA)
}
catch {
print("error")
}
}
What seemed to work for me was changing my array from type Card, to type String. Then appending both newQA.question and newQA.answer separately to playerCards. Although I am unsure this is a valid solution. As I am unsure the question and answer will stay linked to each other that way. Any help is great, thank you in advance.
you should add data to you NSMutableArray like this :
playerCards.addObject(newQA)

Resources