Construct and manage a graphical, event-driven user interface for your macOS app using AppKit.

AppKit Documentation

Post

Replies

Boosts

Views

Activity

NSImage issue when try to deploy a MacOS13 version on OS14 and Xcode15
I cannot set "minimum deployment version" of the software into MacOS 13.0 on MacOS 14.0 beta 2, with Xcode 15 beta. This will give me an error in GeneratedAssetSymbols.swift file. The error is: 'let' property 'isTemplate' may not be initialized directly; use "self.init(...)" or "self = ..." instead. However, development on MacOS 14 is totally fine. Is this issue caused by my implementation or something changes in the SDK? Thanks!
3
0
785
Jun ’23
NSTextField in table view with specific configuration doesn't enable undo
After typing anything in a custom text field with undo support, when opening the Edit menu, the undo item is disabled. It seems that setting translatesAutoresizingMaskIntoConstraints=false, a formatter, allowsEditingTextAttributes=true and calling invalidateIntrinsicContentSize() in textDidChange(_:) causes this behaviour. Is this expected, or is there a workaround? Here is the code: class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { @IBOutlet weak var textField: NSTextField! override func loadView() { view = NSView(frame: CGRect(x: 0, y: 0, width: 400, height: 400)) let textField = MyTextField() textField.frame = CGRect(x: 0, y: 0, width: 100, height: 20) textField.translatesAutoresizingMaskIntoConstraints = false textField.formatter = MyFormatter() textField.allowsEditingTextAttributes = true view.addSubview(textField) } } class MyTextField: NSTextField { override func textDidChange(_ notification: Notification) { super.textDidChange(notification) super.invalidateIntrinsicContentSize() } } class MyFormatter: Formatter { override func string(for obj: Any?) -> String? { return obj as? String } override func getObjectValue(_ obj: AutoreleasingUnsafeMutablePointer<AnyObject?>?, for string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool { obj?.pointee = string as NSString return true } }
0
0
483
Jul ’23
Autosizing text field: NSCell.cellSize(forBounds:) doesn't respect wrapped text unless using attributed string
I'm trying to implement a text field in a table view that automatically adjusts its height to fit the contained text. My current implementation adjusts its intrinsicContentSize in textDidChange(_:). Unfortunately, NSCell.cellSize(forBounds:) doesn't seem to return the correct height unless setting attributedStringValue and allowsEditingTextAttributes = true for the NSTextField. Is this expected, or is there a workaround? Here is the code: class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { var asdf = "asdf fjdskalöf öf fjkldösa jfklödsa kfljsaödkfj klsdajf kldöasj flkjsdöa fkljasö flkjsa öj " override func loadView() { view = NSView(frame: CGRect(x: 0, y: 0, width: 400, height: 400)) let scrollView = NSScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false let tableView = NSTableView() tableView.usesAutomaticRowHeights = true tableView.addTableColumn(NSTableColumn()) tableView.dataSource = self tableView.delegate = self scrollView.documentView = tableView view.addSubview(scrollView) NSLayoutConstraint.activate([scrollView.topAnchor.constraint(equalTo: view.topAnchor), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor)]) } func numberOfRows(in tableView: NSTableView) -> Int { return 1 } func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { let view = NSTableCellView() let text = AutoSizingTextField() text.translatesAutoresizingMaskIntoConstraints = false text.cell?.wraps = true // uncommenting the next 2 lines and commenting out the line after them solves the issue // text.attributedStringValue = NSAttributedString(string: asdf, attributes: [.font: text.font!, .foregroundColor: NSColor.labelColor]) // text.allowsEditingTextAttributes = true text.stringValue = asdf view.addSubview(text) NSLayoutConstraint.activate([text.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), text.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), text.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20), text.widthAnchor.constraint(equalToConstant: 200)]) return view } } class AutoSizingTextField: NSTextField { override var intrinsicContentSize: NSSize { var size = super.intrinsicContentSize guard let cell = cell else { return size } var frame = frame frame.size.height = .infinity size.height = cell.cellSize(forBounds: frame).height NSLog("intrinsicContentSize \(size)") return size } override func textDidChange(_ notification: Notification) { super.textDidChange(notification) invalidateIntrinsicContentSize() needsLayout = true layoutSubtreeIfNeeded() } override func layout() { invalidateIntrinsicContentSize() super.layout() } }
0
0
533
Jul ’23
Core Image drawing corruption
I have written two custom Core Image metal kernels which I'm using to produce a CIImage (by chaining several filters). I'm drawing the output image in a simple view and whatever I use (CIImage, NSImage, CGImageRef), the image appears corrupted on screen, like some sort of graphics corruption (I've tried on two different machines with different systems). However if I add a simple step to write the image to disk from the CIImage then read it from disk and draw it in that very same view, then all is fine and the image appears correctly. What could possibly be happening here?
7
0
884
Jul ’23
Crash at _dispatch_client_callout + 28, no my code on stack trace
I had 2 crash report from our customer. Both crash point is same but there is no my code on crash stack trace. How to fix this kind of crash problem. Thread 1 Crashed:: Dispatch queue: com.apple.root.background-qos 0 libsystem_kernel.dylib 0x7ff81b84922a __pthread_kill + 10 1 libsystem_pthread.dylib 0x7ff81b880f7b pthread_kill + 263 2 libsystem_c.dylib 0x7ff81b7caca5 abort + 123 3 libc++abi.dylib 0x7ff81b83b082 abort_message + 241 4 libc++abi.dylib 0x7ff81b82c23d demangling_terminate_handler() + 266 5 libobjc.A.dylib 0x7ff81b529023 _objc_terminate() + 96 6 libc++abi.dylib 0x7ff81b83a4a5 std::__terminate(void (*)()) + 8 7 libc++abi.dylib 0x7ff81b83a456 std::terminate() + 54 8 libdispatch.dylib 0x7ff81b701a58 _dispatch_client_callout + 28 9 libdispatch.dylib 0x7ff81b704500 _dispatch_continuation_pop + 463 10 libdispatch.dylib 0x7ff81b715dff _dispatch_source_invoke + 2184 11 libdispatch.dylib 0x7ff81b7116a2 _dispatch_root_queue_drain + 343 12 libdispatch.dylib 0x7ff81b711e4d _dispatch_worker_thread2 + 160 13 libsystem_pthread.dylib 0x7ff81b87dc9d _pthread_wqthread + 256 14 libsystem_pthread.dylib 0x7ff81b87cc67 start_wqthread + 15 This crash point is exactly same with this post. I do not throw C++ exception. https://developer.apple.com/forums/thread/725197
4
0
1.2k
Jul ’23
CARemoteLayer Refusing To Draw Hosted Contents
I'm exploring using the CARemoteLayerClient/Server API to render a layer from another process as is described in the docs, but can't seem to get a very simple example to work. Here's a very simple example of what I'd expect to work: // Run with `swift file.swift` import AppKit let app = NSApplication.shared class AppDelegate: NSObject, NSApplicationDelegate { let window = NSWindow( contentRect: NSMakeRect(200, 200, 400, 200), styleMask: [.titled, .closable, .miniaturizable, .resizable], backing: .buffered, defer: false, screen: nil ) func applicationDidFinishLaunching(_ notification: Notification) { window.makeKeyAndOrderFront(nil) let view = NSView() view.frame = NSRect(x: 0, y: 0, width: 150, height: 150) view.layerUsesCoreImageFilters = true view.wantsLayer = true let server = CARemoteLayerServer.shared() let client = CARemoteLayerClient(serverPort: server.serverPort) print(client.clientId) client.layer = CALayer() client.layer?.backgroundColor = NSColor.red.cgColor // Expect red rectangle client.layer?.bounds = CGRect(x: 0, y: 0, width: 100, height: 100) let serverLayer = CALayer(remoteClientId: client.clientId) serverLayer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100) view.layer?.addSublayer(serverLayer) view.layer?.backgroundColor = NSColor.blue.cgColor // Background blue to confirm parent layer exists window.contentView?.addSubview(view) } } let delegate = AppDelegate() app.delegate = delegate app.run() In this example I'd expect there to be a red rectangle appearing as the remote layer. If I inspect the server's layer hierarchy I see the correct CALayerHost with the correct client ID being created, but it doesn't display the correct contents being set from the client side. After investigating this thread: https://bugs.chromium.org/p/chromium/issues/detail?id=312462 and some demo projects, I've found that the workarounds previously found to make this API work no longer seem to work on my machine (M1 Pro, Ventura). Am I missing something glaringly obvious in my simple implementation or is this a bug?
0
0
590
Jul ’23
Bookmark Creation With Security Scope Fails in Xcode Cloud
I have an macOS app, where the user can open/drag a folder so that the contents can be listed and used. The app saves the bookmark data for these folders and restores them the next time the app runs. This works perfect on the development machines and on thousands of users' Macs. Recently I added UI tests which perform a couple if happy path tests and they are helping a lot. One of the tests adds a folder and tries to use an image which is in the folder. The folder is copied from the test bundle to the Desktop at the beginning of the test. This works both locally (on my Mac) and on two CI "servers" (latest macOS, Xcode Server). At the moment I try to migrate to Xcode Cloud. Unit tests run fine (after disabling the Hardened Runtime). However, I do not get the UI tests to succeed. They run and add the folder, however, the URL's bookmark data creation fails. I tried to track the differences during the build and found Xcode Cloud builds always being adhoc-signed. Running the UI tests locally but signing the app (and the tests) adhoc too does not result in the same problem. Problem in short: user selects folder (using NSOpenPanel or Drag'n'Drop) url.bookmarkData() works locally and in Xcode Cloud url.bookmarkData(options: [.withSecurityScope]) only works locally but not in Xcode Cloud This is easily reproducible with a very simple project which I can hand-out if needed. Anybody a hint or idea? Since those folders are essential for the app, not solving this would render Xcode Cloud completely useless for me. Thanks! Daniel
1
0
640
Aug ’23
Change MapKit region update animation duration on macOS
I'm writing a multiplatform app that uses MapKit with custom tiles via MKTileOverlay. The map should have buttons for zooming in and out. Those buttons set the region of the MKMapView with animation parameter. I want to make this animation faster. While good for generic change of a region, it feels too slow when changing the region for the zooming purposes. In general, I'm working with SwiftUI. But because MKTileOverlay is not available there, the MKMapView is being accessed via the UIViewRepresentable and NSViewRepresentable respectively. On iOS, to make animation faster (reduce animation time), I'm using UIView.animate(withDuration: 0.2) { mapView.setRegion(region, animated: true) } and it achieves the goal. On macOS, I tried: NSAnimationContext.runAnimationGroup { context in context.duration = 0.2 mapView.setRegion(region, animated: true) } and: CATransaction.begin() CATransaction.setAnimationDuration(0.2) mapView.setRegion(region, animated: true) CATransaction.commit() but without success. The default animation duration is not overridden. I appreciate any input you could give me. Alexey
0
0
748
Aug ’23
c++ NS::Application please help me aim at a total loss
hi all, so I have followed this on how to set up a metal c++ project in Xcode: https://developer.apple.com/metal/cpp/ i have also downloaded the learn apple cpp examples: https://developer.apple.com/metal/LearnMetalCPP.zip To get to a point of basic fundamental knowledge of how it works I've tried to go through the process of creating a basic window in the same way that its done in these examples, I can't how ever not get Xcode to recognize evin the basic NS::Application component. Do anyone know what I am doing wrong, and also is there a source somewhere with some kind of basic examples online. I do not have to be c++ Ive added a screenshot of Xcode not recognizing NS::Application evinthrough I have followed project guide at the top. thank you so much for looking at this :)
1
0
589
Aug ’23
If NSImage is not Sendable, how should async functions return images?
I saw that the macOS 14 SDK added this: @available(*, unavailable) extension NSImage : @unchecked Sendable { } Do I interpret this correctly to mean that NSImage is not Sendable and this extension’s sole purpose is to document this fact? I understand why NSImage isn’t safe to use from multiple threads at the same time. But what is the best way to pass around images in async contexts, then? CGImage is Sendable and is a fine substitute for pixel-based images, but what about PDFs? Is the only feasible way to create a PDF-based NSImage by doing everything on the main thread? (Except maybe load the file into a Data?) On the other hand, UIImage is Sendable, but I suppose that is because it uses a CGImage under the hood?
3
4
1.4k
Aug ’23
Determinate spinning NSProgressIndicator doesn't adapt to frame size and gets cut off
The following code should produce 6 spinning progress indicators of varying sizes: 3 indeterminate and 3 determinate ones. The first two of the 3 determinate ones are either entirely or partially cut off, which doesn't happen with the indeterminate ones. What's the problem? var progress = NSProgressIndicator(frame: CGRect(x: 0, y: 0, width: 16, height: 16)) progress.style = .spinning view.addSubview(progress) progress = NSProgressIndicator(frame: CGRect(x: 50, y: 0, width: 24, height: 24)) progress.style = .spinning view.addSubview(progress) progress = NSProgressIndicator(frame: CGRect(x: 100, y: 0, width: 32, height: 32)) progress.style = .spinning view.addSubview(progress) progress = NSProgressIndicator(frame: CGRect(x: 150, y: 0, width: 16, height: 16)) progress.style = .spinning progress.isIndeterminate = false progress.doubleValue = 50 progress.maxValue = 100 view.addSubview(progress) progress = NSProgressIndicator(frame: CGRect(x: 200, y: 0, width: 24, height: 24)) progress.style = .spinning progress.isIndeterminate = false progress.doubleValue = 50 progress.maxValue = 100 view.addSubview(progress) progress = NSProgressIndicator(frame: CGRect(x: 250, y: 0, width: 32, height: 32)) progress.style = .spinning progress.isIndeterminate = false progress.doubleValue = 50 progress.maxValue = 100 view.addSubview(progress)
1
0
418
Aug ’23
Converting macOS system colors to iOS system colors in NSAttributedString
When syncing an NSAttributedString between devices, it seems that macOS system colors are decoded as "UIExtendedGrayColorSpace" black color on iOS. For example, if I have text on the Mac and chose systemColorRed, this is converted to UIExtendedGrayColorSpace black on iOS. I would like to convert the macOS system red (for example) to the iOS system red, but I'm not sure the best way to do this. My question is: has anyone discovered an efficient and clean way to convert macOS system colors to iOS system colors when syncing between devices? I have seen that the system colors on both devices have a consistent hex value when reading the color components. A possible solution would be to save the hex value of the colors in the attributed string. We could then enumerate the hex values and exchange the attributed string foreground color for the appropriate system color of whatever device is being used. I would greatly appreciate thoughts regarding this. Thank you everyone!
2
0
514
Aug ’23
Using NSApplicationActivationPolicyAccessory does not hide the icon in dock
I have an application which will launches another application as a child process. The child application does not need the dock icon, we use [NSApp setActivationPolicy: NSApplicationActivationPolicyAccessory]; to achieve it. However, I have discovered that the dock icon cannot be perfectly hidden. The number of recently used apps that aren’t already in dock(not choose keep in dock) less than three: The icon of the child application remains in the dock without being hidden. The number of recently used apps that aren’t already in dock(not choose keep in dock) more than three: The icon of the child application appears a few milliseconds. Even though add LSUIElement key in the Info.plist can work, we are seeking a programmatic modification.
3
0
713
Aug ’23
NSSpellServer example
Is there any modern example of how to create a sandboxed application that provides a spelling service to other macOS applications? The example out there are all in Objective-C and doesn't work when run in modern Xcode.
2
1
309
Aug ’23
Multiple NSMenu issues in Sonoma
Sonoma beta release notes mention that NSMenu was rewritten from scratch using AppKit, however, it seems like a lot of behavior was removed along the way which breaks applications. I've filed several requests using Feedback Assistant, but none of them were fixed in the 3 following betas. FB12867496: NSMenu no longer receives keyboard events from GetEventDispatcherTarget (there is a workaround) FB12867573: NSMenuItem custom view window is nil FB12887219 : NSMenu performSelector highlightItem doesn't highlight menu item FB12938907: NSMenu not properly updated when adding/removing NSMenuItem I wonder if anyone else has experienced similar problems and can share workarounds for them:
6
2
1k
Aug ’23
No console output when project Is built and action is triggered
This is my first Xcode application, I'm building a simple MacOS chatbox application that uses python scrips, PythonKit, and swift to handle serverSide operations and accessing open's api and is meant to trigger these two methods I have in a function called executeProcess() that is meant to invoke other functions in another file when a question is types in the text field and the 'enter' key on a keyboard is hit via the onCommit function, however im getting no console output. here is my relevant code from my contentView.swift file I can provide more code from other files if needed.(I will just be showing the non SwiftUI specific code here) import Cocoa import Foundation import PythonKit import AppKit protocol runPyRunnable { func runPyServer(completion: @escaping(String) -> Void) func sendRequest(userInput: String, completion: @escaping(String) -> Void) } func runPyServer() -> String { print("server run") return "server run" } struct MyPyTypePlaceHolder: runPyRunnable { func runPyServer(completion: @escaping(String) -> Void) { } func sendRequest(userInput: String, completion: @escaping (String) -> Void) { } } struct ContentView: View { var ViewController: runPyRunnable? = MyPyTypePlaceHolder() as? runPyRunnable @State private var text: String = "" @State private var filePath = "" @State private var inputText = "" var body: some View { makeContent() .onAppear{ NSApp.mainWindow?.makeFirstResponder(NSApp.mainWindow?.contentView) } } ZStack { Spacer() TextField("Ask Mac GPT...", text: $inputText, onCommit: { executeProcess(withInput: inputText) { response in print(response) } }) .font(Font.custom("Futura", size: 17.4)) .padding(.horizontal, 25) .padding(.vertical, 15) .background(Color.white) .cornerRadius(29) .overlay( RoundedRectangle(cornerRadius: 27.9).stroke(Color.gray, lineWidth: 1.0) ) .offset(y: -200) .padding(.horizontal, 35) } } func executeProcess(withInput input: String, completion: @escaping (String) -> Void ) { DispatchQueue.global().async { DispatchQueue.main.async { guard !input.isEmpty else { print("TextField is empty, enter input in the text field") return } if let myPyTypeInstance = self.ViewController { myPyTypeInstance.runPyServer { responseFromRunPyServer in myPyTypeInstance.sendRequest(userInput: input) { responseFromSendRequest in completion(responseFromSendRequest) } } } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } }
0
0
434
Sep ’23
F2 key press event for macOS
Why kVK_F2 is not equivalent to constant NSF2FunctionKey for F2 key press event, What is equivalent constant of kVK_F2, since carbon framework is deprecated. When I printed the keyCode, The [Event keyCode] against NSF2FunctionKey is 63237(0xF705) whereas for kVK_F2, it prints is 120 which is 0x78. 0x78 seems to be the standard keyboard value for F2 key. Sample code : //@property (nonatomic, strong) id eventMonitor; NSEvent* (^handler)(NSEvent*) = ^(NSEvent *theEvent) { NSEvent *result = theEvent; NSUInteger flags = [theEvent modifierFlags] &amp; NSEventModifierFlagDeviceIndependentFlagsMask; if ((flags &amp; NSEventModifierFlagFunction) &amp;&amp; (flags &amp; NSEventModifierFlagCommand) &amp;&amp; ([theEvent keyCode] == NSF2FunctionKey)) { NSLog(@"Command + F2 key pressed."); } return result; }; _eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:(NSEventModifierFlagFunction | NSEventMaskKeyDown) handler:handler];
1
0
439
Sep ’23
Sonoma beta - app's dialog buttons grayed out - NSTextField wont allow edits
I have a macOS app built with Xcode 14.1 that works perfectly on Catalina through Ventura. Works on Apple Silicon and Intel machines. When it runs under Sonoma (9/12/23 release and earlier) controls in dialog boxes no longer highlight blue but can be pressed. Text fields can not be edited. Radio buttons can be selected but they all stay gray. This happens to not only the app's custom dialogs but Apple's NSSavePanel() and others. It happens in Sonoma with Apple Silicon or Intel versions under Rosetta. An earlier version built with Xcode 13 works just fine (except WebKit has issues). I made a small app that just tries to do a NSAlert() and it works correctly in Sonoma built with Xcode 14.1. I have not seen any other apps do this under Sonoma. In order to rule out some sort of byzantine focus problem with the view controllers in the app, I removed everything from applicationDidFinishLaunching() and put an NSAlert() in there. Same thing, the default button comes out gray and not blue. I've tried bumping up the minimum release to macOS 12.x. No luck. It's nothing to do with Appearance, I have removed all of that code. Deleted all the prefs. I've rebuilt the project file in Xcode 14.1 from scratch, same thing - no blue focus buttons. I've tried building it with the latest versions of Xcode and the same problem. Any ideas what in the world can cause this?
2
0
732
Sep ’23
Drag URL from my app to another using a promise (in Swift)
Hi All, I have successfully implemented drag & drop of files from and to other apps on macOS successfully using different methods. Including NSFilePromiseProvider for example. There is one app however, that I use on a regular basis, that only support file urls as drop types. So I have to use public.file-url to drag & drop files there. The problem is that the file does not exist when dragging starts. That's why I would like to send a URL promise to the app, instead of a file promise. I can't create the file beforehand because then I would need to create hundreds of large files which will just take up space. So whenever I drag an item from my app to the other app, then the file shall be created and the url shall be sent to that app to be opened. But as the other app only checks the pasteboard for urls without handling promises, this is not working. I do have their code available, but can't change the code. Question: Is there a way in Swift on macOS to drag and drop a an item to another app so that upon mouse up on the other app some async tasks is executed and at the end the other app receives the URL as a result of the async task?
0
1
493
Sep ’23