Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Custom Setter For CoreData NSManagedObject

How to implement custom setter for NSManagedObject in Swift. I need to do task before setting the NSMangedObject Property.

like image 612
Allan Macatingrao Avatar asked Sep 08 '14 03:09

Allan Macatingrao


People also ask

How to create NSManagedObject subclass in Xcode 12?

From the Xcode menu bar, choose Editor > Create NSManagedObject Subclass. Select your data model, then the appropriate entity, and choose where to save the files. Xcode places both a class and a properties file into your project.

Is Coredata thread safe?

Core Data is designed to work in a multithreaded environment. However, not every object under the Core Data framework is thread safe. To use Core Data in a multithreaded environment, ensure that: Managed object contexts are bound to the thread (queue) that they are associated with upon initialization.

Should I use Coredata?

The next time you need to store data, you should have a better idea of your options. Core Data is unnecessary for random pieces of unrelated data, but it's a perfect fit for a large, relational data set. The defaults system is ideal for small, random pieces of unrelated data, such as settings or the user's preferences.

How do I use Coredata?

Open Xcode and create a new iOS project based on the Single View App template. Name the app HitList and make sure Use Core Data is checked. Checking the Use Core Data box will cause Xcode to generate boilerplate code for what's known as an NSPersistentContainer in AppDelegate.


2 Answers

My recommendation would be to use KVC. Maybe not the most elegant solution, but conceptionally a logical application of KVC.

Observe a change of the attribute. Register for the change in init(entity:insertIntoManagedObjectContext:) or maybe better in awakeFromFetch and awakeFromInsert, and remove the observer in willTurnIntoFault.

init(entity: NSEntityDescription!, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    super.init(entity: entity, insertIntoManagedObjectContext: context)
    addObserver(self, forKeyPath: "attribute", options: NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Old, context: nil)
}


override func observeValueForKeyPath(keyPath: String!, ofObject object: AnyObject!, change: NSDictionary!, context: CMutableVoidPointer) {
    if (keyPath == "attribute") {
           // do what you need to do
    }

}

Updated for Swift 3:

init(entity: NSEntityDescription!, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
    super.init(entity: entity, insertIntoManagedObjectContext: context)
    addObserver(self, forKeyPath: "attribute", options: [.old, .new], context: nil)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "attribute" {
           // do what you need to do
    }
}
like image 168
Mundi Avatar answered Oct 04 '22 20:10

Mundi


There is even a simpler way how to do it without managing KVO subscription. It can be done simply by overriding didChangeValueForKey: like this:

 override func didChangeValueForKey(key: String) {
    super.didChangeValueForKey(key)

    if key == "propertyName" {
        // do something now when propertyName changed
    }
}
like image 45
Miroslav Kovac Avatar answered Oct 04 '22 21:10

Miroslav Kovac