How to save multiple entries to one nsmangedObject - ios

I am trying to save 2 different string entities to core data. Then display with a tableview my function below saves the data. Right now the code is being displayed on different tableview cells. Meaning entity a is being displayed on cell 1 and entity b is being displayed on cell 2. They are not being printed into the same cell.
var itemName2 : [NSManagedObject] = []
var itemName : [NSManagedObject] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemName.count
}
func enterData() {
let appDeldeaget = UIApplication.shared.delegate as! AppDelegate
let context = appDeldeaget.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Data", in: context)
let theTitle = NSManagedObject(entity: entity!, insertInto: context)
theTitle.setValue(hits.text, forKey: "hits")
let theTitle2 = NSManagedObject(entity: entity!, insertInto: context)
theTitle2.setValue(atBats.text, forKey: "atBATS")
do {
try context.save()
itemName.append(theTitle)
itemName.append(theTitle2)
} catch {
print("d")
}
self.theScores.reloadData()
hits.text = ""
hits.resignFirstResponder()
}

try this,
func enterData() {
let appDeldeaget = UIApplication.shared.delegate as! AppDelegate
let context = appDeldeaget.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Data", in: context)
let theTitle = NSManagedObject(entity: entity!, insertInto: context)
theTitle.setValue(hits.text, forKey: "hits")
//removed theTitle2 and set the second value in theTitle itself
theTitle.setValue(atBats.text, forKey: "atBATS")
do {
try context.save()
itemName.append(theTitle)
//add theTitle only
} catch {
print("d")
}
self.theScores.reloadData()
hits.text = ""
hits.resignFirstResponder()
}

Related

adding data to CoreData takes lot time

// code to add core data. have 2000 contacts to add. but adding 2000 data takes 45 secs.
func addData(contacts: [CNContact]) {
for data in contacts {
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: entityName, in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
newUser.setValue(data.identifier, forKey: "contactIdentifier")
newUser.setValue(data.familyName, forKey: "finalName")
newUser.setValue(data.givenName, forKey: "givenName")
newUser.setValue(data.phoneNumbers.first?.value.value(forKey: "stringValue") as? String ?? "", forKey: "phoneNumber")
do {
try context.save()
} catch {
UIUtility.showErrorAlert("", message: Constants.errorMessage)
}
}
}
First move this line to before the loop since you only need to do it once
let context = appDelegate.persistentContainer.viewContext
Then replace the next two lines with
let newUser = NSEntityDescription.insertNewObject(forEntityName entityName, into: context)
So the start of the function should look like this
let context = appDelegate.persistentContainer.viewContext
for data in contacts {
let newUser = NSEntityDescription.insertNewObject(forEntityName entityName, into: context)
//...
Creating context and entity once (a bit more efficient) and saving the context once (much more efficient) is certainly faster.
func addData(contacts: [CNContact]) {
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: entityName, in: context)!
for data in contacts {
let newUser = NSManagedObject(entity: entity, insertInto: context)
newUser.setValue(data.identifier, forKey: "contactIdentifier")
newUser.setValue(data.familyName, forKey: "finalName")
newUser.setValue(data.givenName, forKey: "givenName")
newUser.setValue(data.phoneNumbers.first?.value.value(forKey: "stringValue") as? String ?? "", forKey: "phoneNumber")
}
do {
try context.save()
} catch {
UIUtility.showErrorAlert("", message: Constants.errorMessage)
}
}

Bookmark Button with core data in a TableView

