top of page
  • Don Peter

How to detect App Hangs in iOS apps, and fix them.


How to detect App Hangs in iOS apps, and fix them.

One major objective for any app developer is to make sure that their iOS app is smooth and responsive. So, how does one make sure the app is responsive? The rule of thumb is that an application should be able to react to user inputs and touches within 250ms.


If the response time is above 250 ms then the delay becomes apparent and will be noticeable to the app user. iOS documentation categorizes any app response delay that persists for more than 250 ms as App hang.


What developers need is a proper way to identify and fix App hangs. XCode organizer and bug reporting tools like MetricKit and Finotes report App hangs. Reports generated by xcode organizer and MetricKit are not real-time and they also miss App Hangs at times.


Finotes reports App hangs that occur in the application in real-time and supports development, Test Flight and App Store builds. Because the reports are real-time, most App Hang situations will be captured.


Analyzing an App Hang Report

Here are some of the metrics needed for deeper analysis from an App hang report generated by Finotes,

  • Top iOS versions affected.

  • Top device models affected.

  • First app version where the issue is detected.

  • Number of occurrences of the issue.

  • Total time for which the app was unresponsive.

  • Stack trace to identify the point of hang.


Finotes provides App hang issue reports with these metrics.

Screenshot showing top OS versions, Device models and countries where App hang was reported
Top OS versions, Device models and countries where App hang was reported

Screenshot showing number of Devices and total occurrence count of App hang issue
Number of Devices and total occurrence count of App hang issue

Screenshot showing list of app versions, if any, where the same App hang issue was reported
Previous app versions, if any, where the same App hang issue was reported


In most cases the stack trace provided with the issue should give indication of where the root cause lies.

Screenshot of stack-trace indicating the point of origin of App hang issue
Stack-trace indicating the point of origin of App hang issue

There could be situations where stack trace alone might not be sufficient. This is when the rest of the metrics help.


Look for patterns like the top OS versions, device models and the app version where this issue first occurred in the issue report. Occurrences count of the issue will provide a sense of how severe the issue is. Using the combination of these, developers will be able to prioritize and create the test device configuration to reproduce the issue.


Next step is to retrace how the user interacted with the app when the issue occurred. Activity trail, which is a chronologically ordered list of events that happened prior to the App hang which is provided with each App hang issue report in Finotes dashboard. It will have events like the lifecycle of the different viewcontrollers, network changes and state changes of the app along with custom events that are set by the developer.


Screenshot showing activity trail, listing events that occurred prior to App hang issue.
Activity trail listing events that occurred prior to App hang issue.

This will help developers to retrace the app events to identify and reproduce the issue.


How to avoid App Hang situations.

Now that we know how to detect and fix App hangs, let us explore ways to prevent App hangs.


In order to achieve this the main thread of the app should be free from running intensive operations as the application gets frozen when the main thread is stuck.


Now what this means is, execute only tasks that interact with the user interface in the main thread i.e UIKit, AppKit, or SwiftUI based tasks. So how does one execute other long running tasks? Use background threads directly or either through the operation queue or through the Grand Central Dispatch queue to execute such operations.


Let us take the example of a simple HTTP(s) request and using its response data to update a tableview in the app. It is not just the HTTP(s) request that we execute in the separate thread, but de-serializing the JSON object from the response data should be executed outside of the main thread as well. Only the actual tableview update code needs to be executed in the main thread.


Following this coding practice will lower the possibility of App hang issues in your application.


Finotes is available for Objective-C and Swift in iOS and watchOS, and for Java and Kotlin in Android. Click here to get started.



bottom of page