2

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)
        }
    }
}
5
  • Can you show me your coredata model in your project @sindhu ja Commented Apr 29, 2016 at 10:13
  • I have shared the data model in the question. Please find it Commented Apr 29, 2016 at 10:18
  • I couldn't get what you trying to say @vadian Commented Apr 29, 2016 at 10:28
  • @sindhu ja : can you put a break point at let dashboard = data as! NSManagedObject and confirm if dashboard object is nil ?? I guess it wont be if it was nil it would have crashed at that point itself. That means your fetch request is fecthing dashboard object properly, but may be dashboard object has no value for property in count :) So what you can do is post your code for inserting dashboard objects into coredata Commented Apr 29, 2016 at 10:28
  • @SandeepBhandari The insertion is working fine and I can see the data in DB. Anyhow I will share the code. Commented Apr 29, 2016 at 10:43

3 Answers 3

3

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)")
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @vadian. Creating the instance for AppDelegate solves the problem.
Using tight coupling to the AppDelegate is bad and will cause you more hassles than it is worth. You are far better off following the design laid out recently in the Core Data Programming Guide rather than what is in the template.
0

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..

1 Comment

Yes I already created NSManagedSubclass for that entity. I tried your suggestion but it is also not working.
0

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.

1 Comment

Thanks @Dovakin. We used your suggestion and creating the instance for AppDelegate solved the issue.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.