sindhu ja
sindhu ja

Reputation: 53

Core Data - NSManagedObject returning nil

I wrote two seperate functions fetchRecords and displayRecords written in Appdelegate Class. fetchRecords function will fetch all records from the entity and it is working fine.displayRecords function accepts the return value from fetchRecords function and prints all the records one by one.

I have one view controller which calls these two functions to do the desired task. My problem is result.count in displayRecords shows the total number of records available in fetched records.While printing the records one by one the value is nil.

override func viewDidLoad() {
super.viewDidLoad()
    let fetchedRecords = AppDelegate().fetchRecords(fromEntity: "Dashboard")
    AppDelegate().displayRecords(fromFetchedRecords: fetchedRecords)   
}

And here is the fetchRecords and displayRecords functions written in AppDelegate Class

  func fetchRecords(fromEntity entity:String) -> Array<AnyObject> {
    var fetchedResult:Array<AnyObject> = []
    let fetchRequest = NSFetchRequest()
    let entityDescription = NSEntityDescription.entityForName(entity, inManagedObjectContext: self.managedObjectContext)!
    fetchRequest.entity = entityDescription
    do{
        fetchedResult = try self.managedObjectContext.executeFetchRequest(fetchRequest)              
    }catch{
        let fetchError = error as NSError?
        print(fetchError!)
    }
   return fetchedResult
}

func displayRecords(fromFetchedRecords result:Array<AnyObject>) {
    print("Total records:\(result.count)")
    if (result.count > 0) {
        for data in result {
        let dashboard = data as! NSManagedObject
        print("Value: \(dashboard.valueForKey("count"))")
        }
    }
}

Adding my data model here enter image description here

I will share the data insertion code also.

func saveDashBoardData(dictionary: Dictionary<String, String>) {
    print(NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask))

    //Create Manage Object
    let entityDescription: NSEntityDescription = NSEntityDescription.entityForName("Dashboard", inManagedObjectContext: self.managedObjectContext)!
    for data in dictionary {
        let dashboardObject = Dashboard(entity: entityDescription,insertIntoManagedObjectContext: self.managedObjectContext)
        dashboardObject.type  = data.0
        dashboardObject.count = data.1
        do {
            try self.managedObjectContext.save()
            print("Data saved succesfully")
        }
        catch {
            print(error)
        }
    }
}

Upvotes: 2

Views: 1066

Answers (3)

vadian
vadian

Reputation: 285290

The issue is that AppDelegate() creates always a new instance of the class which is not the same as the "hard-coded" delegate instance of the application.

You have to write

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let fetchedRecords = appDelegate.fetchRecords(fromEntity: "Dashboard")
appDelegate.displayRecords(fromFetchedRecords: fetchedRecords)

Since you have created a custom subclass of NSManagedObject use it as type rather than NSManagedObject or – worse – the unspecified AnyObject. It makes many things much easier:

func fetchRecords(fromEntity entity:String) -> [Dashboard] {
  let fetchRequest = NSFetchRequest()
  let entityDescription = NSEntityDescription.entityForName(entity, inManagedObjectContext: self.managedObjectContext)!
  fetchRequest.entity = entityDescription
  do {
     return try self.managedObjectContext.executeFetchRequest(fetchRequest) as! [Dashboard]              
  } catch let fetchError as NSError {
     print(fetchError!)
  }
  return [Dashboard]()
}

func displayRecords(fromFetchedRecords result:[Dashboard]) {
    print("Total records:\(result.count)")

    for dashboard in result { // the check for empty is not needed
       print("Value: \(dashboard.count)")
    }
}

Upvotes: 3

Dovakin Skyrim
Dovakin Skyrim

Reputation: 176

Create a NSManagedObject subclass of Dashboard from your coredata model.

func displayRecords(fromFetchedRecords result:Array<AnyObject>) {

    print("Total records:\(result.count)")
    if (result.count > 0) {
        for data in result {
        let dashboard = data as! Dashboard
        print("Value: \(dashboard.valueForKey("count"))")
        }
    }
}

Key change here is let dashboard = data as! Dashboard. Dashboard is managed object subclass which you need to create with core data model help.

Upvotes: 0

Balaji Ramakrishnan
Balaji Ramakrishnan

Reputation: 1959

Try this one..

let dashboard = Dashboard as! NSManagedObject

print("Value: \(dashboard.count)")

I think it might work. Because you have taken your ManagedObject as data. Better you take it as kind of Dashboard. So that you can access count by dashboardObj.count ..

Hope you created Core Data NSManagedSubclass for the Entity.

Hope it helps..

Upvotes: 0

Related Questions