Post

Replies

Boosts

Views

Activity

Crash when assigning NSImage to `@objc dynamic var` property
Xcode downloaded a crash report for my app which I don't quite understand. It seems the following line caused the crash: myEntity.image = newImage where myEntity is of type MyEntity: class MyEntity: NSObject, Identifiable { @objc dynamic var image: NSImage! ... } The code is called on the main thread. According to the crash report, thread 0 makes that assignment, and at the same time thread 16 is calling [NSImageView asynchronousPreparation:prepareResultUsingParameters:]. What could cause such a crash? Could I be doing something wrong or is this a bug in macOS? crash.crash
11
0
208
Aug ’25
NSTableView.reloadData(forRowIndexes:columnIndexes:) causes wrong subview layout when usesAutomaticRowHeights = true
I have a table view where each row has two labels, one left-aligned and one right-aligned. I would like to reload a single row, but doing so causes the right-aligned label to hug the left-aligned label. Before the reload: After the reload: Reloading the whole table view instead, or disabling automatic row height, solves the issue. Can a single row be reloaded without resorting to these two workarounds? I created FB13534100 1.5 years ago but got no response. class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { override func loadView() { let tableView = NSTableView() tableView.translatesAutoresizingMaskIntoConstraints = false tableView.dataSource = self tableView.delegate = self tableView.usesAutomaticRowHeights = true let column = NSTableColumn() column.width = 400 tableView.addTableColumn(column) let scrollView = NSScrollView(frame: CGRect(x: 0, y: 0, width: 500, height: 500)) scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.documentView = tableView view = scrollView Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { _ in print("reload") tableView.reloadData(forRowIndexes: IndexSet(integer: 2), columnIndexes: IndexSet(integer: 0)) // tableView.reloadData() } } func numberOfRows(in tableView: NSTableView) -> Int { return 5 } func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { let cell = NSTableCellView() let textField1 = NSTextField(labelWithString: "hello") textField1.translatesAutoresizingMaskIntoConstraints = false let textField2 = NSTextField(wrappingLabelWithString: "world") textField2.translatesAutoresizingMaskIntoConstraints = false textField2.alignment = .right let stack = NSStackView(views: [ textField1, textField2 ]) stack.translatesAutoresizingMaskIntoConstraints = false stack.distribution = .fill cell.addSubview(stack) NSLayoutConstraint.activate([stack.topAnchor.constraint(equalTo: cell.topAnchor, constant: 0), stack.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: 0), stack.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: 0), stack.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: 0)]) return cell } }
Topic: UI Frameworks SubTopic: AppKit Tags:
2
0
125
Aug ’25
FileManager.default.trashItem(at:resultingItemURL:) doesn't update trash icon to be full for some devices
A user of my app noticed that when using it to move a file to the trash on an USB drive, the trash doesn't show the file until unmounting the drive and mounting it again. I was able to reproduce it with one of my own USB drives, but with another USB drive it doesn't reproduce. All USB drives are formatted APFS. When moving a file to the trash from the Finder, both USB drives immediately list it in the trash. Is this a macOS bug, or am I doing something wrong? I created FB19941168. let openPanel = NSOpenPanel() openPanel.runModal() let url = openPanel.urls[0] do { var result: NSURL? try FileManager.default.trashItem(at: url, resultingItemURL: &result) print(result as Any) } catch { fatalError(error.localizedDescription) }
1
0
116
Aug ’25
How to install macOS Tahoe 26 on an external drive
In the past I was always able to install every major macOS version on an external drive so that I can test my apps. But now I'm unable to install macOS Tahoe 26 on an external drive. Actually, as far as I'm aware, there are not even official links to macOS 26 installers, but only instructions on how to update to macOS 26 from an existing macOS installation. So I thought I'd install macOS 15 on a separate drive and then update to macOS 26, but whenever I run the macOS 15 installer, tell it to install on the external drive, and reboot after the setup process completes, my MacBook just boots into my main macOS partition as if nothing happened. 3 months ago I somehow managed to install macOS Tahoe beta 1 on an external drive, I don't remember how (but I don't think it was anything crazy); booting into that beta 1 partition and trying to update doesn't work either, as my MacBook again boots into my main macOS partition. I already asked help about the update problem one month ago here, but nobody replied. Could someone at Apple please provide instructions on how one is supposed to install macOS 26 on an external drive (if possible before it becomes available to the public)? Are we supposed to buy a separate Mac for every macOS version that we want to test our apps on?
0
1
180
Sep ’25
Selecting ~/Library in open panel doesn't give access to ~/Library/Mail
A user of my app brought to my attention that unless they select their ~/Library/Mail folder explicitly in an open panel, they get an error when scanning it inside my app. I can confirm that I also get a permission error when trying to scan it as a subfolder of ~/Library, but not if I select it directly. I'm assuming this is intentional, but it would be nice to have an explanation or some documentation that I can point my users to when they encounter what appears to them as a bug in my app. What makes this matter even more confusing is that selecting a folder in any open panel of an app gives the app access to it for the lifetime of the app, but after restarting the app, access is lost again (unless it has a bookmark to it). This was probably the reason why the user thought that it worked in another app but not in mine. This is the code I use to scan: let openPanel = NSOpenPanel() openPanel.canChooseDirectories = true if openPanel.runModal() == .cancel { return } let enumerator = FileManager.default.enumerator(at: openPanel.urls[0], includingPropertiesForKeys: nil) { url, error in print(url.path, error) return true } while let url = enumerator?.nextObject() as? URL { } And this the error related to the Mail folder: ~/Library/Mail Error Domain=NSCocoaErrorDomain Code=257 "The file “Mail” couldn’t be opened because you don’t have permission to view it." UserInfo={NSURL=file:///~/Library/Mail, NSFilePath=/~/Library/Mail, NSUnderlyingError=0x600002991470 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
4
0
122
Sep ’25
Tapping tab item in Xcode UI test doesn't always work
While preparing automated screenshots with Xcode UI tests for the iOS 26 release, I noticed that this simple line of code app.buttons["myTabItem"].tap() doesn't always work, both on iPhone and iPad Simulator. In fact, it rarely works. Even when repeating the same test, mostly it fails on that line, but a few times it works and I can see the tab item change in the simulator. My main view looks like this: TabView { MyTab1() .tag(tag1) .tabItem { Label("label1", systemImage: "image1") } MyTab2() .tag(tag2) .tabItem { Label("label2", systemImage: "image2") .accessibilityIdentifier("myTabItem") } The error I get is Failed to tap "myTabItem" Button: No matches found for Elements matching predicate '"myTabItem" IN identifiers' from input In the given list of buttons, I see the tab items with their labels, but none of them seem to have an identifier, while other buttons have the correct identifier. I wonder how this can only sometimes work. I tried isolating the issue by iteratively commenting out parts of the SwiftUI code, but unfortunately the behaviour seems erratic. When a change results in the issue not happening anymore, undoing the last X changes often causes the issue to stay away, even with configurations that previously had the issue. I've already spent almost a whole day trying to find the root cause, but with such apparently random behaviour it has proven impossible. Of course, I cannot reproduce the issue with a fresh test project, so the only way to reproduce it with 95% probability is running my original project. Has anyone had the same issue, or does anyone know how I could debug this to find out what causes my UI test to not be able to tap another tab item?
0
0
174
Sep ’25
Sidebar created on macOS 26 with NSSplitViewItem(sidebarWithViewController:) is cut off at the top in fullscreen mode
I noticed that when I have a fullscreen window in macOS 26, sidebars look like they are cut off at the top: they suddenly stop where the title bar/toolbar would appear when moving the mouse to the top of the screen, leaving a wide empty gap. Am I the only one who finds this ugly? Is this intended, or is there a workaround? This is how it looks in fullscreen (the sidebar borders are not easy to distinguish, look for the drop shadow): And this when moving the mouse to the top screen border to show the menu bar: I created FB20291636. @main class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { let splitViewController = NSSplitViewController() splitViewController.addSplitViewItem(NSSplitViewItem(sidebarWithViewController: ViewController())) splitViewController.addSplitViewItem(NSSplitViewItem(viewController: ViewController())) let window = NSWindow(contentViewController: splitViewController) window.styleMask = [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView] window.toolbar = NSToolbar() window.delegate = self window.makeKeyAndOrderFront(nil) } func window(_ window: NSWindow, willUseFullScreenPresentationOptions proposedOptions: NSApplication.PresentationOptions = []) -> NSApplication.PresentationOptions { return [.autoHideToolbar, .autoHideMenuBar, .fullScreen] } } class ViewController: NSViewController { override func loadView() { let stack = NSStackView(views: [ NSTextField(labelWithString: "asdf") ]) stack.orientation = .vertical stack.alignment = .leading view = stack view.frame = CGRect(x: 0, y: 0, width: 300, height: 300) } }
Topic: UI Frameworks SubTopic: AppKit Tags:
1
0
103
Sep ’25
NSWindow.titlebarAppearsTransparent only works after collapsing and expanding sidebar
I'm using the simplified code below to create a window with 4 split view items, some of them collapsed. I would expect the title bar to be transparent since I'm using window.titlebarAppearsTransparent = true, but it seems that this particular view configuration causes the title bar to be visible until I collapse and expand the sidebar again. Removing any of the split view items, uncollapsing any of them, or changing the view of any of the view controllers, causes the title bar to be consistently visible or hidden, although I don't understand the logic, since I'm telling the window that it should be transparent. When launching the app in light mode, it's more difficult to notice the issue since the title bar background is equal to the content background and only the separator is visible (even though the code sets window.titlebarSeparatorStyle = .none): After collapsing and expanding the sidebar, the separator is gone: In dark mode the title bar is more visible: After collapsing and expanding the sidebar, the title bar background and separator are gone: I created FB20306872. @main class AppDelegate: NSObject, NSApplicationDelegate, NSToolbarDelegate { var splitViewController: NSSplitViewController! func applicationDidFinishLaunching(_ aNotification: Notification) { let splitViewItem1 = NSSplitViewItem(sidebarWithViewController: ViewController1()) let splitViewItem2 = NSSplitViewItem(viewController: ViewController2()) let splitViewItem3 = NSSplitViewItem(viewController: NSViewController()) splitViewItem3.isCollapsed = true let splitViewItem4 = NSSplitViewItem(viewController: NSViewController()) splitViewItem4.isCollapsed = true splitViewController = NSSplitViewController() splitViewController.splitViewItems = [splitViewItem1, splitViewItem2, splitViewItem3, splitViewItem4] let window = NSWindow(contentViewController: splitViewController) window.styleMask = [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView] window.titlebarAppearsTransparent = true let toolbar = NSToolbar(identifier: "") toolbar.delegate = self toolbar.displayMode = .iconOnly window.toolbar = toolbar window.titlebarSeparatorStyle = .none window.makeKeyAndOrderFront(nil) } func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { return [.space, .flexibleSpace, .sidebarTrackingSeparator, .init("item")] } func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { return [.init("item"), .sidebarTrackingSeparator] } func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? { switch itemIdentifier.rawValue { case "item": let item = NSToolbarItem(itemIdentifier: itemIdentifier) item.image = NSImage(systemSymbolName: "sidebar.leading", accessibilityDescription: nil) item.action = #selector(toggleSidebar(_:)) item.target = self return item default: return nil } } @objc func toggleSidebar(_ sender: Any?) { splitViewController.splitViewItems[0].animator().isCollapsed = !splitViewController.splitViewItems[0].isCollapsed } } class ViewController1: NSViewController { override func loadView() { view = NSView(frame: CGRect(x: 0, y: 0, width: 300, height: 200)) } } class ViewController2: NSViewController { override func loadView() { let textView = NSTextView() let scrollView = NSScrollView(frame: CGRect(x: 0, y: 0, width: 400, height: 200)) scrollView.hasVerticalScroller = true scrollView.documentView = textView view = scrollView } }
Topic: UI Frameworks SubTopic: AppKit Tags:
0
0
81
Sep ’25
Control status item and login item from within app
In macOS 26 I noticed there is a section Menu Bar in System Settings which allows to toggle visibility of status items created with NSStatusItem. I'm assuming this is new, since I never noticed it before. Currently my app has a menu item that allows toggling its status item, but now I wonder whether it should always create the status item and let the user control its visibility from System Settings. Theoretically, keeping this option inside the app could lead to confusion if the user has previously disabled the status item in System Settings, then perhaps forgot about it, and then tries to enable it inside the app, but apparently nothing happens because System Settings overrides the app setting. Should I remove the option inside the app? This also makes me think of login items, which can be managed both in System Settings and inside the app via SMAppService. Some users ask why my app doesn't have a launch at login option, and I tell them that System Settings already offers that functionality. Since there is SMAppService I could offer an option inside the app that is kept in sync with System Settings, but I prefer to avoid duplicating functionality, particularly if it's something that is changed once by the user and then rarely (if ever) changed afterwards. But I wonder: why can login items be controlled by an app, and the status item cannot (at least I'm not aware of an API that allows to change the option in System Settings)? If the status item can be overridden in System Settings, why do login items behave differently?
7
0
162
Sep ’25
Window title bar in macOS 26 is drawn even if titlebarAppearsTransparent = true
macOS 26 sometimes draws the title bar background even when setting NSWindow.titlebarAppearsTransparent = true and I don't understand the logic behind it, or how I can turn this off. I'm trying to do something similar to Xcode's "Welcome to Xcode" window which has a left view and a right table view. In my simplified example, the window contains a label and a text view. This used to work in macOS 15, but in macOS 26 the text view is partially covered by the title bar: As soon as I remove the line scrollView.hasVerticalScroller = true, the title bar isn't drawn anymore: The title bar also isn't drawn when removing the view on the left of the text view: I created FB20341654. This may be related to this other issue: NSWindow.titlebarAppearsTransparent only works after collapsing and expanding sidebar @main class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { let window = NSWindow(contentViewController: ViewController()) window.titlebarAppearsTransparent = true window.titleVisibility = .hidden window.styleMask = [.titled, .closable, .fullSizeContentView] window.makeKeyAndOrderFront(nil) } } class ViewController: NSViewController { override func loadView() { view = NSView(frame: CGRect(x: 0, y: 0, width: 400, height: 200)) let scrollView = NSScrollView() scrollView.hasVerticalScroller = true // commenting this line out solves the issue scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.automaticallyAdjustsContentInsets = false let documentView = NSTextView() documentView.string = (0..<10).map({ "\($0)" }).joined(separator: "\n") scrollView.documentView = documentView let stack = NSStackView(views: [ NSTextField(labelWithString: "asdfasdfasdfasdf"), // commenting this line out also solves the issue scrollView ]) stack.orientation = .horizontal view.addSubview(stack) NSLayoutConstraint.activate([stack.topAnchor.constraint(equalTo: view.topAnchor), stack.leadingAnchor.constraint(equalTo: view.leadingAnchor), stack.trailingAnchor.constraint(equalTo: view.trailingAnchor), stack.bottomAnchor.constraint(equalTo: view.bottomAnchor)]) } }
Topic: UI Frameworks SubTopic: AppKit Tags:
2
0
220
Sep ’25
Take correctly sized screenshots with ScreenCaptureKit
I've been using CGWindowListCreateImage which automatically creates an image with the size of the captured window. But SCScreenshotManager.captureImage(contentFilter:configuration:) always creates images with the width and height specified in the provided SCStreamConfiguration. I could be setting the size explicitly by reading SCWindow.frame or SCContentFilter.contentRect and multiplying the width and height by SCContentFilter.pointPixelScale , but it won't work if I want to keep the window shadow with SCStreamConfiguration.ignoreShadowsSingleWindow = false. Is there a way and what's the best way to take full-resolution screenshots of the correct size? import Cocoa import ScreenCaptureKit class ViewController: NSViewController { @IBOutlet weak var imageView: NSImageView! override func viewDidAppear() { imageView.imageScaling = .scaleProportionallyUpOrDown view.wantsLayer = true view.layer!.backgroundColor = .init(red: 1, green: 0, blue: 0, alpha: 1) Task { let windows = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: true).windows let window = windows[0] let filter = SCContentFilter(desktopIndependentWindow: window) let configuration = SCStreamConfiguration() configuration.ignoreShadowsSingleWindow = false configuration.showsCursor = false configuration.width = Int(Float(filter.contentRect.width) * filter.pointPixelScale) configuration.height = Int(Float(filter.contentRect.height) * filter.pointPixelScale) print(filter.contentRect) let windowImage = try await SCScreenshotManager.captureImage(contentFilter: filter, configuration: configuration) imageView.image = NSImage(cgImage: windowImage, size: CGSize(width: windowImage.width, height: windowImage.height)) } } }
5
0
916
Oct ’25
NSDocument doesn't autosave last changes
I had noticed an unsettling behaviour about NSDocument some years ago and created FB7392851, but the feedback didn't go forward, so I just updated it and hopefully here or there someone can explain what's going on. When running a simple document-based app with a text view, what I type before closing the app may be discarded without notice. To reproduce it, you can use the code below, then: Type "asdf" in the text view. Wait until the Xcode console logs "saving". You can trigger it by switching to another app and back again. Type something else in the text view, such as "asdf" on a new line. Quit the app. Relaunch the app. The second line has been discarded. Am I doing something wrong or is this a bug? Is there a workaround? class ViewController: NSViewController { @IBOutlet var textView: NSTextView! } class Document: NSDocument { private(set) var text = "" override class var autosavesInPlace: Bool { return true } override func makeWindowControllers() { let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil) let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! NSWindowController (windowController.contentViewController as? ViewController)?.textView.string = text self.addWindowController(windowController) } override func data(ofType typeName: String) throws -> Data { Swift.print("saving") text = (windowControllers.first?.contentViewController as? ViewController)?.textView.string ?? "" return Data(text.utf8) } override func read(from data: Data, ofType typeName: String) throws { text = String(decoding: data, as: UTF8.self) (windowControllers.first?.contentViewController as? ViewController)?.textView.string = text } }
Topic: UI Frameworks SubTopic: AppKit Tags:
17
0
464
Oct ’25
App icon produced by Xcode 26 is 1 MB bigger than Xcode 16
When comparing the Assets.car file of the previous and current versions of my app, compiled with Xcode 16 and 26, respectively, with the Terminal command assetutil --info MyApp.app/Contents/Resources/Assets.car I see that the new version contains many more app icons at different sizes, increasing my app's size by 1 MB (not much, but considering that the app is only 6 MB in total...): { "AssetType" : "MultiSized Image", "Name" : "AppIcon", "NameIdentifier" : 6849, "Scale" : 1, "SHA1Digest" : "9D75F76992E9E9E5531A214A4AE282EBD381F7EB903024E00FB25EB42381CC45", "SizeOnDisk" : 308, "Sizes" : [ "16x16 index:1 idiom:universal", "32x32 index:2 idiom:universal", "64x64 index:3 idiom:universal", "128x128 index:4 idiom:universal", "256x256 index:5 idiom:universal", "512x512 index:6 idiom:universal", "1024x1024 index:7 idiom:universal" ] } The previous one allowed me to add only two sizes: { "AssetType" : "MultiSized Image", "Name" : "AppIcon", "NameIdentifier" : 6849, "Scale" : 1, "SHA1Digest" : "AC782A2FFF9A4B2D563EF64DF41A179583440560F8732A176A8376B31000368E", "SizeOnDisk" : 248, "Sizes" : [ "256x256 index:1 idiom:universal", "512x512 index:2 idiom:universal" ] } Is there a way to only ship the strictly necessary app icons sizes while using Xcode 26 Icon Composer, or will all the sizes be required going forward?
0
0
141
Oct ’25
Feedbacks get closed if they cannot be reliably reproduced
It’s very frustrating when in a feedback I specify that I cannot reliably reproduce it and the feedback gets closed with the message “Since this issue cannot be reproduced, this report has been closed”, e.g. FB18985938. Is Apple not interested in hearing about issues that cannot be reliably reproduced? Many issues unfortunately depend on a variety of factors and it’s often impossible for third-party developers or users to figure out how to reliably reproduce them. Usually these kind of issues get addressed by e.g. adding more logging so that the next time it happens it's easier to find out what's causing it. Then the last part of the message “Please file a new report with a sysdiagnose if you encounter this issue again” sounds like I’m being teased, because what use is a new sysdiagnose if I still cannot reproduce it reliably? It will just be closed like the last one. I created FB20595673 for this issue.
0
0
89
Oct ’25
App sometimes crashes when inserting String into Set with assertion ELEMENT_TYPE_OF_SET_VIOLATES_HASHABLE_REQUIREMENTS
Xcode downloaded a crash report for my app that crashed when trying to insert a String into a Set<String>. Apparently there was an assertion failure ELEMENT_TYPE_OF_SET_VIOLATES_HASHABLE_REQUIREMENTS. I assume that this assertion failure happened because the hash of the new element didn't match the hash of an equal already inserted element, but regardless, I don't understand how inserting a simple string could trigger this assertion. Here is essentially the code that leads to the crash. path is any file system directory, and basePath is a directory higher in the hierarchy, or path itself. var scanErrorPaths = Set<String>() func main() { let path = "/path/to/directory" let basePath = "/path" let fileDescriptor = open(path, O_RDONLY) if fileDescriptor < 0 { if (try? URL(fileURLWithPath: path, isDirectory: false).checkResourceIsReachable()) == true { scanErrorPaths.insert(path.relativePath(from: basePath)!) return } } extension String { func relativePath(from basePath: String) -> String? { if basePath == "" { return self } guard let index = range(of: basePath, options: .anchored)?.upperBound else { return nil } return if index == endIndex || basePath == "/" { String(self[index...]) } else if let index = self[index...].range(of: "/", options: .anchored)?.upperBound { String(self[index...]) } else { nil } } } crash.crash
7
0
827
Oct ’25