Post

Replies

Boosts

Views

Activity

Help with SwiftUI macOS focus (keyboard navigation)
Hello, I'm having trouble understanding Focus in SwiftUI on macOS for my application. I have distilled it down to a small reproducible case here. struct ContentView: View {   struct Item : Identifiable, Equatable, Hashable {     let id : Int     let url : URL     @ViewBuilder var view : some View {       if id % 2 != 0 {         AsyncImage(url: url)       } else {         Image(systemName: "questionmark.diamond")       }     }   }   struct DetailView : View {     @Binding var item: Item?     var items : [Item] {       if let item {         return [item, item]       }       return []     }     var body: some View {       List(items) { item in         item.view       }     }   }   var url : URL {     return URL(string: "https://is1-ssl.mzstatic.com/image/thumb/Music/4c/aa/6f/mzi.cnwthgxu.jpg/900x900bb.jpg")!   }   var items : [Item] {     var a : [Item] = []     for i in 0..<10 {       a.append(Item(id: i, url: url))     }     return a   }   @State private var selectedItem : Item?   var body: some View {     NavigationSplitView {       List(items, selection:$selectedItem) { item in         NavigationLink(value: item) {           Text("\(item.id)")         }       }     } detail: {       DetailView(item: $selectedItem)     }   } } If you click on an even row, the behavior is as expected. The side List highlights. Press the Tab key. Nothing highlights, but I assume focus is in the DetailView. Press the Tab key a second time. It will now highlight the focus on the side bar show/hide button in the toolbar. Press the Tab key again, and it will go back to the side view list’s selection. If you click on an odd row, the behavior is not as expected. The side List highlights. Press the Tab key. Nothing highlights, but I still assume focus is in the DetailView. Press the Tab key a second time. This time, instead of focusing the sidebar show/hide button, nothing highlights again. I still assume focus is in the DetailView, but it is not clear what. Now press the Tab key again, and the highlight focuses on the sidebar show/hide button. I’m confused why two Images (one from Image(systemName:) and the other from an URL via AsyncImage) have different Tab key behavior. Why does AsyncImage seem to capture the two images, while the SF Symbols Images do not? Why does anything in the DetailView capture focus at all? Thanks for any tips! FB12044843
0
0
979
Mar ’23
How to reset @SceneStorage?
Hello, On macOS I can use the defaults command line tool to reset or modify @AppStorage data outside the application. Where is @SceneStorage data stored? Alternately, how do I reset my application back to "it's not yet stored"? Thank you for any tips!
0
0
602
Oct ’23
xcstrings and scheme localization debugging issue
Hello, When I use xcstrings in my app, and I have my scheme's localization debugging enabled (when it renders all caps for any non-localized text). Prior to converting to xccstrings, my app shows non caps text for everything. After I convert to xcstrings, some of my app shows caps text for some items. I can see the keys in the xccstrings that I expect, so I do not think it is a bug in the conversion. Could it be a bug in the renderer somehow? FB13261276 Thanks! -- Greg
0
0
639
Oct ’23
Replacement for deprecated CLPlacemark.region?
Hello, I use CLGeocoder to get the CLLocationCoordinate2D and CLRegion for an address. Now that this is deprecated in OS 26, I don't see a replacement for that property on MKMapItem via MKMapItemRequest and PlaceDescriptor. I've filed FB19027378 on this issue. Basically I have some addresses that have a street address, and others that just have a city. With CLGeocoder, when geocoding just the city, the CLRegion was set such that I could show my map zoomed out just right. I'm not sure how to do that now. Thanks!
0
4
165
Jul ’25
Developer Credentials not working in Virtual Machine
Hello, I am running a virtual machine on my Apple Silicon Mac, using the sample Xcode project provided by Apple last year. I have Ventura 13.4 installed on on the host and the VM. I try to enter my Apple ID credentials in "Sign In with Apple ID" in the VM so I may then update this VM to Sonoma. I am sure I am getting my password correct. I cannot log in. Please see the screen shot. Am I supposed to be able to do this? I can log into developer.apple.com within the VM OK. Thank you. FB12263051
1
0
1.1k
Jun ’23
xcstrings in a Swift Package building via swift build fails
If I convert my SPM from .strings to .xcstrings it will fail to build when using swift build. It builds from Xcode 15. My UI code uses bundle: .module so the localized strings are found properly. See https://github.com/bolsinga/site/pull/685 for the change (as well as the action log). Does SPM build somehow not know that .xcstrings in a Resource directory make the build a "bundle build"? I filed FB13261704 Thanks!
1
0
1.5k
Oct ’23
MusicKit / macOS : Song.Artwork not nil when there is no Artwork
I'm using iCloud Music Library. I’m using macOS 14.1 (23B74) and iOS 17.1. i’m using MusicKit to find songs that do not have artwork. On iOS, Song.artwork will be nil for items I know do not have artwork. On macOS, Song.artwork is not nil. However when the songs are shown in Music.app, they do not have Artwork. Is this expected? Alternately, is there a more correct way to determine that a Song has no Artwork? I have also filed FB13315721. Thank you for any tips!
1
0
760
Nov ’24
NavigationSplitView, tvOS, and view focus
Hello, I have a SwiftUI application that uses NavigationSplitView. It's working great on iOS, iPad, and macOS. I decided to give it a try on tvOS. After it builds, it will not allow user interaction on the NavigationSplitView's sidebar. I've tried various view focus modifiers without any success. I'd also expect this to "just work" as default behavior. I have filed FB13447961 on this issue. Here is a distillation of the code that demonstrates the problem. Any ideas? Thank you. enum Category : String, CaseIterable { case first case second case third } enum Detail : String, CaseIterable { case one case two case three } struct DetailView : View { let category : Category? var body: some View { if let category { Text(category.rawValue) List(Detail.allCases, id: \.self) { detail in NavigationLink(value: detail) { Text(detail.rawValue) } } } else { Text("Select Category") } } } struct ContentView: View { // NOTE: If this category is set to something, it will show that category's detail. // The problem is that the NavigationSplitView sidebar does not have, nor does not // seem to be able to get focus. @State var category: Category? @State var path : [Detail] = [] var body: some View { NavigationSplitView { List(Category.allCases, id: \.self, selection: $category) { category in Text(category.rawValue) } } detail: { NavigationStack(path: $path) { DetailView(category: category) .navigationDestination(for: Detail.self) { detail in Text("\(detail.rawValue)") } } } } } #wwdc2023-10162 #wwdc20-10042
1
0
887
Jul ’25
MusicKit and sorted artist and album names?
I have an app that gets data from Music.app with both the iTunesLibrary and MusicKit. iTunesLibrary has ITLibArtist.sortName and ITLibAlbum.sortTitle and ITLibAlbum.sortAlbumArtist. I can’t seem to find an equivalent in MusicKit. How are those properties obtained using MusicKit? Thanks. FYI I have filed FB15554956 on this. You also may see my code at https://github.com/bolsinga/itunes_json
1
1
519
Nov ’24
launchd and git
Hello, I have a script that I can run with launchd. I want it to be able to do some git operations. If I run my script manually (outside of launchd) things work great. If I run it within launchd, it seems to have issues with the sandboxing. git says: error Unable to read current working directory: Operation not permitted Here are the .plist and the .sh. Does anyone have any ideas what I can do? git seems to have many options about reading its configuration files; I assume that is what is going on here. Thanks! com.bolsinga.gitcmd.plist (substitute paths as appropriate): <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!-- Copy this file to ~/Library/LaunchAgents cd ~/Library/LaunchAgents open Console.app and monitor syslog output. NOTE: in the following command, the plist extension is required. launchctl bootstrap gui/501 ~/Library/LaunchAgents/com.bolsinga.gitcmd.plist Look for related output in the syslog. Namely the executable this runs cannot be in ~/Documents, as it will get rejected. It works in ~/Applications launchctl list | grep bolsinga to see if it is running obviously, RunAtLoad below means it will run when loaded. launchctl bootout gui/501 ~/Library/LaunchAgents/com.bolsinga.gitcmd.plist to unload before re-loading when editing this file --> <plist version="1.0"> <dict> <key>Label</key> <string>com.bolsinga.gitcmd</string> <key>ProgramArguments</key> <array> <string>/Users/bolsinga/Applications/gitcmd.sh</string> <string>/Users/bolsinga/Documents/code/git/bin_utils/</string> </array> <key>RunAtLoad</key> <true/> <key>StandardErrorPath</key> <string>/tmp/com.bolsinga.gitcmd.err</string> <key>StandardOutPath</key> <string>/tmp/com.bolsinga.gitcmd.out</string> <key>WorkingDirectory</key> <string>/Users/bolsinga/</string> </dict> </plist> gitcmd.sh #/bin/sh # NOTE! This must be copied into ~/Applications. # So must any scripts it accesses! Otherwise it will not run from ~/bin/ DST_DIR="$1" if [ -z "$DST_DIR" ] ; then echo "No destination directory" 1>&2 exit 1 fi tgit() { GIT_TRACE2=true GIT_TRACE_SETUP=true git $* } echo PWD: `pwd` echo DST_DIR: $DST_DIR echo GIT `which git` tgit config --list tgit -C $DST_DIR config --list cd $DST_DIR tgit config --list
2
0
884
Apr ’24
NavigationStack $path cleared on dealloc?
Hello, This code has a NavigationSplitView, whose sidebar is a List and its detail contains a NavigationStack. It is controlled by two @Observable properties, a selection and a path. The path shown in the detail depends upon the selection in the List. If I programmatically change the selection and path, the path will be set, but via SwiftUI backtraces (pasted below), it will clear out my path. This makes my code lose state. What am I doing wrong? Is this a bug? I'm using Xcode16 running against the iOS 18 simulator (although this also happens with iOS17). To reproduce, Launch the App, Note that you are on the "first" selection. Tap "Nav Path: Path: second-100". You'll go to the "second" selection, but the path will be empty. If you place a breakpoint when the $path is cleared, you'll see it is being cleared by SwiftUI. Backtrace when the path is emptied: (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 * frame #0: 0x00000001043295c0 DoubleNav.debug.dylib`Navigation.path.setter(newValue=0 values) at ContentView.swift:86:22 frame #1: 0x00000001043296d0 DoubleNav.debug.dylib`key path setter for Navigation.path : Navigation at <compiler-generated>:0 frame #2: 0x000000019485b500 libswiftCore.dylib`Swift.NonmutatingWritebackBuffer.__deallocating_deinit + 132 frame #3: 0x0000000194a351c4 libswiftCore.dylib`_swift_release_dealloc + 28 frame #4: 0x0000000194a35bd4 libswiftCore.dylib`bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 156 frame #5: 0x00000001d2f5f584 SwiftUICore`closure #1 () -> () in SwiftUI.ObjectLocation.set(_: τ_0_1, transaction: SwiftUI.Transaction) -> () + 132 frame #6: 0x00000001d2f5f6b0 SwiftUICore`partial apply forwarder for closure #1 () -> () in SwiftUI.ObjectLocation.set(_: τ_0_1, transaction: SwiftUI.Transaction) -> () + 28 frame #7: 0x00000001d2801da8 SwiftUICore`generic specialization <()> of closure #1 () throws -> τ_0_0 in SwiftUI.withTransaction<τ_0_0>(SwiftUI.Transaction, () throws -> τ_0_0) throws -> τ_0_0 + 296 frame #8: 0x00000001d2f5f4d8 SwiftUICore`SwiftUI.ObjectLocation.set(_: τ_0_1, transaction: SwiftUI.Transaction) -> () + 336 frame #9: 0x00000001d2c42468 SwiftUICore`SwiftUI.LocationBox.set(_: τ_0_0.Value, transaction: SwiftUI.Transaction) -> () + 148 frame #10: 0x00000001d2c42c84 SwiftUICore`protocol witness for SwiftUI.Location.set(_: τ_0_0.Value, transaction: SwiftUI.Transaction) -> () in conformance SwiftUI.LocationBox<τ_0_0> : SwiftUI.Location in SwiftUI + 20 frame #11: 0x00000001d2c42e90 SwiftUICore`SwiftUI.ProjectedLocation.set(_: τ_0_1.Projected, transaction: SwiftUI.Transaction) -> () + 196 frame #12: 0x00000001d2c42468 SwiftUICore`SwiftUI.LocationBox.set(_: τ_0_0.Value, transaction: SwiftUI.Transaction) -> () + 148 frame #13: 0x00000001d2cf2fe8 SwiftUICore`SwiftUI.Binding.ScopedLocation.set(_: τ_0_0, transaction: SwiftUI.Transaction) -> () + 28 frame #14: 0x00000001d2c42468 SwiftUICore`SwiftUI.LocationBox.set(_: τ_0_0.Value, transaction: SwiftUI.Transaction) -> () + 148 frame #15: 0x00000001d2cf3190 SwiftUICore`function signature specialization <Arg[0] = Owned To Guaranteed> of SwiftUI.Binding.wrappedValue.setter : τ_0_0 + 32 frame #16: 0x00000001d2cf12c0 SwiftUICore`SwiftUI.Binding.wrappedValue.setter : τ_0_0 + 28 frame #17: 0x00000001d1d0e538 SwiftUI`closure #1 () -> () in SwiftUI.NavigationColumnState.popAllForSelectionChange(popReplacedRoots: Swift.Bool) -> SwiftUI.NavigationState.RequestResults + 524 frame #18: 0x00000001d281be58 SwiftUICore`partial apply forwarder for reabstraction thunk helper from @callee_guaranteed (@guaranteed Swift.Dictionary<__C.NSAttributedStringKey, Any>, @unowned __C._NSRange, @unowned Swift.UnsafeMutablePointer<ObjectiveC.ObjCBool>) -> () to @escaping @callee_guaranteed (@guaranteed Swift.Dictionary<__C.NSAttributedStringKey, Any>, @unowned __C._NSRange, @unowned Swift.UnsafeMutablePointer<ObjectiveC.ObjCBool>) -> () + 20 frame #19: 0x00000001d2b3b64c SwiftUICore`static SwiftUI.Update.dispatchActions() -> () + 1080 frame #20: 0x00000001d2b3ac4c SwiftUICore`static SwiftUI.Update.end() -> () + 108 frame #21: 0x00000001d18daf44 SwiftUI`closure #1 (Swift.Optional<Swift.UnsafeMutableRawPointer>, Swift.Double, Swift.UnsafePointer<__C._UIUpdateTiming>) -> () in static SwiftUI.UIKitUpdateCycle.addPreCommitObserver(() -> ()) -> () + 168 frame #22: 0x00000001d18dafbc SwiftUI`reabstraction thunk helper from @escaping @callee_guaranteed (@unowned Swift.Optional<Swift.UnsafeMutableRawPointer>, @unowned Swift.Double, @unowned Swift.UnsafePointer<__C._UIUpdateTiming>) -> () to @escaping @callee_unowned @convention(block) (@unowned Swift.Optional<Swift.UnsafeMutableRawPointer>, @unowned Swift.Double, @unowned Swift.UnsafePointer<__C._UIUpdateTiming>) -> () + 64 frame #23: 0x0000000185030388 UIKitCore`_UIUpdateSequenceRun + 76 frame #24: 0x00000001859d22e8 UIKitCore`schedulerStepScheduledMainSection + 168 frame #25: 0x00000001859d1720 UIKitCore`runloopSourceCallback + 80 frame #26: 0x000000018041b324 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24 frame #27: 0x000000018041b26c CoreFoundation`__CFRunLoopDoSource0 + 172 frame #28: 0x000000018041a9d0 CoreFoundation`__CFRunLoopDoSources0 + 232 frame #29: 0x00000001804150b0 CoreFoundation`__CFRunLoopRun + 788 frame #30: 0x0000000180414960 CoreFoundation`CFRunLoopRunSpecific + 536 frame #31: 0x0000000190183b10 GraphicsServices`GSEventRunModal + 160 frame #32: 0x0000000185aa2b40 UIKitCore`-[UIApplication _run] + 796 frame #33: 0x0000000185aa6d38 UIKitCore`UIApplicationMain + 124 frame #34: 0x00000001d1e2eab4 SwiftUI`closure #1 (Swift.UnsafeMutablePointer<Swift.Optional<Swift.UnsafeMutablePointer<Swift.Int8>>>) -> Swift.Never in SwiftUI.KitRendererCommon(Swift.AnyObject.Type) -> Swift.Never + 164 frame #35: 0x00000001d1e2e7dc SwiftUI`SwiftUI.runApp<τ_0_0 where τ_0_0: SwiftUI.App>(τ_0_0) -> Swift.Never + 84 frame #36: 0x00000001d1b70c8c SwiftUI`static SwiftUI.App.main() -> () + 148 frame #37: 0x0000000104333df0 DoubleNav.debug.dylib`static DoubleNavApp.$main() at <compiler-generated>:0 frame #38: 0x0000000104333ea0 DoubleNav.debug.dylib`main at DoubleNavApp.swift:11:8 frame #39: 0x00000001048f9410 dyld_sim`start_sim + 20 frame #40: 0x000000010440e154 dyld`start + 2476 Thanks for any tips! Here's the code.
Topic: UI Frameworks SubTopic: SwiftUI
2
0
416
Jul ’25
SwiftUI lifecycle / CarPlay / data model
Is there a way to share a SwiftUI App's @Observable model into a CPTemplateApplicationSceneDelegate ? Is there an incantation to go from the UIApplicationDelegate via @UIApplicationDelegateAdaptor to the UISceneDelegate for CarPlay via a userInfo? I can't seem to figure it out. Otherwise I have to use a shared global, and I'd prefer not to have to do it this way. Any ideas? Thanks!
2
0
102
Jun ’25