简体   繁体   中英

Core Data Retrieval Issue In Swift

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:

实际的XCode屏幕截图

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 eg #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)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM