Charles Proxy Tutorial for iOS

Learn how to use Charles for iOS and macOS to inspect encrypted and unencrypted network traffic for both your own apps and third-party apps. By Irina Galata.

Leave a rating/review
Download materials
Save for later
Update note: Irina Galata updated this tutorial for Xcode 12, Swift 5 and iOS 14. Aaron Douglas wrote the original.

Let’s face it — we’ve all written code that doesn’t work correctly, and debugging can be hard. It’s even more difficult when you’re talking to other systems over a network.

Fortunately, Charles Proxy can make network debugging much easier.

Charles Proxy sits between your app and the internet. You configure your simulator or iOS device to pass all networking requests and responses through Charles Proxy, so you’ll be able to inspect and even change data midstream to test how your app responds.

In this tutorial, you’ll get hands-on experience with this. In the process, you’ll learn all about:

  • Proxies and how they work on macOS and iOS.
  • Preparing your system to use Charles.
  • Snooping on apps.
  • Simulating and troubleshooting slow networks.
  • Troubleshooting your own apps.

Ready to dive in?

Getting Started

Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.
Then, download the latest version of Charles Proxy for Mac (v4.6.1 at the time of writing). Double-click the DMG file and drag the Charles icon to your Applications folder to install it.

Charles Proxy isn’t free, but there’s a free 30-day trial. Charles will only run for 30 minutes in trial mode, so you may need to restart it throughout this tutorial.

Note: Charles is a Java-based app and supports macOS, Windows and Linux. This Charles Proxy tutorial is for macOS, and some things may be different on other platforms.

Launch Charles. It should ask for permission to automatically configure your network settings. If it doesn’t, press Command-Shift-P to manually have Charles ask for this permission.

Charles Proxy Network Settings

Click Grant Privileges and enter your password if prompted. Charles starts recording network events as soon as it launches, so you should already see events popping into the left pane.

Charles Proxy Network Recording

Note: If you don’t see any events, you may have not granted permissions or may have another proxy already set up. A VPN can also make problems. See Charles’ FAQ page for troubleshooting help.

Exploring the App

The user interface is easy to understand without much experience.

Charles Proxy Toolbar

Many goodies are hidden behind buttons and menus, and the toolbar has a few items you should know about:

  • “Broom” clears the current session and all recorded activity.
  • “Record/Pause” is red when Charles is recording events and gray when stopped.
  • “Lock” starts/stops SSL proxying.
  • The middle buttons from the “Tortoise” to the “Checkmark” provide access to common actions, including throttling, breakpoints and request creation.
  • The last two buttons provide access to commonly used tools and settings.

For now, stop recording by clicking the red Record/Pause button.

Under the toolbar is a toggle between Structure and Sequence. With Sequence selected, the top pane contains a summary of all the recorded network requests, while the main pane contains detailed information about the selected request.

With Structure selected, the top pane is replaced by a left-hand pane of the same data, grouped by site address. You can still see individual requests by expanding each individual site.

Charles Proxy Sequence List

Select Sequence to see all events in a continuous list sorted by time. You’ll likely spend most of your time on this screen when debugging your own apps.

Charles merges the request and response into a single screen by default. However, you can split them into separate events.

Choose Charles ▸ Preferences and select Viewers. Uncheck Combine request and response and press OK. You’ll need to restart Charles for the change to take effect.

Try poking around the user interface and looking at events. You’ll notice one peculiar thing: You can’t see most details for HTTPS events!

SSL/TLS encrypts sensitive request and response information. You might think this makes Charles pointless for all HTTPS events, but Charles has a sneaky way of getting around encryption.

More About Proxies

You may be wondering: “How does Charles do its magic?”

Charles is a proxy server, which means it sits between your app and computer’s network connections. When Charles configured your network settings, it changed your network configuration to route all traffic through it. This allows Charles to inspect all network events to and from your computer.

Proxy servers are in a position of great power, but this also implies the potential for abuse. This is why SSL is so important: Data encryption prevents proxy servers and other middleware from eavesdropping on sensitive information.

Network Diagram

However, in this case, you want Charles to snoop on your SSL messages to let you debug them.

SSL/TLS encrypts messages using certificates generated by trusted third parties called certificate issuers.

Charles can also generate its own self-signed certificate, which you can install on your Mac and iOS devices for SSL/TLS encryption. Since this certificate isn’t issued by a trusted certificate issuer, you’ll need to tell your devices to explicitly trust it. Once installed and trusted, Charles will be able to decrypt SSL events!

When hackers use middleware to snoop on network communications, it’s called a “man-in-the-middle” attack. In general, you DON’T want to trust any random certificate, or you could compromise your network security!

There are some cases where Charles’ sneaky man-in-the-middle strategy won’t work. For example, some apps use SSL pinning for extra security. SSL pinning means the app has a copy of the web server’s public key, and it uses this to verify network connections before communicating. Since Charles’ key wouldn’t match, the app would reject the communication.

Besides logging events, you can also use Charles to modify data on the fly, record it for later review and even simulate bad network connections.

Charles Proxy powerful image

Charles is powerful!

Charles Proxy and Your iOS Device

For years, the only way to proxy traffic from a physical iOS device through Charles Proxy was to tell your iOS device to send all network traffic to your computer. This is still a common practice you’ll cover, but first, you’ll check out the Charles Proxy for iOS app!

Open the App Store on your iOS device and search for Charles Proxy. Unfortunately, there isn’t a free version of the iOS app, so you’ll have to buy it if you want to follow along with this section.

Note: Don’t want to purchase the iOS app? Worry not! You can skip this section and continue below, where you’ll learn how to route your app’s network traffic to your Mac.

Charles Proxy on the App Store

Install the app on your device and open it. The initial screen shows the proxy is inactive. There’s a switch and an overview of some key stats for any running session. Toggle the Status Switch on.

Once asked for permission to install VPN Configurations, tap Allow.

Charles asking for VPN Configurations permission

The status will change to Active.

Charles Proxy initial screen

Tap the Current Session disclosure indicator arrow, and the app will navigate to a view comparable to the top pane on the desktop app. If you don’t see any requests, switch to Safari and load a webpage.

Requests in the current session

Tap any of the individual requests and you’ll drill down to a detailed view for that request. As with the desktop app, any SLS/TLS encrypted traffic is still obfuscated.

Unknown SSL traffic

It’s time to fix that. :]