Question:- I am having problem while deleting a row from core data. Whenever I perform the delete function, The values in the row are changed to 0 but the row still exist in Core database. How can I completely remove the row in below written code?
I have a tableView showing some list, each cell has a button with grey bookmark image as default.
When I click on bookmarkBtn, the button image is changed to blue image and the data is stored by coreData. After clicking it again, bookmarkBtn again changes to grey image and the entry in core data is supposed to be deleted.
//Code:- **when bookmarkBtn is clicked.**
#IBAction func btnClicked(_ sender: UIButton)
{
let position: CGPoint = sender.convert(CGPoint.zero, to: self.tableView)
let indexPath = self.tableView.indexPathForRow(at: position)!
sender.tag = indexPath.row
let cell: TableViewCell = self.tableView.cellForRow(at: indexPath) as! TableViewCell
// print("Favorite button tapped")
if sender.isSelected != true
{
cell.bookmarkBtn.setImage(UIImage(named: "bookmark_blue"), for: UIControlState.normal);
sender.isSelected = true;
saveItem(itemToSave:sender.tag)
self.bookmarkArrState.replaceObject(at: (indexPath.row), with:1);
}
else
{
cell.bookmarkBtn.setImage(UIImage(named: "bookmark_grey" ), for: UIControlState.normal);
sender.isSelected = false;
removeData(itemToDelete: sender.tag)
self.bookmarkArrState.replaceObject(at: (indexPath.row), with:0)
}
}
//Code:- **Saving values in CoreData**
func saveItem(itemToSave: Int){
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
//**Note:** Here we are providing the entityName **`Entity`** that we have added in the model
let entity = NSEntityDescription.entity(forEntityName: "AddedBookmark", in: context)
let myItem = NSManagedObject(entity: entity!, insertInto: context)
myItem.setValue(itemToSave, forKey: "indexNo")
do {
try context.save()
}
catch{
print("There was an error in saving data")
}
}
//**Code:- Deleting Data when bookmarkBtn is clicked again**
func removeData(itemToDelete: Int)
{
let mngdCntxt = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
//**Note:** Here we are providing the entityName **`Entity`** that we have added in the model
let entity = NSEntityDescription.entity(forEntityName: "AddedBookmark", in: mngdCntxt)
let myItem = NSManagedObject(entity: entity!, insertInto: mngdCntxt)
if let dataAppDelegatde = UIApplication.shared.delegate as? AppDelegate {
let mngdCntxt = dataAppDelegatde.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "AddedBookmark")
let predicate = NSPredicate(format: "indexNo = %i", Int(itemToDelete))
print("item selected :-\(itemToDelete)")
fetchRequest.predicate = predicate
do{
var result = try mngdCntxt.fetch(fetchRequest)
print(result.count)
print(fetchRequest)
if result.count > 0{
for object in result
{
print(object)
mngdCntxt.performAndWait {
mngdCntxt.delete(result[0] as! NSManagedObject)
mngdCntxt.refreshAllObjects()
}
}
}
do {
try mngdCntxt.save()
}
catch{
print("There was an error in saving data")
}
}
catch{
}
}
}

swift - NSPredicate and Context Save is not working well

I have a function that checking core data. if doesn't exist it should write to in it(but its not working in that way) SoundItems is an array that contains favorited objects and mainArray is the array that contains real objects;
#IBAction func Favori(_ sender: Any) {
// save core data
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext
let newSound = NSEntityDescription.entity(forEntityName: "Sounds", in: context)
let sound = NSManagedObject(entity: newSound!, insertInto: context)
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Sounds")
let predicate = NSPredicate(format: "soundName = %#", soundArray[soundIndex].deletingPathExtension().lastPathComponent)
fetchRequest.predicate = predicate
do {
let fetchResults = try context.fetch(fetchRequest) as? [Sounds]
if fetchResults!.count > 0 {
print("already favd")
}
else {
sound.setValue(soundArray[soundIndex].deletingPathExtension().lastPathComponent, forKey: "soundName")
try context.save()
soundItems.append(sound)
print(sound)
}
}
catch {
print(error)
}
}
and here is the code that listing the core data;
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")! as UITableViewCell
let sound = soundItems[indexPath.row]
cell.textLabel?.text = sound.value(forKey: "soundName") as? String
return cell
}
I tried to run the code in debug mode and it works fine when there is no duplicated core data and adds into the tableView list. But here is the situation; when core data exist(fetchResults!.count > 0) still adding in the tableview as nil label.text but always adds the item of mainArray[0]
If you want to check if the sound is in the favorites and if not add a new sound you have to change the order of the steps
#IBAction func Favori(_ sender: Any) {
// save core data
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext
let fetchRequest : NSFetchRequest<Sounds> = Sounds.fetchRequest()
let favName = soundArray[soundIndex].deletingPathExtension().lastPathComponent
let predicate = NSPredicate(format: "soundName = %#", favName)
fetchRequest.predicate = predicate
do {
let fetchResults = try context.fetch(fetchRequest)
if fetchResults.isEmpty {
let newSound = NSEntityDescription.insertNewObject(forEntityName: "Sounds", into:context) as! Sounds
newSound.soundName = favName
try context.save()
soundItems.append(newSound)
print(newSound)
}
else {
print("already favd")
}
}
catch {
print(error)
}
}
It's recommended to name entities in singular form (Sound).
#vadian had the point. Why did you insert a new sound before fetching the data?
let newSound = NSEntityDescription.entity(forEntityName: "Sounds", in: context)
let sound = NSManagedObject(entity: newSound!, insertInto: context)

