Search code examples
swiftcore-dataindexingfetchuitextfielddelegate

Use core data index to fetch a specific item from core data


My swift code below when loaded places 3 items in the core data entity named "UserName". When the user enters a number into textfield enterT I want the label labelName to display it. So when the user enters 1 the label should display jessica biel because Jesical Biel is the first name entered. Someone stated the suggestion below to solve this problem. I dont know exactly how to do this.I have added a gif below.

Convert the entered number to Int. If this succeeds pass the integer to joke and fetch the record matching the idx attribute.

https://github.com/redrock34/index-fetch

enter image description here

enter image description here

import UIKit import CoreData

  class ViewController: UIViewController,UITextFieldDelegate {
@IBOutlet var labelName : UILabel!
@IBOutlet var enterT : UITextField!

lazy var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

override func viewDidLoad() {
    super.viewDidLoad()

    openDatabse()
    fetchData()
    enterT.delegate = self


}

func textFieldDidEndEditing(_ textField: UITextField) {
    guard let index = Int(textField.text!) else {
        // display an alert about invalid text
        return
    }
    joke(at: index - 1)
}

func joke(at index : Int) {
    let fetchRequest = NSFetchRequest<Users>(entityName: "Users")
    fetchRequest.predicate = NSPredicate(format: "idx == %d", Int32(index))
    do {
        if let user = try context.fetch(fetchRequest).first {
            labelName.text = user.username
        }
    } catch {
        print("Could not fetch \(error) ")
    }
}
func openDatabse()
{
    let names = ["kim kardashian", "jessica biel", "Hailey Rienhart"]
    for i in 0..<names.count {
        let newUser = Users(context: context)
        newUser.username = names[i]
        newUser.idx = Int32(i + 1)
    }
    print("Storing Data..")
    do {
        try context.save()
    } catch {
        print("Storing data Failed", error)
    }
}
func fetchData()
{
    print("Fetching Data..")
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
    request.returnsObjectsAsFaults = false
    do {
        let result = try context.fetch(request)
        for data in result as! [NSManagedObject] {
            let userName = data.value(forKey: "username") as! String

            print("User Name is : "+userName)
        }
    } catch {
        print("Fetching data Failed")
    }
}}

Solution

  • Of course you have to assign values to the idx attribute and you have to assign the result of the fetch to the label.

    First replace

    let appDelegate = UIApplication.shared.delegate as! AppDelegate //Singlton instanc
    var context:NSManagedObjectContext!
    

    with

    lazy var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    

    Then replace both openDatabse and saveData with

    func openDatabse()
    {
        let names = ["kim kardashian", "jessica biel", "Hailey Rienhart"]
        for i in 0..<names.count {
            let newUser = Users(context: context)
            newUser.name = names[i]
            newUser.idx = Int32(i + 1)
        }
        print("Storing Data..")
        do {
            try context.save()
        } catch {
            print("Storing data Failed", error)
        }
    }
    

    Finally add a line in joke to display the value

    func joke(at index : Int) {
        let fetchRequest = NSFetchRequest<Users>(entityName: "Users")
        fetchRequest.predicate = NSPredicate(format: "idx == %d", Int32(index))
        do {
            if let user = try context.fetch(fetchRequest).first {
                labelName.text = user.username
            }
        } catch {
            print("Could not fetch \(error) ")
        }
    }
    

    It creates the records and assigns the proper indexes. Then entering a number in the text field should work.

    But – once again – on each launch of the app the 3 records are inserted again with the same names and indexes. Be aware of that!