As SwiftUI adoption grows, developers face challenges in effectively measuring and optimizing SwiftUI app performance within automated tests.
Currently, the only viable approach to analyzing SwiftUI performance is through Profiling (Instruments), which, while powerful, lacks the ability to be incorporated into automated testing workflows. It would be incredibly valuable if XCTest could introduce new performance metrics specifically tailored for SwiftUI, allowing us to write tests against common performance bottlenecks.
Suggested Metrics:
View Body Evaluation Count – Tracks how often a SwiftUI body is recomputed to detect unnecessary re-renders.
Slow View Bodies – Flags SwiftUI views that take a significant amount of time to compute their body.
These metrics would help developers identify inefficiencies early, enforce performance best practices through CI/CD pipelines, and ensure a smooth user experience. I believe adding these performance metrics would be a game-changer for SwiftUI development.
Thank you for your time and consideration!
Instruments
RSS for tagInstruments is a performance-analysis and testing tool for iOS, iPadOS, watchOS, tvOS, and macOS apps.
Posts under Instruments tag
79 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I'm developing a library and using XCTest for unit tests. While trying to profile the test suite, I noticed that Instruments seems to report a leak every single time the async throwing setup function is called, no matter what.
For example,
This will report a leak:
final class LeakTests: XCTestCase {
override func setUp() async throws {
try await super.setUp()
}
func testLeak() async throws {
try await Task.sleep(nanoseconds: 5_000_000_000)
}
}
This will not report a leak:
final class LeakTests: XCTestCase {
// override func setUp() async throws {
// try await super.setUp()
// }
func testLeak() async throws {
try await Task.sleep(nanoseconds: 5_000_000_000)
}
}
Any ideas on why this might be happening, or should I just file a bug report? It makes it quite difficult to use the leak detection for unit tests, as it shows hundreds of leaks when the whole suite is ran.
Our team is currently handling hang issues and logs received by the Organizer during our project.
Regarding the xCode Organizer, we’d like to ask a few questions:
The hang rate is presented as a bar chart for each app version. Is there any way to get detailed information for each versions? For example, what percentage of the hang rate is attributed to users on different iOS versions?
We've encountered a situation where the hang logs have decreased, but the hang rate has increased. Could you explain why this might occur?
I was wondering how the hang rate is sampled. For instance, does it record all users who experience a hang, or only those under specific conditions? The situation is that we can see only a handful of hang logs (around 13), but we have hundreds of thousands of DAUs. This ratio seems quite off. Could you explain what might cause us to receive such a small number of logs for each version?
Hey,
In the UI of the Instruments app, I can change the recording mode to immediate. Is that possible when using xctrace? It seems to use deferred as a default.
I've tried to create a template, set the recording mode to immediate, and use that template for recording. However, that doesn't seem to work. At least the exported TOC of the .trace will have the following summary:
<summary>
<start-date>2025-01-11T13:00:11.365+01:00</start-date>
<end-date>2025-01-11T13:00:30.525+01:00</end-date>
<duration>19.160279</duration>
<end-reason>Target app exited</end-reason>
<instruments-version>16.0 (16A242d)</instruments-version>
<template-name>core_animation_fps</template-name>
<recording-mode>Deferred</recording-mode>
<time-limit>12 hours</time-limit>
</summary>
This issue might be related to: https://developer.apple.com/forums/thread/735948
Thanks a lot!
Hello, I would like to obtain the average CPU usage of a trace I ran through instruments by looking at the cpu profiler. Is there any way to do this? Or should I be using another instrument.
I'm having an issue with my swiftui macOS application where it is continually consuming more memory over time and after a couple of hours will grind to a halt. I've watched a few videos now on how to use Xcode Memory Graph and Instruments to identify the source of a leak (I assume it is a leak). These videos all provide very obvious issues as examples but mine seems more elusive and I don't know how to identify which part of my code is the cause of the issue.
After running instruments I see the following but the leaked objects are not always consistent:
Xcode Memory Graph shows NSSet as the culprit which is shown under CoreFoundation (not my App). I really am a beginner here and because it's not showing me somewhere in my app that I can go and investigate I'm really stuck.
I am experiencing a crash on iOS 18 for some devices when the app becomes active again after being inactive for one or two days, with the following details:
Crash Information:
Thread: com.apple.main-thread
Exception: EXC_BAD_ACCESS KERN_INVALID_ADDRESS
The crash occurs intermittently on certain devices, but I haven’t been able to reproduce it consistently. Based on the crash logs, it seems to be related to accessing an invalid or corrupted memory address. But if user try to uninstall the app or restart the device, the issue is gone .
Is this a known issue in iOS 18? Are there any official workarounds or fixes?
Could this be related to specific device configurations, such as limited memory on older models?
Are there any known APIs or frameworks in iOS 18 that could trigger such an issue?
What additional debugging steps would you recommend to narrow down the root cause?
Have other developers encountered similar crashes in iOS 18?
Thank you for your help! I appreciate any insights or suggestions.
While I was recently profiling some code from a Swift library, I noticed that XCTest added in signposts for the measurement tests, which I found really helpful to "home in" on the code I wanted to profile digging around in the stack trace.
I tried to add my own signposts to provide just a bit of my own markers in there, but while it compiles and profiles equivalently, the signposts just aren't showing up. This is with Xcode 16.1, macOS Sequoia (15.1) and a swift library, using XCTest and profiling within one of the unit tests.
Is there something in this sequence that doesn't allow the library to set up signposts and have instruments collect them?
The flow I'm using:
import os
let subsystem = "MyLibrary"
class MyClass {
let logger: Logger = .init(subsystem: subsystem, category: "fastloop")
let signposter: OSSignposter
init() {
signposter = OSSignposter(logger: logger)
}
func goFast() {
let signpostId = signposter.makeSignpostID()
let state = signposter.beginInterval("tick", id: signpostId)
// ... do a bunch of work here - all synchronous
signposter.endInterval("tick", state)
}
}
Is there something I'm doing incorrectly in using this API, or not enabling to allow those signposts to be collected by the profiler?
I do see the signposts that XCTests injects into the system, just not any of the ones I'm creating.
I've been developing an app for macOS for some time. As I've been approaching the app's final development stages, I decided to try Instruments as I've suspected a memory leak was occurring, since my app's memory usage slowly grows over time. Instruments has found one leak, and I've spent considerable time trying to find the cause. Long story short, I've ended up with just an EmptyView() and Instruments were still showing a leak. I've tried creating a new project with a placeholder "Hello, world!" text, and Instruments were still detecting a leak. Am I doing something wrong here? Maybe I'm not using Instruments correctly? Or is this a bug? My Instruments version is 16.0, macOS Sequoia 15.1.
Hi Apple Engineers,
I am encountering an issue where the memory usage reported by the Xcode memory report and the Xcode Instruments memory profiler are not aligned. Specifically:
Xcode Memory Report:
After implementing autoreleasepool, URLSession reading a zip file, and moving the task inside DispatchQueue.global().async, the memory usage goes down from 900MB to 450MB, indicating a potential memory leak.
Xcode Instruments Memory Profiler:
The memory usage goes down from 900MB to 100MB, suggesting that the memory has been properly released and there is no significant memory leak.
Could you please help me understand the discrepancy between these two tools and provide guidance on the appropriate way to interpret the memory usage in my application? Which result I should rely on it?
I would greatly appreciate your insights and expertise on this matter. Thank you in advance for your assistance.
I created a simple animation of a circle that changes sizes. The circle pulses like a heartbeat in the center of the screen. My expectation was for the CPU use to be very low, but that is not the case. In addition, even if the CPU use isn't as low as I would expect, I did not expect the CPU use to increase over time because nothing else is happening in the app. Here is the code:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
SplashScreenView()
}
}
}
import SwiftUI
struct SplashScreenView: View {
var body: some View {
ZStack {
SplashNucleusView(minSize: 50, maxSize: 100)
}
}
}
import SwiftUI
struct SplashNucleusView: View {
let minSize: Double
let maxSize: Double
@State private var nucleusColor: Color = .primary
@State private var nucleusRadius: Double = 10
@State private var nucleusOpacity: Double = 1.0
private var nucleusAnimation: Animation {
.easeInOut(duration: 0.25)
.repeatForever(autoreverses: true)
}
let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
var body: some View {
Circle()
.fill(nucleusColor)
.frame(width: nucleusRadius)
.opacity(nucleusOpacity)
.onReceive(timer) { _ in
withAnimation(nucleusAnimation) {
nucleusRadius = Double.random(in: minSize...maxSize)
}
}
}
}
This is how the animation looks:
The animation is snappy until the CPU use reaches 95%, at which point there is visible stuttering. Here is how the CPU looks when the animation duration value is 0.5 seconds and the timer publishing interval is 3 seconds:
Changing the animation duration value to 0.25 seconds and the timer publishing interval to 0.5 seconds changes the CPU use as follows:
The complete view has many other moving parts, which make the issue much worse. The issue is evident with only the circle view. I spent hours working with the debugger, reading about animations, and testing new approaches, but the result is always the same.
Why is this happening?
Requirement :
We wanted to run UI Automation using xcuitest in devices with MDM profiles.
Steps :
We have created a test target for our app and signed with MDM profile (in-house)
Generated app and testbundle-Runner along with xctestrun files using “xcodebuild build-for-testing -scheme “App-TestRelease" -configuration “Release” -derivedDataPath "${CURDIR}/derivedData" -workspace "${PROJECT_NAME}.xcworkspace" -sdk iphoneos”
Tried running “xcodebuild test-without-building -destination platform=iOS,id=000842883-**** -xctestrun App-TestRelease_iphoneos17.5-arm64.xctestrun -derivedDataPath /derived/“
Facing below issues
xcodebuild[35481:3588352] IDELaunchReport: e2934a094f300d40:e2934a094f300d40: Finished with error: Unable to launch com.org.mdm.XCTest.xctrunner
Domain: com.apple.platform.iphoneos
Code: -12
User Info: {
IDERunOperationFailingWorker = IDELaunchiPhoneLauncher;
}
--
Request to launch com.org.mdm.XCTest.xctrunner failed.
Domain: com.apple.dt.deviceprocesscontrolservice
Code: 2
Failure Reason: The request to open "com.org.mdm.XCTest.xctrunner" failed. : Failed to launch process with bundle identifier 'com.org.mdm.XCTest.xctrunner'.
--
The request to open "com.org.mdm.XCTest.xctrunner" failed.
Domain: FBSOpenApplicationServiceErrorDomain
Code: 1
Failure Reason: The request was denied by service delegate (SBMainWorkspace) for reason: Security ("Unable to launch com.org.mdm.XCTest.xctrunner because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user").
User Info: {
BSErrorCodeDescription = RequestDenied;
FBSOpenApplicationRequestID = 0x9f9;
}
--
The operation couldn’t be completed. Unable to launch com.org.mdm.XCTest.xctrunner because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user.
Domain: FBSOpenApplicationErrorDomain
Code: 3
Failure Reason: Unable to launch com.org.mdm.XCTest.xctrunner because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user.
User Info: {
BSErrorCodeDescription = Security;
}
Do you know any software that indicates the frequency of the cores in real time?
the macbook pro adapts the frequency of the cores according to the load/temperature it seems to me
thank
When I was using Instruments to test the Display on my phone, I discovered a long-duration frame. Below that frame, there were some gaps in the vsync queue. As I understand it, vsync signals should appear consistently and steadily. How can this behavior be explained?
My phone is iPhone 15 Plus and iOS 18.
I'm a big fan of MetricKit. I decided to see how my apps are performing with iOS 18 and well, I'm not getting any metric payloads from those devices. Metric payloads received from my test devices adopting iOS 18 has pretty much bottomed out to zero.
Is anyone getting MetricKit MXMetricPayloads from iOS 18 devices?
FB15461298 - MetricKit: Production issue / regression with iOS 18 - Significant dropout or metric payloads being generated since 18.0 - nearly no reports
To demonstrate the issue, I decided to graph the metric payloads my infrastructure receives for all of my apps across all of my devices over the last 16 months starting with WWDC23 timeframe. This data is grouped by count per month. A trend can easily be seen starting in June 2024 where I started to adopt iOS 18 betas.
Zooming in since WWDC24, grouped by week, it is much easier to see the decline.
Note, the second screenshot shows data collected from Xcode builds, TestFlight, and App Store. The last data point from today was a manual creation from Xcode's Debug window, so at least that triggering mechanism works and I can confirm all of my code to upload off device works as expected.
On the bright side, I guess I will ship this 'payload received over time' feature in my MetricKit payload analyzer app with a scrolling window and group by features that make up these screenshots.
What exactly is included/calculated in the following metrics within RealityKit Trace - RealityKit Metrics - 3D render attributes:
3D Mesh Triangles
Total Triangles Submitted
3D Mesh Vertices
Total Vertices Submitted
As the second part of the question, what differentiates between:
3D Mesh Triangles vs Total Triangles Submitted
3D Mesh Vertices vs Total Vertices Submitted
Recently, we reworked a crucial part of our app and managed to half the amount of CPU cycles our app requires (according to Xcode Instruments).
Nonetheless, when using the Time Profiler component in instruments, it shows that the CPU time spent was either higher or the same (depending on execution).
The main time-consuming factor here: libsystem_pthread.dylib - the amount of CPU time spent by this library has doubled from original implementation to reworked implementation.
Therefore, I'm having a few questions:
How should I interpret this result?
How is this even possible if the CPU clock cycles halved?
What is the better metric here, the CPU cycles or the time profiler?
How can I reduce the impact of that said library? What does that library do and how can I influence its performance?
Thanks in advance.
Hi there,
In a project that I am working on, whenever I try running instruments for allocations to see the memory allocations that are happening under the hood, I see the statistics, and the traces updating, however the chart never updates.
I have made new projects on the machine, and I have tried different Xcode versions, and they all show the chart just fine. I have tried running the project on other machines with no success. I have double checked the arguments and options on the active schema I am trying to profile with the schema of a new project and they are identical.
Here is a picture of how it looks:
My questions are as follows:
What properties and settings can disable the chart from showing up?
What diagnostic steps recommended that I should take?
I can not share a reproducible as this is the only project I have with this problem and it is not mine, but please tell me if there is anything else I can provide in order to debug this.
All the best
Parsa
My website is using a lot of memory. JavaScript Allocations Timeline shows that js occupies 130MB. However, instruments show that the overall memory usage of webview reaches 480MB. I would like to know if there is any tool to analyze the distribution of this 480MB of memory usage.
Hello there, I try to add universal links to my app but get some problems. When I started researching how I can test it I found a lot of talks about App Search API Validation Tool. But this service is not open for me, I'm always redirected to the home page. Is there something wrong with me or is this service not working at all?