UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Day 54 - Instafilter, part 4...Applying filters...Error: "Thread 1: Exception: "[<CITwirlDistortion 0x600002ccea00> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key inputIntensity."

Forums > 100 Days of Swift

Getting a successful build...but triggers an error when I try to change the filter after I try to move the slider...but it worked fine in the step where we just used SepiaTone...stopped working when the other filters were added to the UIAlert.

Thread 1: Exception: "[<CITwirlDistortion 0x600002ccea00> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key inputIntensity."

Solutions?

import CoreImage
import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
@IBOutlet var imageView: UIImageView!
@IBOutlet var intensity: UISlider!
var currentImage: UIImage!

var context: CIContext!
var currentFilter: CIFilter!

override func viewDidLoad() {
    super.viewDidLoad()
    title = "Instafilter"
    navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(importPicture))

    context = CIContext()
    currentFilter = CIFilter(name: "CISepiaTone")
}

@objc func importPicture() {
    let picker = UIImagePickerController()
    picker.allowsEditing = true
    picker.delegate = self
    present(picker, animated: true)
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    guard let image = info[.editedImage] as? UIImage else { return }
    dismiss(animated: true)
    currentImage = image

    let beginImage = CIImage(image: currentImage)
    currentFilter.setValue(beginImage, forKey: kCIInputImageKey)
    applyProcessing()
}

@IBAction func changeFilter(_ sender: UIButton) {
    let ac = UIAlertController(title: "Choose filter", message: nil, preferredStyle: .actionSheet)
    ac.addAction(UIAlertAction(title: "CIBumpDistortion", style: .default, handler: setFilter))
    ac.addAction(UIAlertAction(title: "CIGaussianBlur", style: .default, handler: setFilter))
    ac.addAction(UIAlertAction(title: "CIPixellate", style: .default, handler: setFilter))
    ac.addAction(UIAlertAction(title: "CISepiaTone", style: .default, handler: setFilter))
    ac.addAction(UIAlertAction(title: "CITwirlDistortion", style: .default, handler: setFilter))
    ac.addAction(UIAlertAction(title: "CIUnsharpMask", style: .default, handler: setFilter))
    ac.addAction(UIAlertAction(title: "CIVignette", style: .default, handler: setFilter))
    ac.addAction(UIAlertAction(title: "CANCEL", style: .cancel))

    if let popoverController = ac.popoverPresentationController {
        popoverController.sourceView = sender
        popoverController.sourceRect = sender.bounds
    }
    present(ac, animated: true)
}

func setFilter(action: UIAlertAction) {
    guard currentImage != nil else { return }
    guard let actionTitle = action.title else { return }

    currentFilter = CIFilter(name: actionTitle)
    let beginImage = CIImage(image: currentImage)
    currentFilter.setValue(beginImage, forKey: kCIInputImageKey)

    applyProcessing()
}

@IBAction func save(_ sender: Any) {
}

@IBAction func intensityChange(_ sender: Any) {
    applyProcessing()
}

func applyProcessing() {
    let inputKeys = currentFilter.inputKeys

    if inputKeys.contains(kCIInputIntensityKey) {
        currentFilter.setValue(intensity.value, forKey: kCIInputIntensityKey)
    }

    if inputKeys.contains(kCIInputRadiusKey) {
        currentFilter.setValue(intensity.value * 200, forKey: kCIInputRadiusKey)
    }

    if inputKeys.contains(kCIInputScaleKey) {
        currentFilter.setValue(intensity.value * 10, forKey: kCIInputScaleKey)
    }

    if inputKeys.contains(kCIInputCenterKey) {
        currentFilter.setValue(CIVector(x: currentImage.size.width / 2, y: currentImage.size.height / 2), forKey: kCIInputCenterKey)
    }

    guard let outPutImage = currentFilter.outputImage else { return }
    currentFilter.setValue(intensity.value, forKey: kCIInputIntensityKey)

    if let cgImage = context.createCGImage(outPutImage, from: outPutImage.extent) {
        let processedImage = UIImage(cgImage: cgImage)
        imageView.image = processedImage
    }
  }
}

4      

Solution found...remove the following lines from the changeFilter function:

ac.addAction(UIAlertAction(title: "CIBumpDistortion", style: .default, handler: setFilter))
ac.addAction(UIAlertAction(title: "CIGaussianBlur", style: .default, handler: setFilter))
ac.addAction(UIAlertAction(title: "CIPixellate", style: .default, handler: setFilter))
ac.addAction(UIAlertAction(title: "CITwirlDistortion", style: .default, handler: setFilter))

... these filters must have changed.

4      

...not sure if this is up to date...

Core Image Filter Reference

4      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.