I am using Firebase Firestore listeners and am updating 2 tabBarItem badges after fetching.
The badges were updating fine and appeared on the UI until I added a fourth listener, all of which I need. So in total I have 4 asynchronous listeners.
As I've put breakpoints, each listener is working correctly and fetching the right data, and at the point of setting the badgeValue, I see the correct count assigned that was a result of the fetch.
However, the UI either entirely doesn't update and show the badgeValue or inconsistently does.
Is this a memory issue with all the listeners firing off? Any thoughts on what I could possibly implement as a workaround? I've already tried things like DispatchQueue.main.async, and even delaying it, but all have shown inconsistent results.
Any help would be appreciated..
Related
SOLVED: It is not about UITableViewDiffableDataSource. The problem was accessing realm from 2 different thread sequentially and not getting consistent result
One of the thread was main thread and scrolling somehow kept main thread busy and triggered race condition
Everything works if user not scrolling tableview when update is happening.
If user is scrolling or just have finger on the tableview, no animations happening on update and differences does not show up.
I am not getting any error in the console
Data update code is like below:
var snapshot = tableViewDataSource.snapshot()
snapshot.deleteAllItems()
snapshot.appendSections([.conversation])
snapshot.appendItems(conversationList, toSection: .conversation)
tableViewDataSource.apply(snapshot)
Is this somehow an expected behavior?
In my experience, you have to be cognizant of when UI updates occur. UI updates always occur on the main thread.
When the user is actively scrolling, I believe this blocks the main thread, so your diffable data source is likely updating, but your app cannot update the UI until the user releases his/her finger from the display.
I have a large application that uses a number of third-party libraries and am now seeing the following error in the logs: "This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes."
From what I have found here on SO, this is probably being caused by a UI element being changed on a background thread, which is triggering the autolayout. Unfortunately, we have so many UI elements being changed by so many different moving parts that I do not know the best way to find the culprit.
Can anyone tell me how can I found out what exactly is triggering the autolayout change from a background thread?
Sometimes it's not a completion block, but anything that is performed in the background.
In my case it was notifications that where sent. I implemented iCloud in my app, which means that when data was edited or added on another device, the other app(s) receive an iCloud update/notification, which triggered an update of the UITableView.
The code to update the UITableView was not done in the MainThread. Adding the code as shown in the comments fixes it.
According to Apple documentation, "To help your widget look up to date, the system occasionally captures snapshots of your widget’s view. When the widget becomes visible again, the most recent snapshot is displayed until the system replaces it with a live version of the view."
What I am seeing, however, is that the snapshot is removed from screen before the live view is prepared. This results in a flash effect where the old snapshot is taken off screen, the view is blank for a split second, then the new view appears.
Is the developer responsible for making the transition between the snapshot and the live view seamless? If so, what is the strategy behind doing that? I don't see any way to directly control that transition.
I was able to mitigate the effect greatly by moving data loading to
widgetPerformUpdateWithCompletionHandler: and keeping drawing in viewWillAppear:, but I do still see a flash once every 15 (or so) opens of the Notification Center.
I had this same issue and finally figured out the issue I was having with my widget. It turns out it was related to a misunderstanding about the Widget Life Cycle on my behalf.
From the documentation I thought that the today view would keep a 'snapshot' of my widgets state until the widgetPerformUpdateWithCompletionHandler method completion handler was called with success.
This does not seem to be the case. From what I can see the 'snapshot' is just used when the Today View is animating in (when the user pulls down the notification centre). As soon as the today view is loaded and stationary your widget is loaded from scratch (inflated from xib if using) and viewDidLoad is called. At this moment you should populate you widget with cached data (not from a web request). If you don't you will see temporary data from your nib. This is what causes the flashing.
When viewDidLoad is complete widgetPerformUpdateWithCompletionHandler is called which allows you to fetch fresh data. When the fresh data is fetched you should call the completion handler and cache the data it so it can be used when the widget is loaded later on from scratch (in viewDidLoad).
A simple way to cache the data is in user defaults.
You need to be careful about your compilation handler in the
-(void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler
method. What happens is that your extension probably has an error and everytime view appers it is being called again. Try to attach your extension to debugger(Debugger->Attach to Process-> your extension id) and see the result by putting some breakpoints.
I'm struggling with the following scenario and could use some different perspectives to shed some light on me:
I have a self.backstack which is an array of sections to go "back" to when you hit the back button. I'm getting an EXC_BAD_ACCESS when the back button is hit in a particular situation, but I'm not sure which object the code is mad about because everything seems there.
If you look on the bottom left of the image you'll see that self, backStack, and userInfo are all there. Not only that but their respective prints on are logged in the bottom right.
Any thoughts on what the problem might be? Thanks.
I suspect you have an observer of the notification which has been deallocated before it unregistered for the notifications.
Notifications are synchronous, which means that on the line you are crashing on, it is trying to run all of the observer callbacks. Check everywhere you are registering for these, and make sure the objects are either retained elsewhere, or are being properly unregistered (removeObserver iirc) when they are released.
I have an iOS app and I want to make it accessible. Everything goes well but in some screens the voice over loses it's focus and jumps to the first accessible element. It's like the screen is always refreshing. I have used UIAccessibilityInspector and I observed that there are ScreenChanged notifications constantly, from time to time. It's really annoying because I don't know why are those notifications sent and how do I stop/control them.
Thanks,
Alex
I had a similar problem and found that it was caused by a UIPageControl and a timer that I set up to automatically cycle the pages in that control. For some reason, the scrolling caused by that was resetting UIAccessibility to the first element in the view, just like you said. Check and see if you have anything animating or changing state.