CIRAWFilter is never not crashing

Is anyone using the new CIRAWFilter API successfully? This is the one introduced in iOS 15, not the OG one. I'm able to instantiate the class and get an output image, but as soon as I try to use the same instance a second time (in any way), I get a crash.

I'm storing the CIRAWFilter in an instance variable to tweak its parameters (such as exposure) later, but while the CIRAWFilter object is retained, it seems like it's an empty shell. It either crashes with EXC_BAD_ACCESS or responds that it was sent an unrecognized selector.

Makes it tough to adopt this new API!

Here's a reproducible code sample for the curious (make sure to add a RAW file called example.dng to the bundle):

import SwiftUI
import Photos
import CoreImage
import CoreImage.CIFilterBuiltins

final class FilterHolder: ObservableObject {
	var rawFilter: CIRAWFilter? = nil
}

struct ContentView: View {
	enum RawError: String, Error {
		case noURL, noFilter, noImage, noCGImage, noAsset, noFullSizeUrl, unhandled
	}
	@State var image: Image?
	@State var rawError: RawError? = nil
	@State var ev: Float = 0.0
	@StateObject var filterHolder = FilterHolder()

	var body: some View {
		VStack {
			if let image = image {
				VStack {
					image.resizable()
						.aspectRatio(contentMode: .fit)
						.frame(maxWidth: .infinity, maxHeight: .infinity)
					Slider(value: $ev, in: 0...3)
				}
			} else {
				if let error = rawError {
					Text("Error: \(error.localizedDescription)")
				} else {
					Text("Loading…")
				}
			}
		}.onChange(of: ev) { newValue in
			filterHolder.rawFilter?.exposure = newValue
			render()
		}.onAppear {
			loadLocalImage()
		}
	}

	func loadLocalImage() {
		do {
			guard let url = Bundle.main.url(forResource: "example", withExtension: "dng") else {
				throw RawError.noURL
			}

			guard let filter = CIRAWFilter(imageURL: url) else {
				throw RawError.noFilter
			}

			filter.neutralTemperature = 5600.0
			filterHolder.rawFilter = filter
			render()
		} catch {
			rawError = .unhandled
		}
	}

	func render() {
		do {
			guard let output = filterHolder.rawFilter?.outputImage else {
				throw RawError.noImage
			}

			let context = CIContext(options: nil)
			guard let cgImage = context.createCGImage(output, from: output.extent) else {
				throw RawError.noCGImage
			}

			image = Image(uiImage: UIImage(cgImage: cgImage))
		} catch {
			rawError = .unhandled
		}
	}
}

The image should load correctly once, but when the slider is adjusted, you'll see the crash.

Filed as FB9524345

Hmm, interesting. I wonder if the filter is not designed to be re-used. Can you please try with rawFilter.previewImage instead of outputImage?

Hmm, that was a good idea, but sadly it didn't help. I'm still seeing a crash in the .onChange(of: ev) block when setting the exposure. The Objective-C runtime crashes every time I try to access any of CIRAWFilter's variables or methods after the first use.

CIRAWFilter is never not crashing
 
 
Q