Post

Replies

Boosts

Views

Activity

@State not updating when set via .init([...]) parameter
Hi, it seems that a @State variable in a View will not update (initialize to the new value) on subsequent calls to the Views .init method. In the example below (tested on macOS) the Text("internal: \(_internalNumber)") still shows 41, even after 1s is over and number was set to 42 (in the .task). TestView.init runs as expected and _internalNumber shows the correct value there, but in the body method (on the redraw) _internalNumber still has the old value. This is not how it should be, right? import SwiftUI struct ContentView: View { @State private var number = 41 var body: some View { VStack { TestView(number: number) .fixedSize() } .task { try! await Task.sleep(nanoseconds: 1_000_000_000) await MainActor.run { print("adjusting") number = 42 } } } } //////////////////////// // MARK: - TestView - public struct TestView: View { public init(number: Int) { self.number = number __internalNumber = .init(initialValue: number) print("Init number: \(self.number)") print("Init _internalNumber: \(_internalNumber)") } var number: Int @State private var _internalNumber: Int public var body: some View { VStack(alignment: .leading) { Text("number: \(number)") Text("internal: \(_internalNumber)") } .debugAction { Self._printChanges() print("number: \(number)") print("_internalNumber: \(_internalNumber)") } } } // MARK: - debugAction extension View { func debugAction(_ closure: () -> Void) -> Self { closure() return self } }
3
1
3.8k
Jun ’22
Curious sheet behaviour
Hi, I have a strange case involving sheets, which I think it's a bug, but then again I might be missing something. Using the following code: import SwiftUI enum WhichSheet: String { 	case one, two, three, none } struct ContentView: View { 	@State private var _showSheet = false 	@State private var _whichSheet: WhichSheet = .none 		var body: some View { 			VStack(spacing: 8) { 					Button("One Sheet", action: { self._whichSheet = .one; self._showSheet = true}) 					Button("Two Sheet", action: { self._whichSheet = .two; self._showSheet = true}) 					Button("Three Sheet", action: { self._whichSheet = .three; self._showSheet = true}) 			} 				.sheet(isPresented: $_showSheet, content: { 				Text("whichSheet = \(_whichSheet.rawValue)") 			}) 		} } struct ContentView_Previews: PreviewProvider { 		static var previews: some View { 			ContentView() 		} } I would assume that, depending on which button is pressed, I would say a sheet with the text "whichSheet = one" or "whichSheet = two" etc. But no matter which button is pressed first the text on the sheet is always "whichSheet = none". Only if you choose a different button the second (or third, or ...) time the correct text is being displayed. Bug or am I missing something really obvious? (Test using an iOS 14 / 14.2 project with Xcode 12 / 12.2 beta) Cheers, Michael
4
0
1.8k
Mar ’22
@SceneStorage not working on macOS
Hi, using the following ContentView in a SwiftUI app on macOS I would expect that the state of the toggle persists across application launches: struct ContentView: View { @SceneStorage("Toggle") var onOrOff: Bool = false var body: some View { VStack { Toggle("Will it persist?", isOn: $onOrOff) .padding() } } } To my surprise it does not persist. Am I wrong about how @SceneStorage should work? (I am trying this on the lates macOS/Xcode versions) Does @SceneStorage work for anybody on macOS? Thanks for your feedback! Cheers, Michael
4
0
2.5k
Sep ’23
No "upsert" when working with .unique attributes
Hi, in the session the following is mentioned: If a trip already exists with that name, then the persistent back end will update to the latest values. This is called an upsert. An upsert starts as an insert. If the insert collides with existing data, it becomes an update and updates the properties of the existing data. Nevertheless, if I have a unique constraint on an (String) attribute and try to insert the same again, I end up in the debugger in the generated getter of the attribute: @Attribute(.unique) public var name: String { get { _$observationRegistrar.access(self, keyPath: \.name) return self.getValue(for: \.name) // <- here } EXC_BREAKPOINT (code=1, subcode=0x1a8d6b724) Am I missing something? If this is expected behaviour, how should I prevent this crash (other than checking for uniqueness before every insert)? Thank you! Cheers, Michael
4
5
2.7k
Aug ’23
Inserting a Model entity with a relationship results in a runtime error.
Hi, when inserting an entity with a relationship I get the following runtime error: Illegal attempt to establish a relationship 'group' between objects in different contexts [...]. The model looks like this: @Model class Person { var name: String @Relationship(.nullify, inverse: \Group.members) var group: Group init(name: String) { self.name = name } } @Model class Group { var name: String @Relationship(.cascade) public var members: [Person] init(name: String) { self.name = name } } It can be reproduced using this (contrived) bit of code: let group = Group(name: "Group A") ctx.insert(group) try! ctx.save() let descriptor = FetchDescriptor<Group>() let groups = try ctx.fetch(descriptor) XCTAssertFalse(groups.isEmpty) XCTAssertEqual(groups.count, 1) XCTAssertTrue(groups.first?.name == "Group A") let person = Person(name: "Willy") person.group = group ctx.insert(person) try ctx.save() (See also full test case below). Anybody experiencing similar issues? Bug or feature? Cheers, Michael Full test case: import SwiftData import SwiftUI import XCTest // MARK: - Person - @Model class Person { var name: String @Relationship(.nullify, inverse: \Group.members) var group: Group init(name: String) { self.name = name } } // MARK: - Group - @Model class Group { var name: String @Relationship(.cascade) public var members: [Person] init(name: String) { self.name = name } } // MARK: - SD_PrototypingTests - final class SD_PrototypingTests: XCTestCase { var container: ModelContainer! var ctx: ModelContext! override func setUpWithError() throws { let fullSchema = Schema([Person.self, Group.self,]) let dbCfg = ModelConfiguration(schema: fullSchema) container = try ModelContainer(for: fullSchema, dbCfg) ctx = ModelContext(container) _ = try ctx.delete(model: Group.self) _ = try ctx.delete(model: Person.self) } override func tearDownWithError() throws { guard let dbURL = container.configurations.first?.url else { XCTFail("Could not find db URL") return } do { try FileManager.default.removeItem(at: dbURL) } catch { XCTFail("Could not delete db: \(error)") } } func testRelAssignemnt_FB12363892() throws { let group = Group(name: "Group A") ctx.insert(group) try! ctx.save() let descriptor = FetchDescriptor<Group>() let groups = try ctx.fetch(descriptor) XCTAssertFalse(groups.isEmpty) XCTAssertEqual(groups.count, 1) XCTAssertTrue(groups.first?.name == "Group A") let person = Person(name: "Willy") person.group = group ctx.insert(person) try ctx.save() } }
4
3
2.5k
Aug ’23
Do I need to add my own unique id?
Hi, if I have a @Model class there's always an id: PersistentIdentifier.ID underneath which, according to the current documentation "The value that uniquely identifies the associated model within the containing store.". So I am wondering if it is (good) enough to rely on this attribute to uniquely identify @Model class entities, or if there are edge cases where it does not work (like maybe when using CloudKit)? If anybody saw some information regarding this, please let me know :-) Cheers, Michael
5
3
3.1k
Aug ’24
Crashes in _os_semaphore_dispose.cold since Xcode 13 beta 5
Hi, since the Xcode 13 beta 5 I am seeing crashes in _os_semaphore_dispose.cold.* when running in the iOS simulator. This happens in different apps under various conditions, so I can pin it down to something specific. Is anybody else having similar issues? Stack of the crashing thread looks like this: Disassembly looks like this: Thanks for any feedback. Cheers, Michael
17
0
3.9k
Aug ’21