I'm working on a macOS application that needs to query the list of available printers using NSPrinter.printerNames. For performance reasons, I'd like to perform this operation on a background thread.
However, since NSPrinter is part of AppKit, and AppKit is generally not thread-safe unless explicitly stated, I want to confirm:
Is it safe to call NSPrinter.printerNames from a background thread?
I couldn’t find explicit guidance in the documentation regarding the thread-safety of printerNames, so any clarification or best practices would be appreciated.
Thanks in advance!
Note: I tested this api on a background thread in code and it did not give any error.
Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have a UITextView being added at runtime to a UIImageView as the result of doing text recognition. It's set to be editable = NO and selectable = YES. When I set the text and select it, it asks the delegate for the menu to display via:
textView:editMenuForTextInRange:suggestedActions:
The suggested items contains many UIAction and UICommand objects that have private methods or do not have the destructive attribute set, yet they are destructive. Some of these are:
promptForReplace:
transliterateChinese:
_insertDrawing:
_showTextFormattingOptions:
I need to return a menu that has only non-destructive commands in it.
First, why isn't UITextView sending only non-destructive suggested commands when its editable is NO?
Second, how can I filter the array of suggested commands when it's impossible to know if they're destructive (as some are missing that attribute)?
In addition to that, even non-destructive commands are causing an unrecognized selector exception, such as the Speak command, which it is sending to my view controller instead of to the UITextView, which is the only thing that knows what the text is that it should speak.
Topic:
UI Frameworks
SubTopic:
UIKit
Hey, I've been having a problem with scroll views in combination with the .geometryGroup() modifier.
I have filed a Feedback (FB17698293) but I also wanted to post this here in case someone maybe has a better workaround for the problem.
Problem
Whenever you conditionally insert a ScrollView inside a VStack that is modified with a .geometryGroup() modifier, the scroll view content offset resets itself after the insertion animation is done, even if you started scrolling inside the scroll view during the animation and haven't let go of the screen. This happens consistently and is fully reproducible (see below), both using a simulator and a real device.
Unfortunately, this is a very annoying glitch that ruins a lot of cool UX components that rely on .geometryGroup().
The weird thing is that the glitch entirely disappears, if you add a simple, non-zero (but greater than 1) .padding() modifier to the VStack (.padding().geometryGroup()).
I have no idea why this fixes the glitch, but it does. However, adding a padding is not feasible in many situations, so this workaround is not ideal.
Steps to reproduce
Launch the code below (using a simulator or a real device) and tap "Toggle Expansion" to insert the scroll view.
As the view is animating in, drag the scroll content and hold it scrolled away from the top.
Wait for the animation to complete. The scroll view will reset the content offset, even though the drag gesture is still active (i.e. you haven't lifted your finger to release the scroll view)
On a real device, this sometimes even leads to an even worse visual artifact where the scroll view is rendered twice for a few frames; once with the correct offset, and once with the reset offset.
I wanted to include a link to a gif/video showing the glitch, but it tells me that imgur is not allowed on the forums.
Expected Behavior
I want the scroll view to respect the content offset, even if I started changing it mid-animation.
Xcode Version
I am using Xcode 16.4 (16F6) but this problem has been occurring since the .geometryGroup() modifier has been release. I was only now able to pinpoint this problem exactly, so I'm filing this feedback.
Code
The entire code that reproduces the problem:
import SwiftUI
struct ContentView: View {
@State private var isExpanded: Bool = false
var body: some View {
VStack {
if isExpanded {
ScrollView {
Text(loremIpsum)
}
}
Button("Toggle Expansion") {
isExpanded.toggle()
}
}
// .padding(10) // Adding a non-zero padding makes the glitch disappear
.frame(maxWidth: .infinity)
.geometryGroup()
.animation(.default, value: isExpanded)
}
}
#Preview {
ContentView().preferredColorScheme(.dark)
}
// MARK: - Mock Data
let loremIpsum = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt \
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco \
laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt \
mollit anim id est laborum.
"""
Topic:
UI Frameworks
SubTopic:
SwiftUI
Hi everyone,
frome time to time I see crash which Im not able to debug, because there is no line of my code where crash occured.
This is a crash log what Im getting from time to time of some users. In my device I never get this kind of crash.
0 libswiftCore.dylib 0x1172c _assertionFailure(_:_:flags:) + 208
1 libswiftCore.dylib 0x198624 KEY_TYPE_OF_DICTIONARY_VIOLATES_HASHABLE_REQUIREMENTS(_:) + 2980
2 libswiftCore.dylib 0xdb6c8 specialized _NativeDictionary.uncheckedRemove(at:isUnique:) + 534
3 libswiftCore.dylib 0xb250c Dictionary._Variant.setValue(_:forKey:) + 204
4 libswiftCore.dylib 0x5a620 Dictionary.subscript.setter + 520
5 SwiftUICore 0xf62ec ForEachState.item(at:offset:) + 4340
6 SwiftUICore 0xf5054 ForEachState.forEachItem(from:style:do:) + 1796
7 SwiftUICore 0x2272f8 ForEachState.traitKeys.getter + 84
8 SwiftUICore 0x227298 ForEachList.traitKeys.getter + 24
9 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76
10 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76
11 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76
12 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76
13 SwiftUICore 0x2271fc DynamicViewList.WrappedList.traitKeys.getter + 88
27 SwiftUICore 0x226d18 specialized static SectionAccumulator.processUnsectionedContent(list:contentSubgraph:) + 84
28 SwiftUI 0x26afe0 ListSectionInfo.init(list:listAttribute:contentSubgraph:) + 132
29 SwiftUI 0x269bb0 UpdateCollectionViewListCoordinator.updateValue() + 1528
30 SwiftUI 0x785d4 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32
31 AttributeGraph 0xccac AG::Graph::UpdateStack::update() + 540
32 AttributeGraph 0xc870 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424
33 AttributeGraph 0xc444 AG::Subgraph::update(unsigned int) + 848
34 SwiftUICore 0x805a8 GraphHost.flushTransactions() + 860
35 SwiftUI 0x1ac84 closure #1 in _UIHostingView._renderForTest(interval:) + 24
36 SwiftUICore 0x7ffa8 partial apply for closure #1 in ViewGraphDelegate.updateGraph<A>(body:) + 28
37 SwiftUICore 0x7fd6c ViewRendererHost.updateViewGraph<A>(body:) + 120
38 SwiftUICore 0x7fce8 ViewGraphDelegate.updateGraph<A>(body:) + 84
39 SwiftUI 0x3e688 closure #1 in closure #1 in closure #1 in _UIHostingView.beginTransaction() + 172
40 SwiftUI 0x3e5d4 partial apply for closure #1 in closure #1 in closure #1 in _UIHostingView.beginTransaction() + 24
41 SwiftUICore 0x79720 closure #1 in static Update.ensure<A>(_:) + 56
42 SwiftUICore 0x796a4 static Update.ensure<A>(_:) + 100
43 SwiftUI 0x9c808 partial apply for closure #1 in closure #1 in _UIHostingView.beginTransaction() + 80
44 SwiftUICore 0x7f5e0 thunk for @callee_guaranteed () -> () + 28
45 SwiftUICore 0x6161c specialized closure #1 in static NSRunLoop.addObserver(_:) + 144
46 CoreFoundation 0x218a4 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36
47 CoreFoundation 0x213f8 __CFRunLoopDoObservers + 552
48 CoreFoundation 0x75da8 __CFRunLoopRun + 948
49 CoreFoundation 0xc8284 CFRunLoopRunSpecific + 588
50 GraphicsServices 0x14c0 GSEventRunModal + 164
51 UIKitCore 0x3ee674 -[UIApplication _run] + 816
52 UIKitCore 0x14e88 UIApplicationMain + 340
53 SwiftUI 0x291ef8 closure #1 in KitRendererCommon(_:) + 168
54 SwiftUI 0x291e28 runApp<A>(_:) + 100
55 SwiftUI 0x291d0c static App.main() + 180
56 DholRainbow 0x3019e8 main + 4339145192 (DholRainbowApp.swift:4339145192)
57 ??? 0x1b0bf5de8 (Missing)
From Crashlytics I know at least human readable format of this error
Fatal error: Duplicate keys of type 'Contact' were found in a Dictionary. This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion.
I 've checked all my parts of code where Im using dictionary. This is a function which creating that particulary dictionary.
private func logsByDate() {
let groupedByDate = Dictionary(grouping: logs.filter { ($0.remoteParty as? Contact != nil) } ) {
$0.date.removeTimeStamp ?? .distantPast }.mapValues {
$0.compactMap { $0 }
}
var dayLogs = [DayLog]()
for date in groupedByDate {
var contacts = [CallLogContact]()
for log in logs.filter({ $0.date.removeTimeStamp ?? .distantPast == date.key }) {
if let contact = log.remoteParty as? Contact {
if contacts.firstIndex(where: {$0.contact == contact }) == nil {
let contactDayLogs = logs.filter({ $0.remoteParty as? Contact == contact && $0.date.removeTimeStamp == date.key})
contacts.append(
CallLogContact(
contact: contact,
logs: contactDayLogs,
lastCallLogDate: contactDayLogs.sorted(by: {$0.date > $1.date}).first?.date ?? .distantPast
)
)
}
}
}
dayLogs.append(DayLog(date: date.key, contact: contacts))
}
DispatchQueue.main.async {
self.groupedCallLogs = dayLogs
}
}
This function is called from 3 others functions based on notification from the server in case of new call log, fetched call logs and removed call logs.
I am currently developing an AR experience using ARKit with SceneKit and am looking to implement functionality that enables:
Zooming into the AR camera feed, ideally leveraging the ultra-wide or telephoto lenses available on supported devices.
Macro-style focus capabilities, allowing users to view and interact with virtual content closely aligned with small or nearby real-world objects (within a few centimeters).
My objective is to ensure that ARKit continues to render the scene accurately while enabling a zoomed-in view or macro-level focus for better detail visibility and alignment.
Could you please advise on:
Whether ARKit currently supports camera zoom or allows access to macro or ultra-wide cameras within an ARSession.
Limitations or considerations when using multi-camera setups in conjunction with ARKit.
Any guidance or references to documentation or sample code would be greatly appreciated.
Best regards,
Ayush
When the perform method of my AppIntent returns the custom view's dialog, and after I click the "Click Test" button, my app will be launched, but this dialog does not close. How can I close it?
struct QuestionResultView: View {
var body: some View {
VStack {
if #available(iOS 17.0, *) {
Button(role:.cancel, intent: OpenAppIntent()) {
Text("Click Test")
}
}
}.frame(height: 300)
}
}
struct OpenAppIntent : AppIntent {
static let title: LocalizedStringResource = "Open my app"
static let openAppWhenRun: Bool = true
static let isDiscoverable: Bool = false;
@MainActor
func perform() async throws -> some IntentResult {
return .result()
}
}
struct OpenPhotoRecognizing: AppIntent {
static let title: LocalizedStringResource = "Read photo"
static let description = IntentDescription("")
static let openAppWhenRun: Bool = false
func perform() async throws -> some IntentResult & ShowsSnippetView & ProvidesDialog{
return .result(dialog: "Demo Test") {
DemoResultView()
}
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
I want to truncate text from head with max 2 lines.
I try the following code
import SwiftUI
struct ContentView: View {
@State var content: String = "Hello world! wef wefwwfe wfewe weweffwefwwfwe wfwe"
var body: some View {
VStack {
Text(content)
.lineLimit(nil)
.truncationMode(.head)
.frame(height: 50)
Button {
content += content
} label: {
Text("Double")
}
.buttonStyle(.borderedProminent)
}
.frame(width: 200, height: 1000)
.padding()
}
}
#Preview {
ContentView()
}
It show result like this, this is not what I want.
now i must use voip + livekit to developing, When incoming offline messages arrive at the device through VoIP, call ConversationManager The method of reporting NewIncomingConversation (uuid: update:) only first time can push new system UI,second or more time will crash, and acrsh stack appears to indicate that callkit has not been called
Topic:
UI Frameworks
SubTopic:
General
Hello I'm currently building a feature within an ios app using SwiftUI and Mapkit to record the gps cordinates of a user as they move and render the track on the map. the idea is not really to have a "track" but to have a visual representation of the area the user sees while they are moving around. I need this width/breadth to be relative to the map and not the screen, such that when I zoom in and out of the map, the size will adjust automatically.
Hello togehter,
i do have the following question.
If I have my App run in landscape mode and a sheet view get's called, will it be possible to switch automatically from landscape mode in portrait mode and fix this device orientation?
Once the sheet view get's dismissed or closed, the original view will come back and the device orientation shall switch back to landscape mode.
Thanks you so much for your help!
Something func applicationWillEnterForeground is not getting called for specific iOS 18.3.2
Topic:
UI Frameworks
SubTopic:
UIKit
This was also raised in FB17028569
I have iOS document based app using DocumentGroup. I can create and save documents as expected. All that functionality is fine.
@main
struct FooBarApp: App {
var body: some Scene {
DocumentGroup(newDocument: { FoobarDocument() }) { config in
MainView(document: config.document)
}
The problem is when I open an app document from Files.app or Messages the document is never opened directly into the editor, the document browser interface is always presented and the user must manually select the document to open an editor.
This also happens when I use
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil)
to open a new scene. The doc isn't opened into my editor.
I believe my plist document types are setup correctly and that my ReferenceFileDocument is setup correctly
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>foobar</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icon-128</string>
<key>CFBundleTypeIconSystemGenerated</key>
<integer>1</integer>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/json</string>
</array>
<key>CFBundleTypeName</key>
<string>Foobar Project</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.digital-dirtbag.foobar</string>
</array>
<key>NSUbiquitousDocumentUserActivityType</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).ubiquitousdoc</string>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Foobar Project</string>
<key>UTTypeIconFiles</key>
<array>
<string>icon-128.png</string>
</array>
<key>UTTypeIdentifier</key>
<string>com.digital-dirtbag.foobar</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>foobar</string>
</array>
</dict>
</dict>
The question is does DocumentGroup on iOS even support opening documents directly into the editor view?
I know it works on macOS as expected as I tried this with the demo code and it exhibits the same symptoms. Opening a document from iOS Files.app only gets you as far as the document browser while macOS will open an editor directly.
Topic:
UI Frameworks
SubTopic:
SwiftUI
Is is possible to use the camera in ASWebAuthenticationSession? We want to support signing in with a QR Code in our custom OAuth flow but the browser can't seem to access the camera.
Topic:
UI Frameworks
SubTopic:
General
When I present a view controller, whose view is a SwiftUI View, via presentAsModalWindow(_:) the presented window is no longer centered horizontally to the screen, but rather its origin is there. I know this issue occurs for macOS 15.2+, but can't tell if it is from 15.0+. I couldn't find any documentation on why was this changed.
Here's an example code that represents my architecture:
class RootViewController: NSViewController {
private lazy var button: NSButton = NSButton(
title: "Present",
target: self,
action: #selector(presentView))
override func viewDidLoad() {
super.viewDidLoad()
// Add button to tree
}
@objc func presentView() {
presentAsModalWindow(PresentedViewController())
}
}
class PresentedViewController: NSViewController {
override loadView() {
view = NSHostingView(rootView: MyView())
}
}
struct MyView: View {
/* impl */
}
In SwiftUI for macOS, how can I animate the transition from one Tab to another Tab within TabView when the selection changes?
In AppKit, we can do the following:
let tabViewController = NSTabViewController()
tabViewController.transitionOptions = [.crossfade, .allowUserInteraction]
How can I achieve the same crossfade effect when using TabView?
I'm testing using Group Activities and having no trouble iOS<->iOS or starting an activity on macOS and joining via iOS. However, when I start an activity and then try to join it from another macOS client, the starting side joins the session just fine, but the receiving side acts like I don't have the required app, even when it is already running.
I see the active SharePlay icon in the menu bar, and the Current Activity is shown, but instead of an "Open" button there is a "MyApp Required" string and a "View" button that goes to the App Store. (Where the app is not available yet, as expected, since I'm still working on it.) There is no GroupSession started on that Mac yet, obviously.
I'm looking for any hints to help debug what is going on. How does Group Activities find the app for the activity on macOS and how can I figure out why it isn't finding mine?
Thanks!
Hello everyone,
I’m currently developing an iOS app and would like to leverage the AccessorySetupKit framework introduced in iOS 18 to implement pairing functionality with our company's custom hardware product. The specific requirements are as follows:
Our hardware supports both Bluetooth and Wi-Fi connections, and both are enabled.
When the hardware device is in proximity to an iPhone, I want the device to be automatically recognized, and a pairing screen similar to the one in AccessorySetupKit should appear.
Users should be able to perform the pairing process without needing to open our app, even if the app is not in the foreground. The system-level pairing screen should show the hardware information and allow the user to proceed with the pairing.
My questions are:
Does AccessorySetupKit allow the pairing screen to trigger when the app is running in the background, or must the app be in the foreground?
How should I configure AccessorySetupKit to automatically recognize and display my company’s hardware device information? Are there any specific configurations or code implementations needed?
Do I need to implement any specific Bluetooth/Wi-Fi advertising broadcasts to ensure the device is correctly detected by the iOS system when in proximity?
Are there any additional permissions or configurations required, especially for handling background tasks?
Thank you very much for your help, and I look forward to your advice and insights!
Topic:
UI Frameworks
SubTopic:
UIKit
When pushing a page in the navigation, changing the state of interactivePopGestureRecognizer causes the page to freeze.
Just like this:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
CGFloat red = (arc4random_uniform(256) / 255.0);
CGFloat green = (arc4random_uniform(256) / 255.0);
CGFloat blue = (arc4random_uniform(256) / 255.0);
CGFloat alpha = 1.0; //
self.view.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, 0, 100, 44);
btn.backgroundColor = [UIColor redColor];
btn.center = self.view.center;
[btn setTitle:@"push click" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)click:(id)sender {
[self.navigationController pushViewController:[ViewController new] animated:YES];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
@end
QuickTime recording palette behaves in a way which I want to replicate in my desktop app - specifically the behaviour when switching spaces, it appears on top. Currently, my app appears on all spaces, and even over fullscreen applications BUT it already exists when I switch to the space, this feels disjointed.
I can't find a solution to this behaviour. Here's the Window Collection Behaviours I've tried (on an NSPanel):
FullScreenAuxiliary - appears over fullscreen apps.
CanJoinAllSpaces - appears on all spaces.
These two options make the dock show up on all spaces in the same position, but on each space they already exists.
I've tried this behaviour too:
MoveToActiveSpace - which as per docs would move the window into active space only when its reopened, mine stays open all the time.
I can't find any more information on how QuickTime achieves this.
Topic:
UI Frameworks
SubTopic:
SwiftUI
iOS 18.4.1
When I change a Google type event to an iCloud type, a "Cannot Save Event" prompt box pops up.
We have also received user feedback that recurring events also fail to save. After updating to iOS 18.4 when trying to save changes to an existing repeating event, the message "Cannot Save Event" will appear.
EventKitUI
Topic:
UI Frameworks
SubTopic:
UIKit