Reputation: 1209
I have an issue with retrieving core data (code shown below). I created a new XCode project and the datamodel with the three attributes username
, password
and testnumbers
. Using the code below I stored values in them, and outputted the result to the log (the bottom right is that output, from the line of code println(results)
that is commented out). So clearly it has stored everything correctly I assume.
Now I commented that section out and now want to retrieve the values stored under username
, password
and testnumbers
. Printing result.password
seems to be fine with the code, but in the code while trying to print result.testnumbers
and result.username
, it says "'AnyObject' does not have a member named 'testnumbers/username'". I'm not sure what's happening, since my previous output showed the correct storing of these.
I have tried redoing this simple project a few times, always creating the datamodel first and making sure everything is spelled correctly, etc. Same thing keeps happening.
Here is the code:
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context:NSManagedObjectContext = appDel.managedObjectContext!
var newUser = NSEntityDescription.insertNewObjectForEntityForName("Users",
inManagedObjectContext: context) as NSManagedObject
newUser.setValue("Mark", forKey: "username")
newUser.setValue("pass", forKey: "password")
newUser.setValue("12345", forKey: "testnumbers")
context.save(nil)
var request = NSFetchRequest(entityName: "Users")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
if results?.count > 0 {
for result: AnyObject in results! {
//println(results) // this printed everything fine
println(result.password)
println(result.testnumbers)
println(result.username)
}
}
}
}
Here is the output of what that first println(results)
gives me:
Optional([ (entity: Users; id: 0xd000000000040000 ; data: { password = pass; testnumbers = 12345; username = Mark; }), (entity: Users; id: 0xd000000000080000 ; data: { password = pass; testnumbers = 12345; username = Mark; }), (entity: Users; id: 0xd0000000000c0000 ; data: { password = pass; testnumbers = 12345; username = Mark; })])
Actual XCode screenshot:
Upvotes: 1
Views: 96
Reputation: 22939
Your problem is context.executeFetchRequest
returns an array of AnyObject?
. When you're looping through the objects are AnyObject?
, which as Xcode is saying, don't have the properties testnumber
, username
or password
.
To solve this and be able to access properties with dot notation you need to create subclasses for your enties:
1. Select your data model (.xcdatamodel file) and select at least one of your entities. Then go to 'Editor -> Create NSManagedObject Subclass... ' as shown in the picture.
Xcode will take you through creating the subclasses. (Just click next and select all the Entities you want to create subclasses for - probably all of them)
2. Now you'll have .m and .h files for your managed objects. In the .h file you should see properties for each Attribute and Relationship. You can use these properties to access the values stored in CoreData.
Note - 'Create ManagedObject Subclass; creates Objective-C Files, hence the .h and .m. Since you're using Swift you need to include the .h files in your bridging header e.g. #include "User.h"
. If you don't yet have a bridging header, Xcode should ask if you want to create one. Otherwise, have a look at this link: https://bohemianpolymorph.wordpress.com/2014/07/11/manually-adding-a-swift-bridging-header/
3. Now, when you use context.executeFetchRequest
and get your objects, you should cast them to whatever object you are expecting and then you can access their properties. Here's an example:
let results = context.executeFetchRequest(request, nil)
if let user = results.first? as? User { // User is an NSManagedObject Subclass
// Now you can access the properties, e.g:
println(user.username)
}
Upvotes: 1