Post

Replies

Boosts

Views

Activity

Reply to NSWindowController subclass in Swift
You need to add override init(window: NSWindow?) { super.init(window: window) } in your subclass. See https://docs.swift.org/swift-book/documentation/the-swift-programming-language/initialization/ which say: Rule 1 If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers. Rule 2 If your subclass provides an implementation of all of its superclass designated initializers — either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition — then it automatically inherits all of the superclass convenience initializers. The (unstated) corollary here is that if you only override some of the superclass's designated initializers, you inherit none of them. in your case, you'd overridden init(coder:) not init(window:), so the compiler didn't 'see' an init(window:) at all. I'm not smart enough to figure this out on my own, I asked an LLM and then asked it to show me the documentation, because you really can't trust those guys. ;)
Topic: Programming Languages SubTopic: Swift Tags:
Dec ’25
Reply to How to properly register a macOS System Extension in an Electron app?
I don't know if there's anything Electron-specific, but if your app has com.apple.developer.system-extension.install, you need a NSSystemExtensionUsageDescriptionKey or OSBundleUsageDescriptionKey (for DriverKit extensions). Your failure to launch may not be what you think it is. Your program may have some code which unconditionally registers your extension at launch time, and your lack of the required usage description causes the system to terminate your app very early in its life cycle. You may be able to see what is going on my monitoring the console log (filter on your app's bundle ID)
Dec ’25
Reply to is the output frame rate of a CMIOExtension rounded or capped?
Sorry about the delay, I didn't see your message on the day it was posted (that little bell icon doesn't do much). I figured out what I was doing wrong but hadn't got around to replying to my own post. I was using this initializer: @nonobjc public convenience init(formatDescription: CMFormatDescription, maxFrameDuration: CMTime, minFrameDuration: CMTime, validFrameDurations: [CMTime]?) In previous code, I'd created a format like this (pseudocode): CMIOExtensionStreamFormat(formatDescription: description, maxFrameDuration: 30 fps, minFrameDuration: 30 fps, validFrameDurations: nil) which seemed to work fine - my virtual camera had a single format with 30fps. When I made a generator with multiple formats, I tried to add another format with a different frame rate like this: CMIOExtensionStreamFormat(formatDescription: description, maxFrameDuration: 29.97 fps, minFrameDuration: 29.97 fps, validFrameDurations: nil) and ended up with an AVCaptureDevice which offered two formats, both with the min and max frame duration of 30fps. That was the wrong thing to do. I only need a new CMIOExtensionStreamFormat only for a different size of output stream (all my streams use the same pixel format). Each size gets one format with multiple frame rates - pseudocode: CMIOExtensionStreamFormat(formatDescription: description, maxFrameDuration: 29.97 fps, minFrameDuration: 60 fps, validFrameDurations: [29.97fps, 30fps, 59.94fps, 60fps]) That works. Apple's built-in webcam on my laptop can provide arbitrary frame rates between 1 and 30 fps , while most UVC cameras only support a limited, fixed set of frame rates. With that mystery solved, my remaining question is how best to provide an actual frame rate which is closest to the promised value? Currently I do. this by counting frames since the start of generation and comparing setting a timer to fire at the anticipated time of the next frame (startTime + frameCount*frameDuration), rather than using a repeating timer.
Topic: Media Technologies SubTopic: Video Tags:
2w