How to save data to model coredata

I want to save my data to core data when a button is clicked here is my action button code now let app = UIApplication.sharedApplication().delegate as! AppDelegate
let context = app.managedObjectContext
let entity = NSEntityDescription.entityForName("Cart", inManagedObjectContext: context)
let cart = Cart(entity: entity!, insertIntoManagedObjectContext: context) but the only problem now is that i dont how to save here is my code to parse json
Alamofire.request(.GET, url!, headers: headers).responseJSON { (response) in
let result = response.result
if response.result.isSuccess{
let jsonObj = JSON(result.value!)
if let x = jsonObj["Items"].array {
x.forEach
{
if let uw = ($0["name"]).string{
print(uw)
let qw = ($0["image"]).string
if let rw = ($0["price"]).int{
if let hu = ($0["id"]).int{
print(hu)
let foo = Rest(name: uw, imageUrl: qw!, price: "₦\(rw)")
self.rest.append(foo)
}
}
}
}
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
actInd.stopAnimating()
}
}
}
So i have an array called rest which is where i want get data for the tableview. I want to save information of each cell tapped into coredata here is a screenshot of the app
So when the sure button is tapped it saves the item to coredata
here is my code incase you neecode
Try this, adapted to your code.
In the portion that you have (...let app=...) replace it by this:
let app2 = UIApplication.sharedApplication().delegate as! UIApplicationDelegate
if let context2 = app2.managedObjectContext {
let cart2 = NSEntityDescription.insertNewObjectForEntityForName("Cart", inManagedObjectContext: context2) as! Cart
cart2.name = self.res.name
cart2.price = self.res.price
cart2.url = self.res.imageUrl
cart2.id = ""
// Perform a save operation
do {
try context2?.save()
} catch {
let saveError = error as NSError
print(saveError)
}
}
Let me know if this works.
Cheers
Just an example here when you want to save your data in coredata. You have to create entity/model and all the setup for core data elements. For details please study https://www.raywenderlich.com/115695/getting-started-with-core-data-tutorial
func saveName(name: String) {
//1
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
//2
let entity = NSEntityDescription.entityForName("Person",
inManagedObjectContext:managedContext)
let person = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext: managedContext)
//3
person.setValue(name, forKey: "name")
//4
do {
try managedContext.save()
//5
people.append(person)
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}

TableView/CoreData Subtitles and Title

I am making a list app and have a Coredata model with two attributes in it (One for item and one for details)
I can save and input data and it will be displayed correctly but when i close and reopen the app, everything has its own cell.
Any help guys?
Code For CellAtIndex
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell
let item = listItems[indexPath.row]
let detailed = detailedItems[indexPath.row]
cell.textLabel?.text = item.valueForKey("item") as? String
cell.detailTextLabel?.text = detailed.valueForKey("detail") as? String
return cell
}
Code For ViewWillAppear
verride func viewWillAppear(animated: Bool) {
//Load First Item
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchrequest = NSFetchRequest(entityName: "ListEnt")
do{
let results = try managedContext.executeFetchRequest(fetchrequest)
listItems = results as! [NSManagedObject]
detailedItems = results as! [NSManagedObject]
}catch{
print("Error")
}
}
Here is the code for saving, I have a dialog box appear, with to text field, and each text field has its own save function
//Saving Items//
func saveItem(itmToSave: String){
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("ListEnt", inManagedObjectContext: managedContext)
let item = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
item.setValue(itmToSave, forKey: "item")
do{
try managedContext.save()
listItems.append(item)
}catch{
print("Saving Main Item")
}
}
//Saving Details
func saveItem2(itmToSave2: String){
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("ListEnt", inManagedObjectContext: managedContext)
let item2 = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
item2.setValue(itmToSave2, forKey: "detail")
do{
try managedContext.save()
detailedItems.append(item2)
}catch{
print("Saving deatil Item")
}
}
Pictures of the problem
How it looks when you input data (Correct way)
How it looks when you close and reopen the app
Cheers Guys

Resources