如何保存关系数据(核心数据)

时间:2016-07-12 20:49:41

标签: ios swift core-data

我的应用程序中有这个数据结构。如您所见,我认为每个汽车品牌都由一个经销商销售,而经销商可能会销售多个品牌。

我从网络服务中检索CarBrand数据。由于我批量获取数据,如何保存数据,以便将carbrand数据与Delear记录相关联(从而保持我建立的关系)

这是我的尝试:

        let moc = DataController().managedObjectContext

        let carbrandEntity = NSEntityDescription.insertNewObjectForEntityForName("carbrandEntity", inManagedObjectContext: moc) as! CarBrand

        let dealerEntity = NSEntityDescription.insertNewObjectForEntityForName("DealerEntity", inManagedObjectContext: moc) as! Dealer

        for carbrand in self.carbrandArray {
            // add our data
            carbrandEntity.setValue(carbrand[0], forKey: "brandname")
            carbrandEntity.setValue(carbrand[1], forKey: "makeyear")

            do {
                try moc.save()
            } catch {
                fatalError("Failure to save context: \(error)")
            }

        }

        dealerEntity.setValue("Steven&Sons", forKey: "name")
        // How do I save dealer entity so that it is associated with the carbrand data that I just added.

更新

这是我的尝试,但是当我拿到特定的经销商时,我得到经销商信息,但CarBrand(NSSet)总是空的。

        let moc = DataController().managedObjectContext

        let carbrandEntity = NSEntityDescription.insertNewObjectForEntityForName("carbrandEntity", inManagedObjectContext: moc) as! CarBrand

        let dealerEntity = NSEntityDescription.insertNewObjectForEntityForName("DealerEntity", inManagedObjectContext: moc) as! Dealer

        dealerEntity.setValue("Steven&Sons", forKey: "name")

        for carbrand in self.carbrandArray {
            // add our data
            carbrandEntity.setValue(carbrand[0], forKey: "brandname")
            carbrandEntity.setValue(carbrand[1], forKey: "makeyear")


        }

        do {
                try moc.save()
        } catch {
                fatalError("Failure to save context: \(error)")
        }

更新

我还没有收到任何carband数据。这是一个更新的代码

        let dealerEntity = NSEntityDescription.insertNewObjectForEntityForName("DealerEntity", inManagedObjectContext: moc) as! Dealer

        dealerEntity.setValue("Steven&Sons", forKey: "name")

        for c in self.carbrandArray {
            dealerEntity.carbrand?.setValue(c[0], forKey: "brandname")
            dealerEntity.carbrand?.setValue(c[1], forKey: "makeyear")

        }

如果我在提取时犯了任何错误,请查看我的FETCH代码

        let moc = DataController().managedObjectContext
        let dealerEntity = NSFetchRequest(entityName: "DealerEntity")

        do {
            let dealers = try moc.executeFetchRequest(dealerEntity) as! [Dealer]
            for d in dealers {
               print(d.carbrand!.count) // Returns 0
            }

        } catch {
           fatalError("Failed to fetch saved data: \(error)")
    }

1 个答案:

答案 0 :(得分:1)

所以我简化了一个示例供您查看。我在这里上传了一个项目文件,对我来说很有效。

project file

  

我并不是说这是一个完美的解决方案,也不是我声称这些是最佳做法。   我只是向您展示这个概念以及我如何处理这个问题。

这是我的数据模型的样子。

enter image description here enter image description here

这是完成任务的代码。请注意,我们正在封装将对象存储在Managed Object类本身中所必需的逻辑。这不是一项要求,但它是我用来保持代码清洁的一种方法。

发表

public final class Post: NSManagedObject {

    @NSManaged var title: String
    @NSManaged var body: String
    @NSManaged var date: NSDate?
    @NSManaged var comments: Set<Comment>?

    // Insert code here to add functionality to your managed object subclass
    public static func insertIntoContext(moc: NSManagedObjectContext, json: AnyObject) {
        print("\n==============\n Post: \n\(json) \n==============\n")

       let post = NSEntityDescription.insertNewObjectForEntityForName("Post", inManagedObjectContext: moc) as! Post

        guard let 
            title = json["title"] as? String,
            body = json["body"] as? String 
            else { assertionFailure("post body failed"); return }

        post.title = title 
        post.body = body
        post.date = NSDate()

        if let jsonComments = json["comments"] as? [AnyObject] {

            // pass comments data into our comments class to get inserted into
            // our context
            let comments = Comment.returnSet(moc, jsonArray: jsonComments)
            post.comments = comments

        } 

        do {
            try moc.save()
        } catch let error {
            print("failed: \n\(error)\n\n<- - - - ->")
        }
    }
}

<强>注释

public final class Comment: NSManagedObject {

    @NSManaged var text: String
    @NSManaged var name: String

    public static func returnSet(moc: NSManagedObjectContext, jsonArray: [AnyObject]) -> Set<Comment> {
        var comments = Set<Comment>()

        for answer in jsonArray {
            // this guard statement will continue to the next object if our insert fails
            guard let c = Comment.insertIntoContext(moc, json: answer) else { continue }
            comments.insert(c)
        }

        return comments
    }

    public static func insertIntoContext(moc: NSManagedObjectContext, json: AnyObject) -> Comment? {
        //print("\ncomment : \n \(json)\n")
        guard let
            jsonText = json["text"] as? String,
            jsonName = json["name"] as? String
            else { assertionFailure("");return nil }

        let comment = NSEntityDescription.insertNewObjectForEntityForName("Comment", inManagedObjectContext: moc) as! Comment

        comment.text = jsonText
        comment.name = jsonName

        return comment
    }
}

<强>的ViewController

class ViewController: UIViewController {

    var moc: NSManagedObjectContext!

    override func viewDidLoad() {
        super.viewDidLoad()

        // you'd get your data from a webserver ideally
        let postObj : [String: AnyObject] = [
            "title" : "some title",
            "body" : "this is some body text",
            "comments" : [
                [
                    "text":"some comment",
                    "name":"dan beaulieu"
                ],
                [
                    "text":"another comment comment",
                    "name":"user30646"
                ],
                [
                    "text":"a much wiser comment",
                    "name":"Rob"
                ]
            ]
        ]

        // then you pass in your object and your context
        Post.insertIntoContext(moc, json: postObj)

        let posts = NSFetchRequest(entityName: "Post")

        do {
            let posts = try moc.executeFetchRequest(posts) as! [Post]
            for p in posts {
                print("------- Comments ------")
                print(p.comments) // Returns 0
            } 
        } catch {
            fatalError("Failed to fetch saved data: \(error)")
        }

    }
}

<强>的AppDelegate

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    guard let vc = window?.rootViewController as? ViewController
        else { fatalError("Wrong View Controller Type") }
    vc.moc = managedObjectContext

    return true
}