user3781236
user3781236

Reputation: 728

Swift - casting a nil core data string as an optional value

I have a field stored on a core data object called "metadata" which is of type String (no optional, because Apple docs say not to mess with optionals in CD). Sometimes, the metadata field is nil. In checking whether this value is nil, I do the following check:

if object.metadata as String? != nil {
    ...
} 

However, my code continuously crashes on this line as an EXC_BAD_ACCESS. I have also tried:

if let metadata = object.metadata as String? {
    ...
}

Which doesn't work either. I cast objects successfully to optionals in other parts of my code, so I don't understand why this particular case isn't working. How do you check whether a core data property is a nil string?

Upvotes: 3

Views: 4150

Answers (1)

bjtitus
bjtitus

Reputation: 4270

It looks like what you really want is this:

if object.metadata != nil {
    ...
}

or this:

if let metadata = object.metadata as? String {
    // You can now freely access metadata as a non-optional
    ...
}

--EDIT--

My mistake, I didn't read the first part of your question thoroughly enough. It looks like the duplicate answer has a solution for this. Essentially, the generated managed object subclass is a bug and you should modify the properties to be either optional or implicitly unwrapped. You can check both of those using the first method for implicitly unwrapped and second for optionals.

There are several questions which discuss the issue of the generated subclasses not producing optional properties. I wouldn't be too concerned about editing the subclasses; there's nothing special about them except that Apple is making it easier to create them.

Check if property is set in Core Data?

Swift + CoreData: Cannot Automatically Set Optional Attribute On Generated NSManagedObject Subclass

--Edit2--

If you really don't want to touch the subclass you can access the property using valueForKey() and could add that as an extension if you wanted something a bit cleaner.

if let metadata = object.valueForKey("metadata") as String? {
    ...
}

In an extension:

extension ObjectClass {
    var realMetadata: String? {
        set {
            self.setValue(newValue, forKey: "metadata")
        }
        get {
            return self.valueForKey("metadata") as String?
        }
    }
}

Upvotes: 5

Related Questions