How do you subclass CIFilter now? In Swift 3 I could do this as a simple example:
class CustomFilter: CIFilter {
var inputImage: CIImage?
var inputOrigin: CIVector?
var inputAnotherVar: String?
}
But in Swift 4 I get an NSException. If I remove "input" from each variable it works fine. I could just do that. But I feel like I'm missing something important and I can't seem to find anything explaining this behaviour.
This compiles fine in Swift4:
class CustomFilter: CIFilter {
var image: CIImage?
var origin: CIVector?
var anotherVar: String?
}
Here's the error in a Playground:
Based on the comments, here's some Swift 4 code (unchanged from Swift 3) that both builds and executes. I'm not seeing where your issue is, so if this doesn't help you out, comment on it and I'll delete it. (If it does help, I'll edit my answer to be more specific!)
The first
CIFilter
usesCIColorInvert
andCIHeightFieldFromMask
to create a "text mask" based on the text in aUILabel
. It alsooverrides
theoutputImage
property ofCIFilter
. The secondCIFilter
is actually a "wrapper" around aCIKernel
, using anCIImage
asinputImage
, the mask (from the first filter) asinputMask
and also overridesoutputImage
like the first does.Virtually all of this code was lifted from Core Image for Swift by Simon Gladman, nowadays available as an iBook for free. While the book was written in Swift 2, I find it to be a valuable resource for working with Core Image.
(Side note: The book combines all of this. I split out things as I was working on adapting this into an existing app as a watermark. I ended up going a different route!)
Mask.swift
Refraction.swift
Usage
Hope this helps!
I ran into this issue (same "error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION...") in Swift 4 while experimenting with Simon Gladman's "Core Image for Swift." I also tried running example code in an app instead of a playground. The solution for me was to add an
@objc dynamic
in front ofvar inputImage: CIImage?
In your code it would look like this:As I understand it, this is because Swift 4 by default minimizes inference so as to reduce binary code size. In contrast, Swift 3 implicitly infers Objc attributes. What this means in practice, is I have to add the
@objc dynamic
to certain variables that will take advantage of Objective-C's dynamic dispatch, such as when setting a CoreImage filter:filter.setValue(inputImage, forKey: kCIInputImageKey)
. Here are some resources that describe similar issues with Swift's static dispatch using Swift4 when dealing with Obj-C API's that rely on dynamic dispatch and how to deal with dispatch when you migrate from Swift 3 to 4.