Post

Replies

Boosts

Views

Activity

.transformable with ValueTransformer failing after Xcode 15.1 update
In Xcode 15.0.1, I created a new project to start working with SwiftData. I did this by creating a default App project and checking the Use SwiftData checkbox. The resulting project contains just three files: an app entry point file, a ContentView SwiftUI view file, and an Item model file. The only change I made was to annotate the default Item timestamp property with a .transformable attribute. Here is the resulting model: @Model final class Item { @Attribute(.transformable(by: TestVT.self)) var timestamp: Date // Only updated this line init(timestamp: Date) { self.timestamp = timestamp } } And here is the definition of TestVT. It is a basic ValueTransformer that simply tries to store the Date as a NSNumber: // Added this class TestVT: ValueTransformer { static let name = NSValueTransformerName("TestVT") override class func transformedValueClass() -> AnyClass { NSNumber.self } override class func allowsReverseTransformation() -> Bool { true } override func transformedValue(_ value: Any?) -> Any? { guard let date = value as? Date else { return nil } let ti = date.timeIntervalSince1970 return NSNumber(value: ti) } override func reverseTransformedValue(_ value: Any?) -> Any? { guard let num = value as? NSNumber else { return nil } let ti = num.doubleValue as TimeInterval return Date(timeIntervalSince1970: ti) } } And finally, I made sure to register my ValueTransformer but updating the sharedModelContainer definition in the App: var sharedModelContainer: ModelContainer = { ValueTransformer.setValueTransformer(TestVT(), forName: TestVT.name) // Only added this line let schema = Schema([ Item.self, ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) do { return try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError("Could not create ModelContainer: \(error)") } }() Prior to Xcode 15.1, this was working fine. However, now when I try to create an item when running the app I get the following error: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "timestamp"; desired type = NSNumber; given type = __NSTaggedDate; value = 2023-12-14 01:47:11 +0000.' I'm unsure of why this stopped working. The error seems to be complaining about the input being of type Date when NSNumber was expected, but I thought that's what the ValueTransformer was supposed to be doing. Important note: prior to Xcode 15.1, I did not originally override the transformedValueClass() and everything was working but in the new Xcode when launching the app I was getting a Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) on the return try ModelContainer(...) line. Removing the .transformable property from my model fixed the issue. That's why I added the override here, because I think the docs indicate overriding it as well and I missed that the first time. This being said, I think the code I have is what a correct ValueTransformer would look like. If anyone has experienced this issue, or has a working ValueTransformer for SwiftData in Xcode 15.1, please let me know. Appreciate any help with this issue. Thanks so much!
4
3
1.3k
Dec ’23
SwiftUI @Published var inconsistently updating views
I am working on a simple Reversi app built using SwiftUI. Recently I was updating my app and noticed a bug with the UI not updating to match the game state. Here is a screenshot of an in-progress game: Here is a screenshot of the board after I press the undo button: In the second screenshot, the middle-rightmost white piece should be black. The views that display the pieces depend on a game environmentObject: class Game: ObservableObject { @Published var board = Board() @Published var times = GameState.times var pieces: [Piece] { board.pieces.filter({ $0 != nil}) as! [Piece] } } I only ever initialize a Game() object once, in the root of my app: @main struct DuelingDisksApp: App { @StateObject private var game = Game() var body: some Scene { WindowGroup { GamesView() .environmentObject(game) } } } Later, I use the game in a view which displays the correct piece (if any) for a square: struct SquareView: View { @EnvironmentObject private var game: Game let column: Int let row: Int var body: some View { let square = Square(column: column, row: row) let animation: Animation = .linear(duration: 0.3) ZStack { Button { } label: { Text("") } .disabled(game.board.gameOver) if let piece = game.board.pieces[square] { PieceView(isLight: piece.isLight) .frame(width: boardLength / 16, height: boardLength / 16) .transition(.opacity.animation(animation)) .animation(animation, value: game.board) .zIndex(1) } } } } Any ideas as to why only some of the views are getting updated? One thing I tried was to replace @Published var board = Board() in the Game class with: @Published var board = Board() { willSet { objectWillChange.send() } } This fixed the issue. My understanding was that this is equivalent to @Published var board = Board(). If anyone has any ideas on why this issue might be occurring and why adding the objectWillChange fixes it, I would love to know. From all my testing I have been wondering if it is a bug with SwiftUI but want to make sure that I'm not just doing something incorrectly. Thanks for any help!
3
0
729
Feb ’22
SwiftUI: Pop back from NavigationLink in TabView crashes tvOS app
I am trying to make a simple tvOS app. I was testing some basic SwiftUI code shown here: struct ContentView: View { var body: some View { TabView { NavigationView { NavigationLink(destination: Text("Subview")) { Text("Subview") } } .tabItem { Text("Main") } NavigationView { Text("Settings") } .tabItem { Text("Settings") } } } } ContentView() is called directly from the entry point: @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } When testing this code on my Apple TV (Apple TV 4K, running tvOS 15.0), the app launches successfully. I can switch between tabs and click on the NavigationLink to go to the subview. However, when pressing the back/menu button on the Apple TV Remote, the app closes with the following error: [Common] Error response from snapshot request action of type 1 gave Error Domain=BSActionErrorDomain Code=1 "(null)" Is this intended behavior? Looking at the resources and documentation online it appears like NavigationViews nested inside TabViews should work as expected. Any feedback about what the error is trying to explain might be helpful too, as the vague output makes it difficult to determine if this is an issue with my SwiftUI code or if it is a bug with tvOS and SwiftUI. Thanks!
1
0
2.0k
Sep ’21
NavigationLink pushing extra View after List reorder
So I have a list of items, ordered by name, which I get using an @FetchRequest. Each List row has a NavigationLink, where the user can edit the name of the item. If the user edits the name of the item in such a way as to reorder the list, then taps the Back navigationBarItem, it takes them back to the List view, but then the detail view of the item they just edited is pushed again. For example: I have a list of 2 items with names 'Alpha' and 'Beta' I open the detail view for 'Alpha' I set the name to 'Zeta' I go back to the main list view (where now the list would be ordered as 'Beta', then 'Zeta') The detail view for 'Zeta' (used to be 'Alpha') is opened again I am running Xcode 12 with iOS 14 on a physical iPhone, if anyone could help me figure out if it's a beta issue or if it's an issue in the data in my views that would be great! Happy to post code if needed, thanks!
2
0
787
Jul ’20