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
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Pono
  • 11,298
  • 9
  • 53
  • 70
  • You are force-outputting a CIImage object with CIImage! but returning a possible nil, which doesn't seem right. – El Tomato Oct 04 '17 at 13:52

1 Answers1

32

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?
vadian
  • 274,689
  • 30
  • 353
  • 361
  • 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. – Pono Oct 04 '17 at 17:20
  • 1
    Please read the section `Requiring Dynamic Dispatch` in [Using Swift with Cocoa and Objective-C : Interacting with Objective-C APIs](https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-ID35) – vadian Oct 04 '17 at 17:27
  • 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) – kemdo Jul 16 '18 at 05:12
  • @kemdo Don't use `NSPredicate`, use native `filter` and `range(of` with option `diacriticInsensitive` – vadian Jul 16 '18 at 05:15
  • @vadian can you provide some tutorial? Thanks you – kemdo Jul 16 '18 at 05:51