Post

Replies

Boosts

Views

Activity

SwiftData & CloudKit: getting info about current updates
I have an app which uses SwiftData and CloudKit all works fine and well. Now I wanted to implement a feature which lets the user know that there are data incoming from the cloud and they have to wait a little bit for the data to show up. Furthermore my app needs to do some data sanitation when it starts up. This sanitation should only be done after the CloudKit updates are processed. So is there a way that my app can know when CloudKit is doing updates and when it is finished? I was looking for some kind of notification but couldn’t find any info on that. I don’t need to know which data are updated or process the data. I just want to get notified when a sync starts and when it has ended. Actually it would suffice to know when a sync is finished.
2
0
431
Sep ’24
NavigationLinks embedded in a List getting clipped in tvOS
I want to recreate an user experience like in the settings app in tvOS. Therefore I have a HStack with some content on the left side and a List of NavigationLinks on the right side. However a focused link in the list gets clipped on the left side. I tried paddings and spacers and what not, but nothing helped. Is this is a bug or am I missing something? Here is some example code to show the problem: struct ContentView: View { var body: some View { NavigationStack { HStack(spacing: 20) { VStack(alignment: .center) { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } List { ForEach(SomeViewEnum.allCases) { someView in NavigationLink(someView.rawValue, value: someView) } } .navigationDestination(for: SomeViewEnum.self) { someView in Text(someView.rawValue) } } } } } And a screenshot to show the problem:
1
1
627
Oct ’23
tvOS app icon is not used in a multiplatform app
I have a multiplatform app where I support iOS, macOS and tvOS. There is one target which supports it all. In my assets catalog I have the AppIcon entry which holds the app icon for iOS and macOS. This works as expected. However the tvOS app icon is ignored. I added an "tvOS App Icon & Top Shelf Image" asset to my asset catalog and filled it with my icons for tvOS. Then I added it in the target’s general settings App Icon entry under App Icons and Launch Screen like shown in the screenshot. What am I missing? What needs to be done to make this work?
4
0
1.1k
Sep ’23
NavigationView is messing up with .prefersDefaultFocus(in:) in tvOS
I am building a tvOS app which divides the screen into two parts horizontally. Both sides have buttons. I want a certain button on the right side to have focus. To achieve that I am marking the enclosing HStack with .focusScope() and then use .prefersDefaultFocus(in:) on the button which should have focus. This works fine, even if I add another focus scope inside (see source code). But as soon as I wrap the HStack in a NavigationView it falls apart. The scope is not set as intended, instead the left view always gets the focus. Am I missing something? Is this intended? I’m a little lost right now. I am targeting tvOS 16.4 and using Xcode 14.3.1. Fun fact: The simulator view inside Xcode displays the view correctly. The simulator and an actual device are not. Here is an example to showcase that: struct ContentView: View { @Namespace private var mainNamespace @Namespace private var rightNamespace var body: some View { // NavigationView { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundColor(.accentColor) Text("Hello, world!") HStack { VStack { Button("left") {} } VStack { Button("right 1") {} Button("right 2") {} .prefersDefaultFocus(in: rightNamespace) } .focusScope(rightNamespace) .prefersDefaultFocus(in: mainNamespace) } .focusScope(mainNamespace) .padding(.top, 50) } .padding() // } } }
1
0
687
Aug ’23
Implement preferences menu entry in MacCatalyst
I have an app which uses SwiftUI and Mac Catalyst. When running on a Mac I want to provide a preferences menu entry with the usual keyboard shortcut Command + ,. An implementation via the Settings bundle is out of question since my preferences are too complex for this. Here is a reduced example of my implementation: import SwiftUI @main struct PreferencesMenuTestApp: App { @UIApplicationDelegateAdaptor private var appDelegate: AppDelegate var body: some Scene { WindowGroup { ContentView() } } } class AppDelegate: UIResponder, UIApplicationDelegate { override func buildMenu(with builder: UIMenuBuilder) { let preferencesCommand = UIKeyCommand(title: "Preferences…", action: #selector(showPreferences), input: ",", modifierFlags: .command) // let preferencesCommand = UIAction(title: "Preferences…") { action in // debugPrint("show preferences") // } let menu = UIMenu(title: "Preferences…", options: .displayInline, children: [preferencesCommand]) builder.insertSibling(menu, afterMenu: .about) } @objc func showPreferences() { debugPrint("show preferences") } } The problem is that the menu entry is disabled. Obviously the provided selector is not recognised. When I mark the AppDelegate with @main, then the menu entry is enabled. Of course then the app's window is empty. When I switch to the UIAction implementation (the out commented code) it works fine. But since one cannot provide a keyboard shortcut for UIActions this is not a good solution. What am I missing? How would one implement a preferences menu entry that actually works?
3
0
1k
Aug ’23
#Preview macro can’t find member which is added via an extension
For my app I use a struct for my CoreData persistence controller like so: struct PersistenceController { static var shared = PersistenceController() // more code omitted for brevity } As a development asset I made an extension to the PersistenceController to provide a special instance for previews with some sample data. extension PersistenceController { static var preview: PersistenceController = { let result = PersistenceController(inMemory: true) // create some sample data return result }() } Now I want to use the special preview instance with the new #Preview macro in Xcode beta 2. The deployment target for the app is set to iOS 17. #Preview { var context = PersistenceController.preview.container.viewContext return SpanList() .preferredColorScheme(.light) .environment(\.managedObjectContext, context) } But the preview fails to build due to the following error: Type 'PersistenceController' has no member 'preview'. My experiments show that everything I add to the PersistenceController via an extension is not available in the preview macro. This is no matter where I place the extension. Even when it’s placed in the same file as the PersistenceController itself. Am I missing something or is this intended behaviour?
1
0
1k
Jun ’23
Understanding SwiftUI and control flow
I’ve got this simple view and it doesn’t work as expected. When clicking the button a new Eventis created and the flag used as binding for a sheet is set to true. This should show the sheet and give the sheet access to the Event. Instead I get the error message Fatal error: Unexpectedly found nil while unwrapping an Optional value. I can’t see the problem. As far as I see this the tmpEvent variable should have a valid value once the sheet is presented. import SwiftUI struct TestView: View {   @Environment(\.managedObjectContext) private var viewContext   @State private var showingSheet = false   @State private var tmpEvent: Event?     var body: some View {     VStack {       Button(action: showSheet) {         Label("Add event", systemImage: "plus.circle")       }     }     .sheet(isPresented: $showingSheet) {       Text("event title: \(tmpEvent!.descriptionString)"). // Fatal error occurs here     }   }    private func showSheet() {     tmpEvent = Event(context: viewContext)     showingSheet = true   } } Any ideas why this isn’t working?
1
0
723
Aug ’21
SwiftUI app crashes when deleting an object from a list
In my app I’ve got a list view and a view for displaying the rows in the list. When I delete an item from that list the app crashes in the row view stating an illegal access. I don’t understand why the row view is rendered again for the deleted item. The list view: import Foundation import SwiftUI struct SpanList: View {   @Environment(\.managedObjectContext) private var viewContext    @FetchRequest(     sortDescriptors: [ NSSortDescriptor(keyPath: \Span.startDate,                                         ascending: true) ],     predicate: NSPredicate(format: "isArchived != YES"),     animation: .default)   private var activeSpans: FetchedResults<Span>   var body: some View {     NavigationView {       VStack {         List {           Section(header: ActiveSectionHeader()) {             ForEach(activeSpans, id: \.id) { item in               NavigationLink(destination: getConfiguredEditView(span: item)) {                 SpanRow(span: item)               }               .buttonStyle(PlainButtonStyle())               .listRowBackground(item.color.opacity(0.5))             }             .onDelete(perform: deleteItems)           }         }         .listStyle(GroupedListStyle())       }     }   }   private func getConfiguredEditView(span: Span) -> some View {     EditSpan(span: span)       .navigationTitle("Edit Span")       .navigationBarTitleDisplayMode(.inline)   }   private func deleteItems(offsets: IndexSet) {     withAnimation {       // Necessary due to a bug in the framework. Without this the app crashes       // with a bug stating multiple access from different threads is not       // allowed.       viewContext.perform {         offsets.map {           activeSpans[$0]         }.forEach(viewContext.delete)         PersistenceController.shared.save()       }     }   } } The row view: import SwiftUI import CoreData struct SpanRow: View {   @ObservedObject var span: Span   var body: some View {     HStack(alignment: .center) {       VStack(alignment: .leading) {         HStack {           if span.showOnStartPage && !span.isArchived {             Image(systemName: "paperclip")           }           Text(span.descriptionString)             .font(.headline)             .fontWeight(.bold)         }         Spacer()         HStack { // It crashes here           Text("\(span.startDate, formatter: dateFormatter)")           Text("–")           if span.usesEndDate {             Text("\(span.endDate, formatter: dateFormatter)")           } else {             Image(systemName: "infinity")           }         }       }       Spacer()       if let daysSinceStart = span.daysSinceStart {         VStack {           Text("\(daysSinceStart)")             .font(.largeTitle)             .fontWeight(.semibold)           Text("days")         }       }     }     .padding(.vertical, 5)   }   private let dateFormatter: DateFormatter = {     let formatter = DateFormatter()     formatter.dateStyle = .medium     return formatter   }() } What am I missing?
0
0
914
Jul ’21