Salman Ali
Salman Ali

Reputation: 255

Core Data Value returns Nil

Hi i have been working with core data to store and retrieve some values(String only) from the core data. Here is how i am storing the values.

The Function :

public func saveStringValue(forKey: String, value: String) -> Bool{
    var saved = false
    if self.entityName != nil && self.appDelegate != nil{
        let context = appDelegate?.persistentContainer.viewContext
        if context != nil{
            let entity = NSEntityDescription.entity(forEntityName: self.entityName!, in: context!)
            let entityHandle = NSManagedObject(entity: entity!, insertInto: context!)
            entityHandle.setValue(value, forKey: forKey)
            do{
                try context?.save()
                saved = true
            }catch let error as NSError{
                saved = false
                print("Error : \(error)")
            }
        }
    }

    return saved 
}

Here is how i call it

let historyManager = HistoryManager(entity: "SearchHistory")
        let titleInserted = historyManager.saveStringValue(forKey: "title", value: book.title!)
        if(titleInserted == true)
        {
            print("Title Inserted to Entity")
        }

        if let image = book.imageUrl{
            let imageInserted = historyManager.saveStringValue(forKey: "image", value: image)
            if imageInserted == true{
                print("Image Url Inserted to Entity")
            }
        }

I can see in the console printed that

  1. Title inserted into entity
  2. ImageInserted Into entity

Here is the code to retrieve the value from core data store

public func fetchAll() -> [Book]{
    var books = [Book]()
    let context = self.appDelegate?.persistentContainer.viewContext
    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: self.entityName!)
    //let fetchRequest: NSFetchRequest<SearchHistory> = SearchHistory.fetchRequest()

    do{
        let fetchedBooks = try context?.fetch(fetchRequest)

        for aBook in fetchedBooks!{
            if let title = aBook.value(forKey: "title"){
                let book = Book(title: title as! String)
                if let im = aBook.value(forKey: "image"){

                    book.imageUrl = im as! String
                    print("ImageUrl : \(im) : ")
                }
                else{
                    print("No Value for key : image")
                }
                books.append(book)
            }


        }
    }
    catch let error as NSError{
        print("Fetch Error: \(error.localizedDescription)")
    }
    print("Books : \(books.count)")
    return books
}

But when i run the code to retrieve the book imageUrl it returns nil and prints

  1. No value for key : image It retrieves the title but not the imageUrl. Can you help me through this problem or point me to the right direction. And please do post the reason why i was getting this problem and how to solve it. Thanks.

Upvotes: 0

Views: 2015

Answers (1)

Paulw11
Paulw11

Reputation: 114846

Your problem is that your saveStringValue creates a new NSManagedObject instance each time you call it.

The first time you call saveStringValue you will create a SearchHistory object that has a title but no image. The second time you call it you will create another SearchHistory object with an image value but no title.

In my opinion, your saveStringValue function is unnecessary. Assuming your code is based on a template that resulted from clicking "use Core Data" in Xcode, you will have a SearchHistory class available and you can use something like this:

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext

let newHistory = SearchHistory(context: context)

newHistory.title = book.title
newHistory.image = book.imageUrl

appDelegate.saveContext()

Upvotes: 1

Related Questions