Post

Replies

Boosts

Views

Activity

SwiftData model in Swift package
Hi, I am looking for information on how to setup a ModelContainer for a Swift app when the SwiftData model is located in a Swift package. Let's say the model code resides in a package called DomainModel. That package was added target's embedded content and the model types are used to init the model container using the modelContainer(for:) view modifier on the ContentView of the app. This crashes the app on startup with a EXC_BAD_ACCESS code=2. When copying the model code from the package directly into the app, the app starts just fine. I kindly ask for a code sample or any information about how to setup the model container when using a model from a Swift package. Thanks in advance and I am looking forward to replacing CoreData 🙂
6
0
2k
Jun ’23
Using NavigationStack in the details of a NavigationSplitView causes loss of navigation paths
In the executable code below I try to implement the main navigation view for an (iPadOS) app. The expected behaviour is as follows: A NavigationSplitView is used to present a sidebar to the user containing the main categories of the app If a user selects a category, in the detail view of the NavigationSplitView a NavigationStack is presented The navigation stack allows users to interact with the specific part of the app associated with the category by pushing other views on the navigation stack If a user switches goes to category A, pushes some views on A's NavigationStack, switches to category B and then switches back to category A, it is expected that the NavigationStack of category A contains all the views, the user pushed there earlier However, (4) is not working. Every time a user selects another category in the sidebar, the navigation paths of the associated NavigationStack becomes empty. For example, if a user pushes three views on the view stack of category A, then uses the sidebar to select category B, the navigation paths of category A become empty and the NavigationStack of category B is displayed. I kindly ask for help as I cannot find the issue in the code. The following code demonstrates the issue: import SwiftUI /// Add this view to your app to test the behavior. /// /// This view displays a sidebar with four entries (RootCategory enum). /// Each detail view has a NavigationStack that referes to one of the Routing /// state objects from the RootNavigation. /// /// The goal is that users can switch the categories in the sidebar without losing /// their navigation stack of their respective child view once they are going back /// to a previously selected category. /// /// However, this does not work because everytime a different categor is selected from /// the sidebar, the navigation paths of the ChildView's routing is emptied. (see line 82). struct RootNavigation: View { @StateObject var categoryOneRouting = Routing() @StateObject var categoryTwoRouting = Routing() @StateObject var categoryThreeRouting = Routing() @StateObject var categoryFourRouting = Routing() @State var navigationSelection: RootCategory? = .category1 var body: some View { NavigationSplitView { List(RootCategory.allCases, selection: $navigationSelection) { category in NavigationLink(category.name, value: category) } .navigationTitle("App Title") } detail: { switch navigationSelection { case .category1: ChildView(title: RootCategory.category1.name) .environmentObject(categoryOneRouting) case .category2: ChildView(title: RootCategory.category2.name) .environmentObject(categoryTwoRouting) case .category3: ChildView(title: RootCategory.category3.name) .environmentObject(categoryThreeRouting) case .category4: ChildView(title: RootCategory.category4.name) .environmentObject(categoryFourRouting) case nil: Text("Selection does not exist") } } } } struct ChildView: View { let title: String @EnvironmentObject var routing: Routing var body: some View { NavigationStack(path: $routing.routes) { VStack { Text(title) .navigationTitle(title) Button("Screen 1") { routing.routes.append(.subview1) } Button("Screen 2") { routing.routes.append(.subview2) } Button("Screen 3") { routing.routes.append(.subview3) } } .navigationDestination(for: Route.self) { route in Text(route.rawValue) } } .buttonStyle(.borderedProminent) } } class Routing: ObservableObject { @Published var routes: [Route] = [] { willSet { // when selecting another category in the sidebar, the navigation paths of // the currently visible NavigationStack will be set to empty. Why and how // can I prevent it from losing the navigation paths of NavigationStacks // that disappear? if newValue.isEmpty { print("Navigation paths just got emptied") } } } } enum RootCategory: Int, CaseIterable, Identifiable { case category1 case category2 case category3 case category4 var id: Int { self.rawValue } var name: String { switch self { case .category1: return "Category 1" case .category2: return "Category 2" case .category3: return "Category 3" case .category4: return "Category 4" } } } enum Route: String { case subview1 case subview2 case subview3 } #Preview { return RootNavigation() }
0
2
699
Jul ’23
searchable search bar loses input onSubmit or cancel
In the following example, every time a user submits or cancels the search, the entered text removed from the search bar. If a user wants to modify the serach expression (for example because of a typo) they have to enter the entire search expression again. In our app users enter a query in a domain specific query language in the search bar. These queries can become complex and users often want to refine the query after surveying previous results. Right now, users have to enter their previous search again if they want to modify it. How can I modify the example code in order to prevent the search expression to be removed from the search bar after submitting or canceling the search? import SwiftUI struct SomeView: View { @State private var searchExpression = "" @State private var isPresented = false init() { } var body: some View { NavigationStack { VStack { Text("some view") .searchable(text: $searchExpression, isPresented: $isPresented) .onSubmit(of: .search) { // dismissing the search bar will clear the text the from searchExpression var. This also happens if the user cancels the search. isPresented = false } } } } } #Preview { SomeView() } Please note that I intentionally did not use the @Environment(\.dismissSearch) variable because it is not available in the SomeView. The described behavior is the same when using a more complex view hierarchy that uses the environment varaible to dismiss the search bar.
1
0
985
Jul ’23
Xcode 15 beta 7 Previews building issue
Summary When trying to display SwiftUI previews, building the previews may fail with the following error: Linking failed: linker command failed with exit code 1 (use -v to see invocation) ld: warning: search path '/Applications/Xcode.app/Contents/SharedFrameworks-iphonesimulator' not found ld: warning: Could not find or use auto-linked framework 'CoreAudioTypes': framework 'CoreAudioTypes' not found Note that may app does not use CoreAudioTypes. Observation This issue seems to occur when two conditions are met: The SwiftUI view must be located in a Swift Package Somewhere in either the View or the #Preview a type from another package has to be used. Say I have to packages one named Model-package and one named UI-Package. The UI-Package depends on the Model-Package. If I have a SwiftUI view in the UI-Package that uses a type of the Model-Package either in the View itself or in the #Preview, then the described error occurs. If I have a View in the UI-package that does not use a type of the Model-Package anywhere in its View or #Preview then the SwiftUI Preview builds and renders successful. I created a bug report: FB13033812
35
11
28k
Aug ’23
ModelContainer causes errors depending on the order in which configurations are supplied
Dear community, I am looking for help with an issue that is puzzling me regarding the creation of a SwiftData ModelContainer. I have a ModelContainer that holds some model types that are stored using two different configurations: let fullSchema = Schema([TypeA.self, TypeB.self]) let configurationA = ModelConfiguration(schema: Schema([TypeA.self]), url: "url/to/file/in/app-support/dir") let configurationB = ModelConfiguration(schema: Schema([TypeB.self]), url: "url/to/another/file/in/app-support/dir") let modelContainer = ModelContainer(for: fullSchema, configurations: configurationA, configurationB) // (1) read on I add this container to my view hierarchy using the .modelContainer(modelContainer) view modifier. In on of my views of the app I use a @Query to access objects of type TypeB like this. @Query(sort: \TypeB.someAttribute, order: .reverse) private var arrayOfB: [TypeB] Accessing the view in my app will cause the app to crash with the error: Thread 1: "NSFetchRequest could not locate an NSEntityDescription for entity name 'TypeB'" Now, if I reverse the order in which i specify the configuration for the model container in the line marked // (1) above to let modelContainer = ModelContainer(for: fullSchema, configurations: configurationB, configurationA) the query resolves successfully without crashes. I am looking for information on why the order of the configuration might matter and how to fix this behavior. Please note that because the app is in early development, I do not have objects of type TypeA implemented yet and cannot verify if this behvaior occurrs with these types, too. Edit: This behavior is also true for queries for TypeA. They will not crash the app if the configuration for TypeA is the first configuration passed to the ModelContainer.
1
2
902
Oct ’23
BGAppRefreshTask behavior when user disables Background App Refresh
Hello community, I am looking for information about how BGAppRefreshTasks behave in case a user has disabled the Background App Refresh for my app in the Settings app. Does disabling Background App Refresh for my app means, that my registered and schedules tasks will never run or will the system execute scheduled tasks when the app is in the foreground and has priority on system resources? My app is dependent on the data downloaded with an BGAppRefreshTask and I want to know if I have to implement alternative ways to download data, for example when the scene phase changes, if users restrict my app. Thanks for any information about this topic in advance!
1
0
863
Nov ’23
Content of ScrollView changes size while scrolling
Hi community, I have an issue where the content of a horizontal scroll view, embedded in a vertical scroll view, changes its' size while scrolling away from the initial scroll content. At some point the entire scroll content of the inner (horizontal) scroll view collapses in height. When scrolling back to the initial scroll content, the height of the scroll content is restored. Please see the attached view to reproduce the issue. Tested with Xcode 15.2 with Xcode Previews, iOS 17.2 Simulator and 17.2.1 on Device. /// This view demonstates a bug that causes the content of a /// nested ``ScrollView`` to collapse in on itself when the /// horizontal scroll view is being scrolled. /// The proper size of the scroll content is restored if the user /// scrolls to the leading position of the view again. struct CollapsedViewHierarchy: View { @State private var images: [CatImage] = [] var body: some View { NavigationStack { if images.isEmpty { ContentUnavailableView("Cats unavailable", systemImage: "cat", description: Text("Your cats are being fetched from the internet")) } else { ScrollView { Text("To reproduce this bug, scroll through the list of cats. At some point the content collapses in on itself. If you scroll back to the beginning of the list, the proper size will be restored.") .foregroundStyle(.secondary) ScrollView(.horizontal) { ScrollViewContent() } .contentMargins(12.0, for: .scrollContent) .scrollIndicators(.hidden) } .navigationTitle("Cats") .refreshable { images = try! await fetchImages() } } } .task { images = try! await fetchImages() } } private func ScrollViewContent() -> some View { LazyHStack { ForEach(images, id: \.self) { image in Tile(image: image) .containerRelativeFrame(.horizontal, count: 2, span: 2, spacing: 20.0) } } } private func Tile(image: CatImage) -> some View { VStack(alignment: .leading) { AsyncImage(url: image.url) { image in image .resizable() .aspectRatio(2.0, contentMode: .fill) .clipped() } placeholder: { Color.gray } .mask(RoundedRectangle(cornerRadius: 12)) Text(image.id) .bold() Text(image.url.absoluteString) .font(.footnote) .foregroundStyle(.secondary) } } private func fetchImages() async throws -> [CatImage] { let metadataUrl = URL(string: "https://api.thecatapi.com/v1/images/search?limit=20")! let (data, _) = try await URLSession.shared.data(from: metadataUrl) let decoder = JSONDecoder() return try decoder.decode([CatImage].self, from: data) } } fileprivate struct CatImage: Codable, Hashable { let id: String let url: URL } #Preview { CollapsedViewHierarchy() } Why does the scroll content (cat pictures in the example view) changes size while scrolling? This is not related with the loading state of the async image as it also occurs after all images have been loaded? I greatly appreciate any feedback and suggstions how to fix this!
0
1
699
Jan ’24
Privacy Accessed API reason 1C8F.1 not available in Xcode 15.2
Hi community, i am updating the PrivacyInfo file of our app. Our app has multiple extensions, some of them accessing the UserDefaults. Because of that I want to set the Privacy Accessed API Type to a value of 1C8F.1. However, from the drop down menu for possible values, the value for code 1C8F.1 is not available. It does not show up in the list. Can I just manually edit the underlying xml file and just add <string>1C8F.1</string> to the array for NSPrivacyAccessedAPITypeReasons and expect it to work or will this cause issues when submitting our app to the app review?
4
0
2.9k
Jan ’24
Looking for tutorial on how to use SwiftData correctly in background threads
Hello community, I am in search of a tutorial that comprehensively explains the proper utilization of SwiftData for updating model data in a background thread. From my understanding, there is extensive coverage on creating a model and loading model data into a view, likely due to Apple's detailed presentation on this aspect of SwiftData during WWDC23. Nevertheless, I am encountering difficulties in finding a complete tutorial that addresses the correct usage of SwiftData for model updates in a background thread. While searching the web, I came across a few discussions on Stack Overflow and this forum that potentially provide an approach. However, they were either incomplete or proved ineffective in practical application. I would greatly appreciate any links to tutorials that thoroughly cover this topic.
1
0
2.0k
Feb ’24