- Published on
Simulating Device Conditions in Xcode for Real-World Testing
- Authors

- Name
- Mick MacCallum
- @0x7fs
When developing iOS apps, it's easy to test on devices with optimal conditions—fast Wi-Fi, climate-controlled environments, and devices that never leave your desk. But in the real world, users experience apps under far less ideal circumstances: on thermal-throttled devices in direct sunlight, on 3G cellular connections in the subway, or while multitasking with intensive features like navigation and music streaming. Xcode provides a powerful but often overlooked feature called Device Conditions that allows you to simulate these challenging scenarios without leaving your desk.
As emphasized in Apple's WWDC 2019 session "Designing for Adverse Network and Temperature Conditions", these are not edge cases—they're real situations that you and your users will face. Great apps continue to work well even under challenging real-world situations, and Device Conditions gives you the tools to test for that.
What Are Device Conditions?
Device Conditions is a feature introduced in Xcode 11 that lets you simulate various environmental and hardware constraints on physical devices and simulators. This includes:
- Network Link (for testing various network speeds, quality levels, and connectivity issues)
- Thermal State (for simulating different levels of thermal throttling without physically warming your device)
These tools help you proactively identify performance issues, test error handling, and ensure your app provides a good user experience even under adverse conditions.
Accessing Device Conditions
To access Device Conditions in Xcode:
- Connect your iOS device or launch a simulator
- Open the Devices and Simulators window (⇧⌘2 or Window → Devices and Simulators)
- Select your device from the left sidebar
- Look for the Device Conditions section in the lower part of the window
Once you've picked a condition you want to activate, click Start from the devices window. These conditions are system-wide, so you can expect everything to start reacting differently, including your app.
Network Link Conditioner
The Network Link Conditioner is invaluable for testing how your app handles various network conditions. Rather than testing only on your fast office Wi-Fi, you can simulate realistic network types that your users actually experience.
Available Network Profiles
Xcode provides several network profiles including:
- 2G, EDGE - Very slow legacy networks
- 3G - Moderate speed cellular network (still widely used)
- LTE, 4G - Modern cellular networks
- Wi-Fi - Various Wi-Fi connection types
- Network quality variants - Good EDGE, Average 3G, etc.
- Custom profiles - Configure specific bandwidth, packet loss, and latency
An important note: The activated network condition acts as a ceiling or cap on your network type—it cannot upgrade your network performance from where it actually is in the real world. Additionally, while the network link affects the whole system, the UI indicators for your network (like the cellular signal bars) will remain unchanged.
Why Test with Network Link Conditioner?
Many developers test only on 5G or fast Wi-Fi, but some users are on slower 3G and 4G networks. If a 3G connection is their reality, they might be happy to wait for a download to finish even if it takes longer. However, if your app uses arbitrary timeouts that don't account for slower networks, you're not respecting their wishes.
Testing with Network Link Conditioner helps you:
- Set reasonable timeouts - Timeout when you stop making progress, not just when progress takes too long
- Identify performance wins - Discover opportunities to use features like Optimistic DNS or TLS 1.3
- Test app launch - Ensure your app remains launchable even without a network connection
- Improve user experience - Verify that loading states and error handling work well on slower connections
Recommendations from Apple
From the WWDC session, Apple recommends:
- Test with at least 3G networks of varying quality
- Use HTTP/2 for better performance
- Avoid reachability checks whenever possible—just try to use the network
- Don't mock out or skip network calls in your tests entirely
Testing Thermal State
Thermal state is one of the most impactful conditions to test. When a device gets hot—whether from environmental effects like direct sunlight, intensive work like AR rendering, or simply being used as a wireless hotspot—iOS automatically throttles performance to prevent overheating and protect the battery.
Available Thermal States
iOS reports four thermal states to your app:
- Nominal - Normal operating temperatures, no corrective action needed
- Fair - Slightly elevated temperature. iOS starts pausing discretionary background work like Photos analysis. Your app should proactively start energy-saving measures.
- Serious - System performance will be impacted. iOS lowers frame rates for ARKit apps and FaceTime. iCloud backup restoration is paused. Your app should reduce heavy CPU usage, graphics, and I/O.
- Critical - Severe thermal throttling. Your app should stop using peripherals such as the camera.
How Thermal Conditions Work
When you activate a thermal condition in Xcode, there are several important behaviors to understand:
Ramping - The device will ramp up over time to the selected state. For example, if you activate "Serious," the device starts at Nominal, reaches Fair, and eventually reaches Serious. This process takes a few seconds (typically around 10 seconds). If you're subscribed to thermal state notifications, you'll receive notifications at each state change.
The device doesn't actually warm up - Your device has not physically changed in temperature. This makes testing safe, quick, and repeatable without needing to wait for devices to actually heat up.
Acts as a floor, not a ceiling - The thermal condition acts like a floor, not a fixed state. If you run heavy computational loads or leave your device in the sun while a thermal condition is active, the actual thermal state can increase beyond the floor you set. This is a safety precaution to ensure your device still behaves safely even during intensive testing.
Automatic tear down - When you stop the condition, the device will ramp down (e.g., from Serious to Fair to Nominal).
Responding to Thermal State in Code
Your app should dynamically react to thermal state changes. Here's how to implement this:
import Foundation
// Register for thermal state change notifications
NotificationCenter.default.addObserver(
self,
selector: #selector(thermalStateChanged),
name: ProcessInfo.thermalStateDidChangeNotification,
object: nil
)
@objc func thermalStateChanged() {
let thermalState = ProcessInfo.processInfo.thermalState
switch thermalState {
case .nominal, .fair:
// Enable all features
enableFaceTracking(true)
enablePersonSegmentation(true)
enableMotionBlur(true)
case .serious:
// Reduce resource usage
enableFaceTracking(false)
enablePersonSegmentation(false)
enableMotionBlur(true)
case .critical:
// Minimal features, stop peripherals
enableFaceTracking(false)
enablePersonSegmentation(false)
enableMotionBlur(false)
stopCameraUsage()
@unknown default:
break
}
}
By designing defensively, you can reduce your app's energy impact by turning off background work and resource-intensive features, which helps prevent contributing to higher thermal states.
Why Test Thermal Throttling?
Testing a thermal throttled device is crucial because:
- Performance degradation - Apps can lose almost half their frame rate. For example, in Apple's demo, an app running at 30+ FPS dropped to 17 FPS under serious thermal conditions.
- User experience - ARKit apps might struggle to find surfaces, animations become less smooth, and interactions feel sluggish.
- Real-world scenarios - Users sitting outdoors, running multiple intensive features, or using their device as a hotspot will experience thermal throttling regularly.
Without testing, you might ship an app that performs well in your climate-controlled lab but frustrates users in the real world.
Monitoring with Xcode's Energy Gauge
Xcode's Debugging Navigator includes an energy gauge with thermal state information. This gauge shows:
- Two thermal state tracks at the bottom of the energy impact section
- The bottommost track shows the actual thermal state of the device (color-coded for easy interpretation)
- The top track shows the active thermal device condition (if one is set)
- Average energy impact - Higher energy impact means higher battery drain and higher chances of your app causing thermal state increases
You can use this gauge to verify that your energy-saving measures are actually reducing your app's energy impact when thermal conditions are active.
Integrating into Your Testing Workflow
Device Conditions fit best within a comprehensive testing strategy. As discussed in the WWDC session, the Test Pyramid model provides a good framework:
- Unit tests - Fast, focused tests in clean room conditions to find functional regressions
- Integration tests - Check that subsystems work together with real-world conditions
- UI tests - Exercise the app as users would, with all the variance that brings
Device Conditions are most valuable for your integration and UI test suites, where you want to validate real-world behavior. While these tests might have higher variance than clean room unit tests, that variance deserves the same attention you'd give to any tough edge case in your code.
Practical Testing Strategy
Here's Apple's recommended approach:
- Test with at least 3G networks of varying quality
- Test with serious thermal state to see how your app degrades gracefully
- Don't dismiss complaints as one-offs - If users report issues under certain conditions, test under those conditions
- Lock in performance wins - Make device condition testing part of your integration and UI test runs
- Use Instruments - Profile your app with device conditions active to find optimization opportunities
Real-World Impact
As one Apple engineer noted in the session: "If you're ending up on the top of the list on the battery impact screen, users might even consider deleting your app." By testing with device conditions and responding appropriately to thermal states, you can:
- Prevent negative app store reviews mentioning poor performance in heat or on trains
- Ensure consistent user experience across different environments
- Improve battery life and reduce energy impact
- Make performance progressions that translate to the real world
Conclusion
Device Conditions is an essential tool that often goes underutilized. The typical development environment—fast Wi-Fi and climate control—is not representative of how your users experience your app. By regularly testing your app under simulated real-world stress conditions, especially thermal throttling and poor network connectivity, you can catch issues before your users do.
Next time you're about to submit a build, take a moment to:
- Test it with the thermal state set to "Serious"
- Test it with the network link set to "3G - Average"
- Activate both conditions simultaneously
- Run through your critical user flows
You might be surprised what you discover. As Apple's team concluded: "Great apps continue to work well even under challenging real-world situations." Device Conditions gives you the tools to make sure yours is one of them.
For more information, watch WWDC 2019: Designing for Adverse Network and Temperature Conditions and check the Xcode documentation on simulating device conditions.
