I've run into a problem with the following setup:
I have a Core Data database with parent objects with a relationship to many child objects. I have a main view using SwiftUI FetchedResults that displays the parent objects in a list and properties about the child objects. I have a second view that lets you change properties of the child objects.
The parent object has the property: name (string). The child object has: name (string) and star (bool). On the main view I display a list of parent objects and how many child objects are starred. On the second view I update if a child object is starred. Upon updating the property on the second view and saving, the first view does not update until you relaunch the app.
Here is the main view:
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(sortDescriptors: [SortDescriptor(\.name)])
private var parents: FetchedResults<Parent>
@State private var editingParent: Parent?
var body: some View {
List {
ForEach(parents) { parent in
VStack(alignment: .leading) {
Text(parent.name ?? "No Name")
Text("\(parent.children!.count) children")
Text("\(getNumberOfStar(parent: parent)) Stared")
}
.onTapGesture {
editingParent = parent
}
}
}
.sheet(item: $editingParent) { parent in
ChildrenView(parent: parent)
}
Button {
PersistenceController.shared.saveParent(name: "New Parent")
} label: {
Text("Add Parent")
}.padding()
Button {
parents.forEach { parent in
PersistenceController.shared.delete(parent: parent)
}
} label: {
Text("Delete All")
}.padding()
}
//this function does not get called when the database changes
func getNumberOfStar(parent: Parent) -> Int {
let children = parent.children!.allObjects as! [Child]
let starred = children.filter({$0.star == true})
return starred.count
}
}
This is the child view:
@FetchRequest var children: FetchedResults<Child>
var parent: Parent
init(parent: Parent) {
self.parent = parent
_children = FetchRequest<Child>(sortDescriptors: [], predicate: NSPredicate(format: "parent = %@", parent))
}
var body: some View {
List {
ForEach(children) { child in
HStack {
Text(child.name ?? "No Name")
Text(child.star ? "⭐️" : "")
Spacer()
Button {
PersistenceController.shared.updateStar(child: child)
} label: {
Text("Toggle Star")
}
}
}
}
Button {
PersistenceController.shared.saveChild(name: "New Child", parent: parent)
} label: {
Text("Add Child")
}
}
}
This is the Persistence Controller:
static let shared = PersistenceController()
let container: NSPersistentContainer
init(inMemory: Bool = false) {
container = NSPersistentContainer(name: "Model")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
func save() {
let viewContext = container.viewContext
do {
try viewContext.save()
} catch {
/**
Real-world apps should consider better handling the error in a way that fits their UI.
*/
let nsError = error as NSError
fatalError("Failed to save Core Data changes: \(nsError), \(nsError.userInfo)")
}
}
func saveParent(name: String) {
let newParent = Parent(context: container.viewContext)
newParent.name = name
save()
}
func saveChild(name: String, parent: Parent) {
let newChild = Child(context: container.viewContext)
newChild.name = name
newChild.parent = parent
newChild.star = false
save()
}
func updateStar(child: Child) {
child.star.toggle()
save()
}
func delete(parent: Parent) {
let viewContext = container.viewContext
viewContext.delete(parent)
save()
}
}
Finally here is the App struct:
struct Core_Data_Child_Save_ExampleApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Posts under SwiftUI tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm working with the FamilyControls API and am running into an issue with sharing ActivityTokens between devices in the same family sharing network.
Based on this documentation, ActivityTokens are only accessible and readable by other members in the family sharing network. My app is based on the idea that if one user selects the Games category in the FamilyActivityPicker, then this token can be shared with another device in the same family-sharing network and this other device can read and display the category.
So my question is:
If a user in the network selects an activity category in the FamilyActivityPicker, can this category token be shared, read, and used by another user in the family-sharing network?
Is there any way to prevent the keyboard from bouncing when changing the focus state in onSubmit? Or is it not recommended to change focus in onSubmit?
The following view is setup so that pressing return on the keyboard should cause focus to move between the TextFields.
struct TextFieldFocusState: View {
enum Field {
case field1
case field2
}
@FocusState var focusedField: Field?
var body: some View {
Form {
TextField("Field 1", text: .constant(""))
.focused($focusedField, equals: .field1)
.onSubmit { focusedField = .field2 }
TextField("Field 2", text: .constant(""))
.focused($focusedField, equals: .field2)
.onSubmit { focusedField = .field1 }
}
}
}
I would expect that when pressing return, the keyboard would say on screen.
What actually happens is the keyboard appears to bounce when the return key is pressed (first half of gif). I assume this is because onSubmit starts dismissing the keyboard then setting the focus state causes the keyboard to be presented again.
The issue doesn't occur when tapping directly on the text fields to change focus (second half of gif).
I'm trying to push a SwiftUI view from UIKit using UIHostingController. In the new view there is a button in the right side of the navigation bar, but it pops after the push animation. I can't make it appear with an animation like in a normal UIViewController.
I tried adding the button in the navigationItem of the hosting controller and in the toolbar of the SwiftUI but none gives a smooth animation.
I've made a small test and this are the results.
This is the code:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = "Home"
}
@IBAction func buttonNavPressed(_ sender: Any) {
let vc = UIHostingController(rootView: ContentView())
vc.navigationItem.title = "NavItem Button"
vc.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(sayHello))
navigationController?.pushViewController(vc, animated: true)
}
@IBAction func buttonSwiftUIPressed(_ sender: Any) {
let vc = UIHostingController(rootView: ContentViewWithButton())
navigationController?.pushViewController(vc, animated: true)
}
@objc func sayHello() {
print("Hello")
}
}
struct ContentView: View {
var body: some View {
Text("No button")
}
}
struct ContentViewWithButton: View {
var body: some View {
Text("With button")
.navigationTitle("SwuitUI W Button")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button(action: { print("Hello") },
label: { Image(systemName: "camera") }
)
}
}
}
}
There is any workaround to this problem?
I'm running into an issue with using .topBarTrailing placement for a toolbar item. The app fails to launch (crashes) with this placement. The following view works fine with any other placement (other than .topBarLeading).
What am I doing wrong?
var body: some View {
NavigationStack {
Text("Overview")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
// noop
} label: {
Label("Add", systemImage: "plus")
}
}
}
.navigationTitle("Overview")
.navigationBarTitleDisplayMode(.inline)
}
}
I've opted to use .confirmationAction as a workaround, which works fine. It also positions the toolbar item in the same place on the view as the .topBarTrailing placement would.
I'm using Xcode version 15.0 and targeting WatchOS 10.
Verbose error output when trying to run the app in the simulator:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Layout requested for visible navigation bar, <PUICStackedNavigationBar: 0x100e1e8d0; baseClass = UINavigationBar; frame = (0 0; 198 60); opaque = NO; autoresize = W; layer = <CALayer: 0x60000027c280>> delegate=0x101877800 standardAppearance=0x60000261cc60, when the top item belongs to a different navigation bar. topItem = <UINavigationItem: 0x100f11230> title='Overview' style=navigator, navigation bar = <PUICStackedNavigationBar: 0x100f22a80; baseClass = UINavigationBar; frame = (0 0; 198 60); opaque = NO; autoresize = W; layer = <CALayer: 0x6000002887c0>> delegate=0x101069600 standardAppearance=0x60000261f3c0, possibly from a client attempt to nest wrapped navigation controllers.'
My app's top crash is a mysterious one and I can't seem to figure it out. It always crashes on
_objc_fatalv(unsigned long long, unsigned long long, char const*, char*)
But the stack traces include a few different possible culprits like
NavigationBridge_PhoneTV.pushTarget(isDetail:)
UIKitNavigationBridge.update(environment:)
ViewRendererHost.updateGraph()
UIScrollView(SwiftUI) _swiftui_adjustsContentInsetWhenScrollDisabled
Crash reports here:
2024-12-02_21-37-21.7864_-0600-1e78918e5586309b96a1c2986ff722778dec8a77.crash
2024-12-02_19-18-29.1251_-0500-a2fc5513683cd647b4adbbe03cc59e4a09237b5f.crash
2024-12-01_11-59-09.8888_-0500-9eb224ab3d37e76d0b966ea83473f584ac3bbe18.crash
2024-11-28_17-17-38.4808_+0100-46208989f016fbefd16c30873a88c2ef61dd91a1.crash
Hopefully someone here can shed some light. For context we use a lot of UIHostingController's to bridge our SwiftUI views.
Hey there! My app's top crash is a mysterious one and I can't seem to figure it out. Hopefully someone here can shed some light. For context we use a lot of UIHostingController's to bridge our SwiftUI views.
Crashed: com.apple.main-thread
0 libsystem_kernel.dylib 0x13ec4 __abort_with_payload + 8
1 libsystem_kernel.dylib 0x33bec abort_with_payload_wrapper_internal + 104
2 libsystem_kernel.dylib 0x33b84 abort_with_payload_wrapper_internal + 30
3 libobjc.A.dylib 0xbea0 _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 116
4 libobjc.A.dylib 0xbe2c _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 30
5 libobjc.A.dylib 0xb040 weak_register_no_lock + 396
6 libobjc.A.dylib 0xa9bc objc_initWeak + 440
7 libswiftCore.dylib 0x43abe8 swift_unknownObjectWeakInit + 92
8 SwiftUI 0xf40cc NavigationBridge_PhoneTV.pushTarget(isDetail:) + 376
9 SwiftUI 0xf9490 UIKitNavigationBridge.update(environment:) + 1060
10 SwiftUI 0x5b51c UIHostingController._update(environment:) + 156
11 SwiftUI 0x96a30 _UIHostingView.updateEnvironment() + 3484
12 SwiftUICore 0xa0d0a0 closure #1 in ViewRendererHost.updateGraph() + 364
13 SwiftUICore 0xa0ca08 ViewRendererHost.updateGraph() + 180
14 SwiftUICore 0xa0d7d4 closure #1 in ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 368
15 SwiftUICore 0xa0b0d4 ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 556
16 SwiftUI 0x8f1634 UIHostingViewBase.renderForPreferences(updateDisplayList:) + 168
17 SwiftUI 0x8f495c closure #1 in UIHostingViewBase.requestImmediateUpdate() + 72
18 SwiftUI 0xcc700 thunk for @escaping @callee_guaranteed () -> () + 36
19 libdispatch.dylib 0x2370 _dispatch_call_block_and_release + 32
20 libdispatch.dylib 0x40d0 _dispatch_client_callout + 20
21 libdispatch.dylib 0x129e0 _dispatch_main_queue_drain + 980
22 libdispatch.dylib 0x125fc _dispatch_main_queue_callback_4CF + 44
23 CoreFoundation 0x56204 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 16
24 CoreFoundation 0x53440 __CFRunLoopRun + 1996
25 CoreFoundation 0x52830 CFRunLoopRunSpecific + 588
26 GraphicsServices 0x11c4 GSEventRunModal + 164
27 UIKitCore 0x3d2eb0 -[UIApplication _run] + 816
28 UIKitCore 0x4815b4 UIApplicationMain + 340
29 (MyApp) 0x1a7e0 main + 8 (main.swift:8)
30 ??? 0x1bf97eec8 (Missing)
// Füge OrderRow hinzu
struct OrderRow: View {
let order: Order
var body: some View {
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("Tisch \(order.tableNumber)")
.font(.headline)
Spacer()
Text(order.status.rawValue)
.font(.caption)
.padding(.horizontal, 8)
.padding(.vertical, 4)
.background(order.status.color.opacity(0.2))
.foregroundColor(order.status.color)
.cornerRadius(8)
}
Text(order.timestamp, style: .time)
.font(.caption)
.foregroundColor(.gray)
ForEach(order.items) { item in
Text("\(item.quantity)x \(item.item.name)")
.font(.subheadline)
}
HStack {
Spacer()
Text(String(format: "%.2f €", order.totalAmount))
.bold()
}
}
.padding()
.background(Color.white)
.cornerRadius(12)
.shadow(radius: 2)
}
}
struct MenuItemRow: View {
let item: MenuItem
var body: some View {
HStack {
Text(item.name)
.font(.headline)
Spacer()
Text(String(format: "%.2f €", item.price))
.font(.subheadline)
}
.padding()
}
}
struct MenuItemsView: View {
@Binding var selectedItems: [OrderItem]
@Environment(.dismiss) private var dismiss
func filteredItems(for category: MenuCategory) -> [MenuItem] {
return sampleMenuItems.filter { $0.category == category }
}
func addItemToOrder(_ item: MenuItem) {
if let index = selectedItems.firstIndex(where: { $0.item.id == item.id }) {
selectedItems[index].quantity += 1
} else {
selectedItems.append(OrderItem(item: item, quantity: 1))
}
}
var body: some View {
NavigationView {
List {
ForEach(MenuCategory) { category in
Section(header: Text(category.rawValue)) {
let filteredItems = sampleMenuItems.filter
ForEach(filteredItems) { item in
}
MenuItemRow(item: sampleMenuItems.filter) {
addItemToOrder
}
}
}
}
}
.navigationTitle("Menü")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Fertig") {
dismiss()
}
}
}
}
}
}
// Sample Menü-Items
let sampleMenuItems: [MenuItem] = [
MenuItem(name: "Cola", description: "0,33l", price: 3.50, category: .drinks, image: "cola"),
MenuItem(name: "Sprite", description: "0,33l", price: 3.50, category: .drinks, image: "sprite"),
MenuItem(name: "Bier", description: "0,5l", price: 4.00, category: .drinks, image: "beer"),
MenuItem(name: "Nachos", description: "mit Käsesauce", price: 5.50, category: .snacks, image: "nachos"),
MenuItem(name: "Pommes", description: "mit Ketchup", price: 4.50, category: .food, image: "fries"),
MenuItem(name: "********", description: "alkoholfrei", price: 6.50, category: .specials, image: "********")
]
struct NewEventView: View {
var body: some View {
Text("New Event")
}
}
struct EventManagementView: View {
var body: some View {
Text("Event Management")
}
}
struct OrderRow: View {
var order: String
var body: some View {
Text("Order: (order)")
}
}
#Preview {
ContentView()
}
How can I make this appear inside the NavigationSplitView toolbar?
It doubles up with the close button and takes up space...
App Main view
import SwiftUI
@main
struct WritingApp: App
{
var body: some Scene
{
DocumentGroup(newDocument: WritingAppDocument())
{ file in
StoryView(document: file.$document)
}
}
}
Story view
import SwiftUI
struct StoryView: View
{
@Binding var document: WritingAppDocument
@State private var isShowingSheet = false
@FocusState private var isFocused: Bool
var body: some View
{
NavigationSplitView
{
Text("Sidebar")
}
detail:
{
HStack
{
Text("Detail View")
}
.toolbar
{
ToolbarItem
{
Button("Book", systemImage: "book")
{
}
}
ToolbarItem
{
Button("Circle", systemImage: "circle")
{
}
}
}
}
}
}
When working with SwiftUI TabView and ScrollView at root level with scrollPosition(id:anchor:), after tapping on Tab item the ScrollView scrolls to the top, but the scroll position ID does not get updated.
struct ContentView: View {
@State var positionID: Int?
var body: some View {
TabView {
Tab("Test", systemImage: "house") {
ScrollView(.vertical) {
LazyVStack(pinnedViews: [.sectionHeaders]) {
ForEach(0 ... 100, id: \.self) { index in
Text("\(index)")
}
}
.scrollTargetLayout()
}
.scrollPosition(id: $positionID, anchor: .top)
.onChange(of: positionID) { _, newValue in
print(newValue)
}
}
}
}
}
FB15964820
Hi, I've created an carousel using an Tabview component and it is divided in pages, each page has 7 items. Now we wan't to load the carousel page by page, but whenever I updated the list which Tabview uses to render, it flickers because it rerenders previous elements.
I've tried to use a scroll view for this but this app is for Vision Pro and I added some 3D transformations (position/rotation) to the cards from the tabview and when I added this in the scrollview they becom unclickable.
Do you have any sugestions what can I do?
Bellow is a sample of the code, I put [items] just to suggest there is a list.
VStack (spacing: 45) {
TabView(selection: $navigationModel.carouselSelectedPage) {
let orderedArtist = [items]
let numberOfPages = Int((Double(orderedArtist.count) / Double(cardsPerPage)).rounded(.up))
if(numberOfPages != 1){
Spacer().tag(-1)
}
ForEach(0..<numberOfPages, id: \.self) { page in
LazyHStack(alignment: .top, spacing: 16){
ForEach(0..<cardsPerPage, id: \.self) { index in
if(page * cardsPerPage + index < orderedArtist.count){
let item = orderedArtist[page * cardsPerPage + index]
GeometryReader{proxy in
I am currently implementing an authentication function using ASWebAuthenticationSession to log in with my Instagram account.
I set a custom scheme for the callbackURLScheme, but
In the Instagram redirect URL
I was told I can't use a custom scheme.
What should I do with the callbackURLScheme of the ASWebAuthenticationSession in this case?
Hello everyone! I've encountered an issue related to SwiftUI and StoreKit. Please take a look at the SwiftUI code snippet below:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
List {
NavigationLink {
Page1()
} label: {
Text("Go to Page 1")
}
}
}
}
}
struct Page1: View {
@Environment(\.dismiss) private var dismiss
@State private var string: String = ""
var body: some View {
List {
NavigationLink {
List {
Page2(string: $string)
.simpleValue(4)
}
} label: {
Text("Tap this button will freeze the app")
}
}
.navigationTitle("Page 1")
}
}
struct Page2: View {
@Binding var string: String?
init(string: Binding<String>) {
self._string = Binding(string)
}
var body: some View {
Text("Page 2")
}
}
extension EnvironmentValues {
@Entry var simpleValue: Int = 3
}
extension View {
func simpleValue(_ value: Int) -> some View {
self.environment(\.simpleValue, value)
}
}
This view runs normally until the following symbol is referenced anywhere in the project:
import StoreKit
extension View {
func notEvenUsed() -> some View {
self.manageSubscriptionsSheet(isPresented: .constant(false))
}
}
It seems that once the project links the View.manageSubscriptionsSheet(isPresented:) method, regardless of whether it's actually used, it causes the above SwiftUI view to freeze.
Steps to Reproduce:
Clone the repository: https://github.com/gongzhang/StrangeFreeze
Open it in Xcode 16 and run on iOS 17-18.1
Navigate to the second page and tap the button, causing the app to freeze.
Remove manageSubscriptionsSheet(...), then everything will work fine
I'm going through the tutorial and have copied the code given to me verbatim, but I am still getting the error 'Value of type 'SettingsView' has no member 'tabItem'. Not sure what to do. Code is below.
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
TabView {
ContentView()
.tabItem {
Label("Journal", systemImage: "book")
}
SettingsView()
.tabItem { *error is here - Value of type 'SettingsView' has no member 'tabItem'
Label("Settings", systemImage: "gear")
}
}
}
}
}
This problem will occur in Xcode 16 beta and iOS 18 beta, are there any changes to the function of highPriorityGesture in iOS 18?
Example code is:
import SwiftUI
struct ContentView: View {
@State private var dragable: Bool = false
@State private var dragGestureOffset: CGFloat = 0
var body: some View {
ZStack {
ScrollViewReader { scrollViewProxy in
ScrollView(showsIndicators: false) {
cardList
.padding(.horizontal, 25)
}
}
}
.highPriorityGesture(dragOffset)
}
var cardList: some View {
LazyVStack(spacing: 16) {
Text("\(dragGestureOffset)")
.frame(maxWidth: .infinity)
.padding(.vertical,8)
.background {
RoundedRectangle(cornerRadius: 8)
.fill(.gray)
}
//Display 100 numerical values in a loop
ForEach(0..<100) { index in
Text("\(index)")
.frame(maxWidth: .infinity)
.padding(.vertical,8)
.background {
RoundedRectangle(cornerRadius: 8)
.fill(.gray)
}
}
}
}
var dragOffset: some Gesture {
DragGesture()
.onChanged { value in
if abs(value.translation.width) > 25 {
dragable = true
dragGestureOffset = value.translation.width
}
}
.onEnded { value in
if abs(value.translation.width) > 25 {
dragable = false
dragGestureOffset = 0
}
}
}
}
If I add items at the root level, this code works, but if I attempt to add a child to any item, it runs an infinite loop where it goes from the AddItemView back to the SubItemView and starts all over. I suspect it has something to do with the Predicate in SubItemView, but the debugger is crap, so I'm just guessing.
Minimal code:
@Model
final class Item {
var id: String
var name: String
var children: [Item] = []
@Relationship(deleteRule: .cascade) var parent: Item?
init(name: String, parent: Item?, id: String = UUID().uuidString) {
self.name = name
self.parent = parent
self.id = id
}
}
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query(
filter: #Predicate<Item> {
item in
item.parent == nil
}, sort: \Item.name
) public var rootItems: [Item]
var body: some View {
NavigationStack {
List {
ForEach(rootItems) { item in
HStack {
NavigationLink ( destination: SubItemView(parent: item)) {
Text(item.name) }
}
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
NavigationLink(destination: AddItemView(itemParent: nil)) {
Text("Add To Do")
}
}
}
}
}
}
struct SubItemView: View {
@Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) private var modelContext
@State var parent: Item
@State private var todo: String = ""
@State var selectedDate = Date()
@State var showPicker: Bool = false
@Query var children: [Item]
init(parent: Item) {
self.parent = parent
let parentID = parent.id
_children = Query(filter: #Predicate<Item> {
$0.parent.flatMap(\.id) == parentID && $0.parent.flatMap(\.id) != nil
}, sort: \Item.name )
}
var body: some View {
Form {
LabeledContent {
TextField("Name", text: $parent.name)
} label: {
Text("Name:")
}
}
Text("Parent: \(parent.name)\n")
NavigationStack {
Text("Child count: \(children.count)")
List(children) { child in
HStack {
if(child.children.isEmpty) {
Text(child.name)
NavigationLink ( destination: SubItemView(parent: child)) {
Text("").foregroundColor(.white).background(Color.blue)
}
.opacity(0)
.background(
Text("")
)
} else {
Text(child.name)
NavigationLink(destination: SubItemView(parent: child)) {
Text("")
}
}
}
}
}
.navigationTitle("Sub Items")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
NavigationLink(destination: AddItemView(itemParent: parent)) {
Text("Add To Do")
}
}
ToolbarItem {
Button("Save") {
try? modelContext.save()
dismiss()
}
}
}
}
}
struct AddItemView: View {
@Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) private var context
@State var itemParent: Item?
@State private var name = ""
@State private var showWarning: Bool = false
@State var child = Item(name: "", parent: nil)
var body: some View {
NavigationStack {
Form {
LabeledContent {
TextField("Item", text: $name)
} label: {
Text("Todo:")
}
}
.navigationTitle("Add New Item")
.toolbar {
Button("Save") {
let tmp = Item(name: name, parent: itemParent)
if(itemParent != nil) {
itemParent!.children.append(tmp)
}
context.insert(tmp)
try? context.save()
dismiss()
}
}
}
}
}
Hello,
I recently switched my app from flutter which was using sqlite3 database. I would like to migrate my existing users to SwiftData.
The issue is I do not know where to start in finding the database for the current users, reading the data and inserting into the SwiftData schema.
I tried searching but not clear on how to proceed. Any help pointing in the right direction would be great. Thanks.
Hello, I wanted to sync my Swift Data App with iCloud. I provided default values to all my models, made very relationship between my models optional. Then, at Signing and Capabilities, I finally added Background Modes (and checked Remote notifications) and iCloud (and checked CloudKit and added a container with my bundle id). Now I receive these errors every time I run my app on a device that is connect to iCloud
CoreData: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _recoverFromError:withZoneIDs:forStore:inMonitor:](2620): <NSCloudKitMirroringDelegate: 0x302de80f0> - Failed to recover from error: CKErrorDomain:15
Recovery encountered the following error: (null):0
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _finishedRequest:withResult:](3582): Finished request: <NSCloudKitMirroringDelegateSetupRequest: 0x3031d4460> 53CB1DFC-E589-4945-8AF1-36126756110B with result: <NSCloudKitMirroringResult: 0x301c79320> storeIdentifier: 41F2B808-5C97-44B3-BC28-5534FEBCCF2C success: 0 madeChanges: 0 error: <CKError 0x301c98870: "Partial Failure" (2/1011); "Failed to modify some record zones"; uuid = 044262C6-5136-4989-823C-B0430F7B87DC; container ID = "iCloud.lu.yansoisson.blip-notes"; partial errors: {
com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x301c7a9a0: "Server Rejected Request" (15/2000); op = 15C2EFE32CB459E1; uuid = 044262C6-5136-4989-823C-B0430F7B87DC>
}>
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndExecuteNextRequest](3551): <NSCloudKitMirroringDelegate: 0x302de80f0>: Checking for pending requests.
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndExecuteNextRequest]_block_invoke(3567): <NSCloudKitMirroringDelegate: 0x302de80f0>: No more requests to execute.
CoreData: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate recoverFromError:](2310): <NSCloudKitMirroringDelegate: 0x302de80f0> - Attempting recovery from error: <CKError 0x301c98870: "Partial Failure" (2/1011); "Failed to modify some record zones"; uuid = 044262C6-5136-4989-823C-B0430F7B87DC; container ID = "iCloud.lu.yansoisson.blip-notes"; partial errors: {
com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x301c7a9a0: "Server Rejected Request" (15/2000); op = 15C2EFE32CB459E1; uuid = 044262C6-5136-4989-823C-B0430F7B87DC>
}>
Here's the debug message that appears first when I start the app
CoreData: debug: CoreData+CloudKit: -[PFCloudKitOptionsValidator validateOptions:andStoreOptions:error:](36): Validating options: <NSCloudKitMirroringDelegateOptions: 0x3023ec6e0> containerIdentifier:iCloud.lu.yansoisson.blip-notes databaseScope:Private ckAssetThresholdBytes:<null> operationMemoryThresholdBytes:<null> useEncryptedStorage:NO useDeviceToDeviceEncryption:NO automaticallyDownloadFileBackedFutures:NO automaticallyScheduleImportAndExportOperations:YES skipCloudKitSetup:NO preserveLegacyRecordMetadataBehavior:NO useDaemon:YES apsConnectionMachServiceName:<null> containerProvider:<PFCloudKitContainerProvider: 0x3010e62d0> storeMonitorProvider:<PFCloudKitStoreMonitorProvider: 0x3010e62e0> metricsClient:<PFCloudKitMetricsClient: 0x3010e62f0> metadataPurger:<PFCloudKitMetadataPurger: 0x3010e6300> scheduler:<null> notificationListener:<null> containerOptions:<null> defaultOperationConfiguration:<null> progressProvider:<NSPersistentCloudKitContainer: 0x300785440> test_useLegacySavePolicy:YES archivingUtilities:<PFCloudKitArchivingUtilities: 0x3010e6310> bypassSchedulerActivityForInitialImport:NO bypassDasdRateLimiting:NO activityVouchers:(
)
storeOptions: {
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
NSPersistentCloudKitContainerOptionsKey = "<NSPersistentCloudKitContainerOptions: 0x3036f0ea0>";
NSPersistentHistoryTrackingKey = 1;
NSPersistentStoreMirroringOptionsKey = {
NSPersistentStoreMirroringDelegateOptionKey = "<NSCloudKitMirroringDelegate: 0x302de80f0>";
};
NSPersistentStoreRemoteChangeNotificationOptionKey = 1;
}
CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate observeChangesForStore:inPersistentStoreCoordinator:](427): <NSCloudKitMirroringDelegate: 0x302de80f0>: Observing store: <NSSQLCore: 0x10214ca00> (URL: file:///var/mobile/Containers/Data/Application/780A6276-3BE4-458E-BD2D-EC304B123111/Library/Application%20Support/default.store)
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _setUpCloudKitIntegration:](589): <NSCloudKitMirroringDelegate: 0x302de80f0>: Successfully enqueued setup request: <NSCloudKitMirroringDelegateSetupRequest: 0x3031d4460> 53CB1DFC-E589-4945-8AF1-36126756110B
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndExecuteNextRequest](3551): <NSCloudKitMirroringDelegate: 0x302de80f0>: Checking for pending requests.
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndExecuteNextRequest]_block_invoke(3564): <NSCloudKitMirroringDelegate: 0x302de80f0>: Executing: <NSCloudKitMirroringDelegateSetupRequest: 0x3031d4460> 53CB1DFC-E589-4945-8AF1-36126756110B
CoreData: warning: CoreData+CloudKit: -[PFCloudKitSetupAssistant _checkAccountStatus:]_block_invoke(342): Fetched account info for store 41F2B808-5C97-44B3-BC28-5534FEBCCF2C: <CKAccountInfo: 0x3007bbb80; accountStatus=Available, accountPartition=Prod, deviceToDeviceEncryptionAvailability=(account|device), hasValidCredentials=true, walrus=Enabled, needsToVerifyTerms=false, accountAccessAuthorization=Yes, validationCounter=545>
(null)
CoreData: warning: CoreData+CloudKit: -[PFCloudKitSetupAssistant _checkUserIdentity:]_block_invoke(1446): Fetched user recordID for store 41F2B808-5C97-44B3-BC28-5534FEBCCF2C: <CKRecordID: 0x3012ddbc0; recordName=_e002d189d325132b7dae12ad045e5d76, zoneID=_defaultZone:__defaultOwner__>
(null)
Does anyone know how to solve this issue since I have done everything exactly like mentioned in multiple tutorials and blogs?
Thanks
Hi,
I'm experiencing a layout issue in SwiftUI when using TabView, NavigationStack, and a List in a specific navigation flow. Here's how to reproduce it:
Tap on Tab 3.
Tap "Tap Me to go to the subview" to navigate to the detail view.
In the detail view, tap Back to return to Tab 3.
Tap "Tap Me to go to the subview" again.
Problem: When returning to the detail view, the content (especially the List) appears incorrectly positioned within the safe area, as if it's overlapping or misaligned with the navigation bar. This happens only when navigating back and forth after dismissing a sheet presented from a different tab.
This animated gif shows the workflow to visualize the problem:
Expected Behavior: The content should consistently respect the safe area and be positioned correctly under the navigation bar.
Thanks in advance for your help!
Here is the complete code to reproduce the issue:
import SwiftUI
@Observable
class MenuSelector {
var initialIndex: Int
var customTabIndex: Int
var isCustomTabSelected: Bool = false
private var previousIndex: Int
init(customTabIndex: Int, initialIndex: Int = 0) {
self.initialIndex = initialIndex
self.customTabIndex = customTabIndex
self.itemSelected = initialIndex
self.previousIndex = initialIndex
}
var itemSelected: Int {
didSet {
if itemSelected == customTabIndex {
previousIndex = oldValue
itemSelected = oldValue
isCustomTabSelected = true
}
}
}
}
struct NavigationStackSpikeView: View {
@State private var tabSelector = MenuSelector(customTabIndex: 1)
var body: some View {
TabView(selection: $tabSelector.itemSelected) {
Text("Tab 1")
.tabItem {
Text("Tab 1")
}
.tag(0)
Text("I want to present a sheet for this tab")
.tabItem {
Text("Action")
}
.tag(1)
Tab3View()
.tabItem {
Text("Tab 3")
}
.tag(2)
}
.sheet(isPresented: $tabSelector.isCustomTabSelected) {
SheetView()
}
}
}
struct Tab3View: View {
@State private var navigationPath = NavigationPath()
var body: some View {
NavigationStack(path: $navigationPath) {
VStack {
NavigationLink(value: Destination.subview) {
Text("Tap Me to go to the subview")
}
}
.navigationDestination(for: Destination.self) { destination in
switch destination {
case .subview:
DetailView()
}
}
}
}
enum Destination: Hashable {
case subview
}
}
struct DetailView: View {
var body: some View {
VStack {
List {
Text("A detail")
}
.listStyle(.plain)
}
.navigationTitle("Details")
.navigationBarTitleDisplayMode(.inline)
}
}
struct SheetView: View {
@Environment(\.dismiss) var dismiss
var body: some View {
VStack {
Text("I'm a sheet")
Button("Dismiss") { dismiss() }
}
}
}
#Preview {
NavigationStackSpikeView()
}
The code below works, in that it successfully creates an item and attached it to the parent item, but the parent view doesn't show the new child until you navigate away from the parent and then back to it.
Parent:
Child1
Child2
// Add Child 3 and this does not refresh when returning through the dismiss() call, but if I navigate to the grand Parent, and then back to the Parent, Child 3 is there. Any ideas?
NavigationStack {
Form {
LabeledContent {
TextField("Item", text: $name)
} label: {
Text("Item:")
}
}
.navigationTitle("Add New Item")
.toolbar {
Button("Save") {
var tmp = Item(timestamp: Date(), name: name, parent: itemParent)
if(itemParent != nil) {
itemParent!.children.append(tmp)
}
context.insert(tmp)
try? context.save()
dismiss()
}
}
}