Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store custom object with CoreData in Swift?

I have a class named Chord which subclassed UILabel :

import UIKit

class Chord: UILabel {

var numTextLine: Int?
var positionInTextLine: CGFloat?
var tempPosInLine: CGFloat?

init(chordName: String, dLine: DLine, xAxis: CGFloat, posInTextLine: CGFloat) {
    // posInLine: CGFloat
    let labelSize = chordName.sizeWithAttributes([NSFontAttributeName: UIFont.systemFontOfSize(14.0)])
    let labelPositionY = ((dLine.upLine.frame.height) - labelSize.height) / 2

    super.init(frame: CGRect(origin: CGPoint(x: xAxis, y: labelPositionY), size: labelSize))

    self.numTextLine = dLine.numTextLine
    self.positionInTextLine = posInTextLine

    self.tempPosInLine = self.positionInTextLine

    self.text = chordName
    self.font = self.font.fontWithSize(14)
    self.textAlignment = NSTextAlignment.Center
    self.userInteractionEnabled = true
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    //fatalError("init(coder:) has not been implemented")
}
}

And I would like to persistent store an object called Song using CoreData. The Song object has an attribute that is an array of Chord. So I subclassed NSManagedObject as the following :

import Foundation
import CoreData

class Song: NSManagedObject {
    @NSManaged var lyrics: NSString?
    @NSManaged var chords: NSData?
    @NSManaged var title: NSString?
    @NSManaged var artist: NSString?
}

And basically I'm stuck there. I have set the attribute's type to BinaryData in CoreData model view and tried to use NSKeyedArchiver.archivedDataWithRootObject(myObject) before saving the ManagedContext and NSKeyedArchiver.unarchiveObjectWithData(myObject) as? [Chord] after fetching the entity, but when I unarchive the NSData I get an UILabel object although I've set as? [Chord].

Anyone can get me on the right way to go?

like image 306
Louis. B Avatar asked Feb 08 '23 01:02

Louis. B


1 Answers

There are a couple of really important things here:

First, saving UI objects to Core Data, or any data file, is a terrible idea. It's technically possible to do what you're trying to do, but it's extremely bad design. You should be saving your data, not your UI objects. You should configure your UI based on your data, not save the actual UI objects. Although MVC is a strategy and not a cast-iron rule, mixing up your model and view to this extent is a really bad idea. What you should do is save all of the relevant data for a chord in your model (details like the name, etc) but not the actual UILabel used to display it.

Second, and purely in the interest of understanding Core Data but not as something you should do in this specific case-- if you want to save a custom object in Core Data, you'll want to make sure your object's class conforms to NSCoding. If you use the "transformable" type for the Core Data attribute, Core Data will use NSCoding methods to encode/decode your custom objects. UILabel conforms to NSCoding, so if this were a good idea for UILabel, which it isn't, you'd need to override the NSCoding method in your subclass.

like image 109
Tom Harrington Avatar answered Feb 10 '23 22:02

Tom Harrington