Prefer using the typed factory methods provided by CoreImage.CIFilterBuiltins over the string-based CIFilter(name:) initializer and KVO setValue(_:forKey:). This provides compile-time type safety and avoids runtime crashes caused by misspelled keys or incorrect types.
Note: You must import CoreImage.CIFilterBuiltins to access these methods.
// WRONG
import CoreImage
guard
let kMeansFilter = CIFilter(name: "CIKMeans")
else { return nil }
kMeansFilter.setValue(ciImage, forKey: kCIInputImageKey)
kMeansFilter.setValue(CIVector(cgRect: ciImage.extent), forKey: "inputExtent")
kMeansFilter.setValue(1, forKey: "inputCount")
kMeansFilter.setValue(5, forKey: "inputPasses")
// RIGHT
import CoreImage.CIFilterBuiltins
let kMeansFilter = CIFilter.kMeans()
kMeansFilter.inputImage = ciImage
kMeansFilter.extent = CIVector(cgRect: ciImage.extent)
kMeansFilter.count = 1
kMeansFilter.passes = 5