SwiftUI ViewGraph fatal error on running app - ios

I have a problem time to time running my app. When app crashes the error is:
SwiftUI/ListHeaderFooterCellSupport.swift:72: Fatal error: PlatformListViewBase has no ViewGraph!
2023-01-24 12:41:04.886495+0200 AppHere[10301:2175189] SwiftUI/ListHeaderFooterCellSupport.swift:72: Fatal error: PlatformListViewBase has no ViewGraph!
The crash does not happen all the time, it happens some times. And it is upredictable, I try to do different things to catch where is the problem, but seems that I cant quite get it.
Is it something on adding List to view?
If so, here is a design how I bult my view:
ForEach(handler.categorys, id: \.id){ category in
Section {
List{
ForEach(category.menuItems!, id: \.id){ item in
MenuItemCell(overviewHandler: overviewHandler,
item: item,
currency: currency)
}
}
} header: {
Text("Menu item's - \(category.categoryName!)")
}
}

Related

Pop back from NavigationLink in TabView crashes tvOS app

I'm trying to make a simple tvOS app. I was testing out some basic UI code and had the following:
struct ContentView: View {
var body: some View {
TabView {
NavigationView {
NavigationLink(destination: Text("Subview")) {
Text("Subview")
}
}
.tabItem {
Text("Main")
}
NavigationView {
Text("Settings")
}
.tabItem {
Text("Settings")
}
}
}
}
This launches the app correctly, and I can click the NavigationLink to open the Subview. But, when I press the back/menu button the app closes and the console prints out the following error:
[Common] Error response from snapshot request action of type 1 gave Error Domain=BSActionErrorDomain Code=1 "(null)"
I'm not quite sure where to go from here. From what I have seen, I believe the above code should work (it works fine on my iOS devices). Are there any modifiers I need to add to get this to work or do I need to change the structure of my View?
I am testing this code on my Apple TV 4K (2nd gen) on tvOS 15.0.

SwiftUI. App crashes on iPad with iOS 13.4-13.7 when long-pressed

