Post

Replies

Boosts

Views

Activity

Binding with ForEach or List doesn't work anymore when using @Observable macro
Hi. The binding in a ForEach or List view doesn't work anymore when using the @Observable macro to create the observable object. For example, the following are the modifications I introduced to the Apple's example called "Migrating from the Observable Object Protocol to the Observable Macro" https://developer.apple.com/documentation/swiftui/migrating-from-the-observable-object-protocol-to-the-observable-macro struct LibraryView: View { @Environment(Library.self) private var library var body: some View { List($library.books) { $book in BookView(book: book) } } } All I did was to add the $ to turn the reference to library.books into a binding but I got the error "Cannot find '$library' in scope" Is this a bug or the procedure to use binding in lists changed? Thanks
3
0
1.8k
Jun ’23
SwiftData serious bug with relationships and CloudKit in iOS 18.0 (Xcode 16 Beta)
Hi guys. Can someone please confirm this bug so I report it? The issue is that SwiftData relationships don't update the views in some specific situations on devices running iOS 18 Beta. One clear example is with CloudKit. I created a small example for testing. The following code creates two @models, one to store bands and another to store their records. The following code works with no issues. (You need to connect to a CloudKit container and test it on two devices) import SwiftUI import SwiftData struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var records: [Record] var body: some View { NavigationStack { List(records) { record in VStack(alignment: .leading) { Text(record.title) Text(record.band?.name ?? "Undefined") } } .toolbar { ToolbarItem { Button("Add Record") { let randomNumber = Int.random(in: 1...100) let newBand = Band(name: "New Band \(randomNumber)", records: nil) modelContext.insert(newBand) let newRecord = Record(title: "New Record \(randomNumber)", band: newBand) modelContext.insert(newRecord) } } } } } } @Model final class Record { var title: String = "" var band: Band? init(title: String, band: Band?) { self.title = title self.band = band } } @Model final class Band { var name: String = "" var records: [Record]? init(name: String, records: [Record]?) { self.name = name self.records = records } } This view includes a button at the top to add a new record associated with a new band. The data appears on both devices, but if you include more views inside the List, the views on the second device are not updated to show the values of the relationships. For example, if you extract the row to a separate view, the second device shows the relationships as "Undefined". You can try the following code. struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var records: [Record] var body: some View { NavigationStack { List { ForEach(records) { record in RecordRow(record: record) } } .toolbar { ToolbarItem { Button("Add Record") { let randomNumber = Int.random(in: 1...100) let newBand = Band(name: "New Band \(randomNumber)", records: nil) modelContext.insert(newBand) let newRecord = Record(title: "New Record \(randomNumber)", band: newBand) modelContext.insert(newRecord) } } } } } } struct RecordRow: View { let record: Record var body: some View { VStack(alignment: .leading) { Text(record.title) Text(record.band?.name ?? "Undefined") } } } Here I use a ForEach loop and move the row to a separate view. Now on the second device the relationships are nil, so the row shows the text "Undefined" instead of the name of the band. I attached an image from my iPad. I inserted all the information on my iPhone. The first three rows were inserted with the first view. But the last two rows were inserted after I extracted the rows to a separate view. Here you can see that the relationships are nil and therefore shown as "Undefined". The views are not updated to show the real value of the relationship. This example shows the issue with CloudKit, but this also happens locally in some situations. The system doesn't detect updates in relationships and therefore doesn't refresh the views. Please, let me know if you can reproduce the issue. I'm using Mac Sequoia 15.1, and two devices with iOS 18.0.
2
0
481
Sep ’24
Updating a Core Data object does not update the SwiftUI view
Hi, guys. When I update a value in a Core Data object, the view is not updated to show the change. I don't understand what I'm doing wrong, since this worked before. Right now I have Xcode 16 Beta installed, but it happens with Xcode 15. Here is an example. import SwiftUI import CoreData struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @State private var selectedItem: Item? var body: some View { NavigationStack { VStack { Text("Year: \(selectedItem?.year ?? 0)") .onTapGesture { changeYear() } Spacer() } .onAppear { // Load an item from the database let request: NSFetchRequest<Item> = Item.fetchRequest() request.fetchLimit = 1 if let item = try? viewContext.fetch(request).first { selectedItem = item } } } } private func changeYear() { let year = Int16.random(in: 1900..<2020) print("Random year: \(year)") selectedItem?.year = year try? viewContext.save() } } #Preview { ContentView() .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) } I think it is easy to follow. There is an entity called Item with an attribute called year. I preloaded a few objects for the preview. This view loads one item and assigns it to a state property. When you tap on the Text view, the changeYear() method is executed. In this method I select a random year, assign it to the object in the selectedItem property and save the context. A message is printed on the console with the new value, but the view never updates. I'm also having similar problems with SwiftData and To Many relationships. They also do not update the views when they are modified. In case you want to test it, you can just create a new project with Core Data set in, change the name of the attribute in the Item entity to year and select Int16 as the data type, and then update the following method to preload some values. @MainActor static let preview: PersistenceController = { let result = PersistenceController(inMemory: true) let viewContext = result.container.viewContext for _ in 0..<10 { let newItem = Item(context: viewContext) newItem.year = Int16.random(in: 1900..<2020) } do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } return result }() Thanks for any help.
2
1
635
Aug ’24
How the new relationships in SwiftData work?
There is a new Relationship macro in Xcode Beta 6. The macro includes two new arguments: minimumModelCount and maximumModelCount. I wonder if anyone knows what these values are for and if there is another change under the hood. Relationship( _ options: PropertyOptions..., deleteRule: Schema.Relationship.DeleteRule = .nullify, minimumModelCount: Int? = 0, maximumModelCount: Int? = 0, originalName: String? = nil, inverse: AnyKeyPath? = nil, hashModifier: String? = nil )
1
1
739
Aug ’23
SwiftUI PhotosPicker deselection doesn't work
Hi, guys. In Xcode Beta 4, the PhotosPicker view doesn't modify the state property when all the items are deselected. This seems to be a bug, but I don't know how to file a bug for a beta API. This code generates a list with the selected pictures. If you select a picture and then deselect it, the item is not removed from the list. import SwiftUI import PhotosUI struct ContentView: View {    @State private var selected: [PhotosPickerItem] = []    var body: some View {       NavigationStack {          List(selected, id: \.itemIdentifier) { item in             Text(item.itemIdentifier ?? "")          }          .toolbar {             ToolbarItem(placement: .navigationBarTrailing) {                PhotosPicker(selection: $selected, matching: .images, photoLibrary: .shared()) { Text("Select Photos") }             }          }       }    } }
1
0
1.4k
Aug ’22
Xcode bug in SwiftUI previews when using Core Data
Hi, guys. Can someone confirm this problem so I submit the bug to Apple. When the Core Data Persistent Store is empty, the canvas preview crashes. To test it, you just need to create a new project with the Core Data option enabled. Then go to the Persistence.swift file created by the template, and remove the for in loop in the closure assigned to the preview property that creates 10 new items. The property will look like this: static var preview: PersistenceController = { let result = PersistenceController(inMemory: true)    return result }() Now, you will get an error when the system tries to fetch items [NSManagedObjectContext executeFetchRequest:error:]. You only need to add one single item for the error to disappear. It looks like a pretty bad bug, so I want to be sure it is not my computer. Thanks.
3
0
1.5k
Jan ’22
Pop Up buttons in Interface Builder don't show menu in iOS 15
Hi, guys. I'm testing the new pop-up and pull-down buttons in iOS 15, but they do not show the pop-up menu when pressed (all the options in the Attributes Inspector panel are checked). They only work when I define the entire menu in code. My questions are: Is this because the feature was not implemented yet? If this is implemented later and we can define the menu in Interface Builder, how do you respond to a selection? In code, I can specify the action in the closure, but how do I do it if the menu is defined in Interface Builder? This is how I define the menu from code, just in case someone needs to know: import UIKit class ViewController: UIViewController {   @IBOutlet weak var myButton: UIButton!   override func viewDidLoad() {    super.viewDidLoad()         let optionsClosure = { (action: UIAction) in      print(action.title)    }    myButton.menu = UIMenu(children: [      UIAction(title: "Option 1", state: .on, handler: optionsClosure),      UIAction(title: "Option 2", handler: optionsClosure),      UIAction(title: "Option 3", handler: optionsClosure)    ])   } } Thanks JD
3
0
4.7k
Jun ’21
How to turn an AttributeContainer into an NSAttributedString.Key dictionary
Hi, guys. While trying to update the old code to the new AttributedString structure I realized that there are properties in UIKit that take a dictionary of NSAttributedString.Key values. For instance, the code below assigns a dictionary to the titleTextAttributes property of the UINavigationBarAppearance object. This property doesn't take an AttributeContainer value and I couldn't find any way to convert the container into a dictionary. Is there a way to do it or do we still have to use the old NSAttributedString.Key values in these cases? Thanks! class ViewController: UIViewController {    override func viewDidLoad() {     super.viewDidLoad()     let standard = UINavigationBarAppearance()     standard.titleTextAttributes = [.foregroundColor: UIColor.red]     navigationController?.navigationBar.standardAppearance = standard    } }
1
0
1.4k
Jun ’21
Where is the option Optimize Mac Storage for iCloud Drive?
Hi, guys. I want to put my apps on the cloud so I can develop them from any device, but after a while, the files are removed locally and I get errors. I need to store the files locally on every computer and get them to automatically synchronize with iCloud, but I can't find the option "Optimize Mac Storage" anymore. Also, if I deactivate that option are the files going to stay locally or there is anything else I have to do to make sure that happens? Thanks!
1
0
954
Jun ’21
Can @MainActor replace DispatchQueue.main?
Hi, guys. The use of @MainActor is confusing? Should I use it only to turn classes into main actors? What if one of my functions access the interface from a closure that could run on a different thread? How do I tell the system to access a label from the main thread? Should I mark the entire view controller class with the @MainActor? Is there anything similar to use with functions or statements or should I still use DispatchQueue.main? Thanks.
1
0
1.3k
Jun ’21
How to disable help windows in Xcode
Hi, guys. How can I disable the popup windows that appear when you keep the mouse over an option in the Attributes Inspector panel?https://ibb.co/cwWRTFqI don't remember these windows poping up in previous versions. I think is a new "feature" but it becomes extremelly annoying after just a few minutes working on the storyboard. They do not only appear when you just leave the mouse over the option for a while but also when you are working with the option. For instance, try to change the tag value of an element. After you press the button three or four times, the help window appears and covers the field, not letting you see what you are doing. Probably the worse idea in the history of Xcode.Thanks
2
0
1.3k
Mar ’20