Save data for tableview coredata in swift - ios

I have passed two parameters from another tableview in order to save my notes "my Text" in different array. I just want to save myText for different row for the tableview but now i can just save and see the common myText.
var allnote = [NSManagedObject]()
var csname:Int = 1
var cspath:Int = 1
func saveNote(myText:String){
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let managedObjectContext = appDelegate.managedObjectContext!
let entity = NSEntityDescription.entityForName("Logitem", inManagedObjectContext: managedObjectContext)
let notes = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedObjectContext)
notes.setValue(myText, forKey: "itemText")
allnote.append(notes)
var error: NSError?
if managedObjectContext.save(&error) {
println("Couldn't save\(error?.userInfo)")
}
fetchnote()
}

Related

Value of type 'AppDelegate' has no member 'managedObjectContext'

func saveName(name: String){
//1
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let person = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
//3
person.setValue(name, forKey: "name")
//4
var error: NSError?
if !managedContext.save(&error) {
print("Could not save \(error!), \(String(describing: error?.userInfo))");
}
//5
people.append(person)
}
I can't get this program working correctly. I was trying save to CoreData.
In Swift 3, you access the context object like this:-
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
As the managed object context is used frequently add a lazy instantiated property in AppDelegate
lazy var managedObjectContext : NSManagedObjectContext = {
return self.persistentContainer.viewContext
}()
Both entity and managedObjectContext are supposed to be non-optional.
Change your second line in your code to access the managed object context
let managedContext = appDelegate.persistantContainer.Viewcontext

Swift multiple values being saved to coredata

I'm making a game that has a few constants that are in it:
struct moneyConstants {
static var tapValue = NSInteger()
static var tapMultiplier = NSInteger()
static var moneyPerSecond = NSInteger()
static var money = NSInteger()
}
I'm using CoreData to save the values after when the application closes. I want to know if you are able to save multiple values at once. Lets say my code to save something is:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Constants", inManagedObjectContext:managedContext)
let moneyS = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
moneyS.setValue(moneyConstants.money, forKey: "moneySave")
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
If I wanted to save a second value like:
let moneyPerSecondS = NSManagedObject(entity:entity!, insertIntoManagedObjectContext:managedContext)
moneyPerSecondS.setValue(moneyConstants.moneyPerSecond, forKey: "money")
Can I place those lines before the do { section? Or do I have to put it after the do { section and then write another do { section?
Of course you can (if the attributes are declared in the model):
let moneyS = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
moneyS.setValue(moneyConstants.money, forKey: "moneySave")
moneyS.setValue(moneyConstants.moneyPerSecond, forKey: "money")
Everything which does not throw is not required to be placed in a do scope.

Why can't I set a variable on my custom class?

I'm creating my first iOS app in Swift, and I'm stuck on a basic thing. I want to create a custom class and set a variable. I keep seeing the error "Value of type [Item] has no member [name].
This is my custom class:
import UIKit
import Foundation
import CoreData
class Item:NSManagedObject {
var name:String?
convenience init(name: String?, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
let entity = NSEntityDescription.entityForName("ItemEntity", inManagedObjectContext: context)!
self.init(entity: entity, insertIntoManagedObjectContext: context)
}
}
And this is my code that tries to use it:
func editItem(id:Int, category:String, brand:String, name:String, colour:String, purchasePrice:String, purchaseDate:String, expiryDate:String) -> Int {
// vars
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("ItemEntity", inManagedObjectContext: managedContext)
let item = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
var listItem = [Item]()
let fetchRequest = NSFetchRequest(entityName: "ItemEntity")
// fetch the item from the core data with the same ID
do{
let predicate = NSPredicate(format: "id == %#", String(id))
fetchRequest.predicate = predicate
fetchRequest.fetchLimit = 1
let results = try managedContext.executeFetchRequest(fetchRequest)
listItem = results as! [Item]
}
catch {
let fetchError = error as NSError
print (fetchError)
}
// edit the item
listItem.name = "text" // !! THIS IS THE LINE WHICH DISPLAYS THE ERROR
// save the item
do {
try managedContext.save()
}
catch {
let saveError = error as NSError
print (saveError)
}
}
Really appreciate your help, this one seems so basic but a lot of googling hasn't helped me figure it out.
listItem is an array of Item, so if you want to change the name of one thing in this list you should specify the index you wanna change, like
listItem[0].name = "text"
Put spaces around the colon. Syntax if I'm not mistaken.
I think the problem code is here:
let item = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext) as! Item
By default, the item type is NSManagedObject, so listItem have no member [name]. You need to cast down it to Item Object.

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

Only last item in JSON is saved in Core Data [duplicate]

I'm trying to save multiple objects in Core Data to the IPodSongs entity in a for loop, namely the title of the song currently in the for song in result{} loop. But my code only saves the very last song in the loop, and just keeps overwriting the same object. Instead of overwriting the same object, I need to create a new object each time. What am I doing wrong?
func fetchiPodSongsOnSignup() {
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as! NSManagedObject
var request = NSFetchRequest(entityName: "IPodSongs")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
let query = MPMediaQuery.songsQuery()
let result = query.collections as! [MPMediaItemCollection]
for song in result {
for song in song.items as! [MPMediaItem] {
newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")
println(newSong)
context.save(nil)
}
}
You dont need to create a request to save new objects to Core Data. What you did wrong was create a single managed object, inserted it and then changeded it through the loop instead of creating a new object for each song.
This should work:
func fetchiPodSongsOnSignup() {
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
let query = MPMediaQuery.songsQuery()
let result = query.collections as! [MPMediaItemCollection]
for song in result {
for song in song.items as! [MPMediaItem] {
var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as NSManagedObject
newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")
println(newSong)
}
}
if context.save(&errorPointer == false {
printlin("Error received while saving")
}
}
Also put if context.save(&errorPointer == false {printlin("Error received while saving")} at the very end.
Try this , this will work ....
Insert in for loop and save in outside loop ...
func fetchiPodSongsOnSignup() {
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
let query = MPMediaQuery.songsQuery()
let result = query.collections as! [MPMediaItemCollection]
for song in result {
for song in song.items as! [MPMediaItem] {
var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as NSManagedObject
newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")
context.insert(newSong)
}
}
context.save(nil)
}
You are using the same inserted object in all iterations :
for song in song.items as! [MPMediaItem] {
newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")
You are indeed changing the song's object value but you use the same instance which in turn is the same entity in the core db.
You need to use a new instance for every new song:
var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as! NSManagedObject
newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")
This will work for you most probably! Try it!
for song in result {
for song in song.items as! [MPMediaItem] {
var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as! NSManagedObject
newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")
println(newSong)
context.save(nil)
}
}

Resources