It's my first question on stackoverflow. Please correct me if I wrong with formatting topic.
I get crash of application when try use long press (?haptic touch?) on real iPad. Also it's reproducible on Simulators iPad with Force Touch click on Magic Trackpad.
Which devices have this bug?
Every iPad since iOS 13.4 until the last iOS 13.
Every Simulator iPad since iOS 13.4 until the last iOS 13.
I never saw this bug on iPhone.
My set up for testing: MacOS Catalina 10.15.6, xCode 11.7,
Simulator iPad mini 2019 5-gen iOS 13.7,
iPad 2018 6-gen iOS 13.7.
Upd 26.10.2020. Also, I try to use xCode 12.0.1 on MacOS Catalina 10.15.7,
iPad 2018 6-gen iOS 13.7. I retested, looks like the bug still available on iOS 13.4-13.7, but is gone for iOS 14. Good decision for iOS 13 I didn't find.
Steps to reproduce the bug.
I use SwiftUI view (TestCrashIPAD) with List, ForEach and dynamic sections (source code below).
Some static sections are predefined, some dynamic sections appear after fetching from server.
IMPORTANT the bug reproducible only when first appear view! Don't go to another screen or minimize the app!
Just open this view (TestCrashIPAD).
Wait until dynamic sections appers.
As soon as the sections appear, try long-press on the cell with text "r1" or "r2" or ... (screenshot)
Get crash (screenshot)
CRASH
I get crash on AppDelegate with:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
I investigated a little bit, and found: this bug reproducible since iOS 13.4. Also with iOS 13.4 there is a View Modifier onDrag (link). May be it's somehow connected, because in call stack I see:
UIDragInteractionLongPressDriver
UIGestureRecognizer
May be something wrong with dynamic sections array, because I see:
SwiftUI.Sections.rowIDs(forSectionAt: Swift.Int)
SwiftUI.ListCoreDataSource.rowIndex(at: Foundation.IndexPath)
Question
How to fix this issue? How to work around without crash in this case? Please, say any idea.
Source Code
Please have a look the source code:
import SwiftUI
struct TestCrashIPAD: View {
#State var sections = [TestSection]()
var body: some View {
List {
// predefined sections
Section(header: Text("Section predefined")) {
Text("1")
Text("2")
}
Section(header: Text("Section predefined")) {
ForEach(1..<7) {
Text("\($0)")
}
}
// dynamic content
ForEach(sections) { section in
Section(header: Text(section.title)) {
ForEach(section.rows) { row in
HStack {
Text(row.str)
Spacer()
}
}
}
}
}
.listStyle(GroupedListStyle())
.navigationBarTitle("iPad crash with long press")
.onAppear(perform: onAppearAction)
}
func onAppearAction() {
DispatchQueue.global().async {
// fetch some data from the server
sleep(3)
// show data in UI
DispatchQueue.main.async {
self.sections = [TestSection](TestSection.array)
}
}
}
}
struct TestSection: Identifiable {
let id = UUID()
let title: String
let rows: [TestRow]
static var array: [TestSection] {
var result = [TestSection]()
for idx in 0..<50 {
result.append(TestSection(title: "s\(idx)", rows: TestRow.array))
}
return result
}
}
struct TestRow: Identifiable {
let id = UUID()
let str: String
static var array: [TestRow] {
var result = [TestRow]()
for idx in 0..<Int.random(in: 3..<7) {
result.append(TestRow(str: "r\(idx)"))
}
return result
}
}
Looks like the answer is to add .onLongPressGesture { } to your lists that are crashing
(i got this from comments, but this resolved my issues, so seems like an answer. posting as an answer bc not everyone reads comments

Swift: Crash when loading a Table many times

I have following issue:
In my App, you have online recipes now imagine a TabViewController. On the first two pages of this TabViewController you have a view displaying recipes stored on the Realtime Database of Firebase. On the third one you have a simple view with some buttons, but no Firebase used and imported. The problem now is, when I slam the Bottom Bar multiple times and therefore switch the TabViewController multiple times in a second the app crashes. This probably because of Firebase reloading everytime since there is a TabViewController change, maybe resulting in a overload.
Now I get following error:
Fatal error: Index out of range: file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.2.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
2020-05-22 16:44:28.057640+0200 GestureCook[10451:3103426] Fatal error: Index out of range: file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.2.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
It highlights this code let recipe = myRecipes[indexPath.row] with the index out of range. Now how can I either reduce load on the server or avoid this error?
The reason why there is an increased load is probably since I have to fetch multiple recipes from different locations at once like this simplified example:
// dict is a list of recipe IDs
// And the GetRecipeService.getRecipe is a service which gets a recipe using a .observeSingleEvent (this causes these requests)
for child in dict {
GetRecipeService.getRecipe(recipeUID: child.key) { recipe in
self.myRecipes.append(recipe ?? [String:Any]())
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
How could I reduce load? Is there something as multipath udpates in Firebase, but just as a get, so I don't have to load 10-20 recipes with a .observeSingleEvent?
First of all the DispatchQueue block is at the wrong place. It must be inside the closure
GetRecipeService.getRecipe(recipeUID: child.key) { recipe in
self.myRecipes.append(recipe ?? [String:Any]())
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
To manage multiple asynchronous requests in a loop there is an API: DispatchGroup
let group = DispatchGroup()
for child in dict {
group.enter()
GetRecipeService.getRecipe(recipeUID: child.key) { recipe in
self.myRecipes.append(recipe ?? [String:Any]())
group.leave()
}
}
group.notify(queue: .main) {
self.tableView.reloadData()
}

Receiving EXC_BAD_ACCESS exception

I am using a singleton class to select data from CoreData, and send it back to the calling ViewController. My issue is that when getting one of the ManagedObject's properties, the app crashes with an EXC_BAD_ACCESS exception.
This only seems to happen on iOS 9.x or on the simulator, but is pretty consistent on those. It hasn't happened on a device running 10.x. I set the scheme diagnostics to show zombie objects, and am now presented with the following error:
-[CFString copy]: message sent to deallocated instance 0x15b92990
The issue is that the string being referenced is on an object retrieved directly before I get this error, and I am using Swift (So not manually deallocating anything), so I don't understand why it is deallocated.
The code that selects the object looks like this:
func getModelTypePrice(mmCode: String, year: Int) -> ModelTypePrice? {
let request = NSFetchRequest<ModelTypePrice>(entityName: "ModelTypePrice")
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [NSPredicate(format: "mmcode = %#", mmCode),
NSPredicate(format: "reg_year = %d", year)])
do {
let prices = try managedContext.fetch(request)
if prices.count == 1 {
return prices[0]
}
} catch {
print("Error selecting object: \(error)")
}
return nil
}
That is called from the ViewController, and used as follows:
if let price = LibraryAPI.sharedInstance.getModelTypePrice(mmCode: "123", year: 2017) {
self.newPrice = price.new_price // Error happens here.
}
The ViewController does have an optional String property called newPrice. The new_price property on a ModelTypePrice is also an optional String.
I am at a bit of a loss here, so any advice or suggestions would be appreciated.
This fixed it: [CFNumber release]: message sent to deallocated instance
The problem was the name of the property of the managed object starting with new(it was new_price). Changing it to price_new fixed it. Apparently they changed how this is handled in iOS 10.x, as it was never a problem there.
Maybe this saves someone else some frustration.

Force reload watchOS 2 Complications

I have issues getting Complications to work. It would be helpful if I was able to reliably refresh them.
Therefore I linked a force-press menu button to the following method
#IBAction func updateComplication() {
let complicationServer = CLKComplicationServer.sharedInstance()
for complication in complicationServer.activeComplications {
complicationServer.reloadTimelineForComplication(complication)
}
}
Unfortunately this leads to the app crashing. with a fatal error: unexpectedly found nil while unwrapping an Optional value.
I understand that calling reloadTimelineForComplication(complication) is budgeted but that can't be the issue here as it doesn't work from the very beginning.
I am currently using watchOS2 + Xcode 7 GM
I'd appreciate any ideas on making Complications refresh while the app is running?
Trace or use the exception breakpoint and focus on reading the whole error message where it tells you exactly on which line it found the nil unexpectedly (I do suspect the complicationServer). Use 'if let' instead of 'let' to force unwrap the respective variable.
private func reloadComplications() {
if let complications: [CLKComplication] = CLKComplicationServer.sharedInstance().activeComplications {
if complications.count > 0 {
for complication in complications {
CLKComplicationServer.sharedInstance().reloadTimelineForComplication(complication)
NSLog("Reloading complication \(complication.description)...")
}
WKInterfaceDevice.currentDevice().playHaptic(WKHapticType.Click) // haptic only for debugging
}
}
}

Resources