"This class is not key value coding-compliant" using CoreImage
Asked Answered
B

1

14

I'm working on a simple MacOS command-line application in Swift. I created a custom CoreImage filter and having troubles to use it. The code compiles just fine but when it runs it exits with the following error:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key inputImage.'

Any help with this issue would be greatly appreciated. Tried searching for an answer on SO but since my application does not use Storyboards or Outlets (it's pure command-line) unfortunately I couldn't help myself.

My program breaks on this line:

filter.setValue(inputImage, forKey: kCIInputImageKey)

Here's the code I'm using:

class CustomFilter:CIFilter {
    var inputImage:CIImage?

    let kernelString = CIKernel(string:
        "kernel vec4 chromaKey( __sample s) { \n" +
            "  vec4 newPixel = s.rgba;" +
            "  newPixel[0] = 0.0;" +
            "  newPixel[2] = newPixel[2] / 2.0;" +
            "  return newPixel;\n" +
        "}"
    )

    override var outputImage:CIImage! {
        guard
            let inputImage = inputImage
        else {
            return nil
        }

        let extent = inputImage.extent

        let blur = kernelString?.apply(
            withExtent: extent,
            roiCallback: {
                (index, rect) in
                return rect
            },
            arguments: [inputImage])

        return blur!.cropping(to: extent)
    }
}

let filter = CustomFilter()

filter.setValue(inputImage, forKey: kCIInputImageKey) // it breaks here

guard
    let result = filter.outputImage
else {
    return nil
}

return result
Banc answered 4/10, 2017 at 13:24 Comment(1)
You are force-outputting a CIImage object with CIImage! but returning a possible nil, which doesn't seem right.Dowser
B
33

Key value coding-compliant properties must be marked as dynamic

dynamic var inputImage : CIImage?

and in Swift 4 even as @objc

@objc dynamic var inputImage : CIImage?
Bulletin answered 4/10, 2017 at 13:54 Comment(5)
That worked like a charm, thank you. Can you please explain why it had to be declared as @objc dynamic var? I'm confused because that looked like a standard in-class variable.Banc
Please read the section Requiring Dynamic Dispatch in Using Swift with Cocoa and Objective-C : Interacting with Objective-C APIsBulletin
added @objc dynamic but still got error. plz help........@objc dynamic var name : String.......... let resultPredicate = NSPredicate(format: "name contains[c] %@", s.lowercased()) let result = self.videoData.filtered(using: resultPredicate)Seth
@Seth Don't use NSPredicate, use native filter and range(of with option diacriticInsensitiveBulletin
@Bulletin can you provide some tutorial? Thanks youSeth

© 2022 - 2024 — McMap. All rights reserved.