Advanced Git, Second Edition

Git is key to great version control and collaboration on software projects.
Stop struggling with Git and spend more time on the stuff that matters!

Home iOS & Swift Tutorials

Using Proxyman to Inspect Network Traffic

Learn how to use Proxyman as a man-in-the-middle proxy to inspect network traffic on your iOS device or simulator.

4.5/5 11 Ratings

Version

  • Swift 5.5, iOS 15, Xcode 13

It’s almost impossible to write apps these days without using some kind of networking. It’s an essential concept every developer has to learn: Parse data from JSON and display it in your UI. Between fetching the data and displaying it, you often have a network call. Dealing with it can be frustrating at times. Have you ever coded everything right, with Xcode showing no errors, but still there’s no data displayed in your app? Fortunately, this is where Proxyman comes to the rescue. You can use its powerful toolkit to inspect and debug your network calls. It acts as a man-in-the-middle between your app and the web server.

In this tutorial you’ll learn how to:

  • Set up Proxyman on your Mac.
  • Enable SSL proxying of HTTPS requests.
  • Inspect your app’s network traffic.
  • Edit network responses to simulate different scenarios.
  • Use the Atlantis framework to inspect network calls on a physical device.

You’ll need a physical device if you’d like to try out proxying a device’s traffic. However, if you don’t have one, you can skip that part of the tutorial.

First, take a look at the app you’ll use for this tutorial.

Getting Started

Download the starter project by clicking Download Materials at the top or bottom of the tutorial.

Open Jokester.xcodeproj inside the starter folder. Build and run to see the app in action:

Jokester iOS app running on a Simulator. It has an image and a card. Tapping the card displays a random dad joke from network and a random image above it.

Jokester is a simple, one-screen app that fetches a random dad joke from the JokeAPI and a random image using the Lorem Picsum random image generator. Every time you tap the card, the app makes two network calls: One that gets a random joke in JSON format, parses it and then displays it in a card view and a second that generates a random image. These two calls are independent of each other.

Before you begin, you ask: What sorcery is proxying?

A witch boiling something in her cauldron with Swifties flying around her

Understanding Proxying

Networking — the Wingardium Leviosa of modern computing.

Sorcery or not, you’ll have a hard time finding an app that’s not using networking in some way.

Have you ever finished designing your UI, and the preview looks good, but once you build and run your app, it’s empty? You’re not getting any errors, and Xcode isn’t complaining when you need it to?

Xcode’s console output might give you some hints about what’s happening, but it’s not telling you much.

There’s a better way to debug your networking calls: using a proxy.

A proxy acts as a middleman between the client seeking the resources and a server that provides those resources:

A diagram of how proxying works. A conversation between Sam and Jack has a proxy in between.

When you have a proxy set up between the client and the server, the server doesn’t know to whom it’s sending the information. It’s only aware of the request and that it needs to send a response.

First, you need to download and set up Proxyman.

Setting up Proxyman

At the time of writing, version 2.31.0 is the latest version of Proxyman. While your version may be different, the concepts will still be the same.

Before you begin, you need to install Proxyman on your machine.

Installing Proxyman

Download the latest version from the Proxyman website. Click the button on the website entitled Download Proxyman for macOS and wait for the DMG file to download.

Open the file, then drag and drop Proxyman to Applications:

Installation process showing you to drag and drop Proxyman.dmg file to your Applications folder

When you open Proxyman for the first time, it’ll prompt you to Install Proxy Helper Tool:

When you open Proxyman for the first time you'll see this window that asks you to install Proxy Helper Tool

Proxyman uses a macOS command-line tool called networksetup to change the system proxy settings. It works, however it is less performant than installing Proxyman’s own helper tool for this. Installing it requires entering your password as it requires elevated privileges to function.

Click Install Helper Tool and enter your password when prompted. If you closed the pop-up or wish to install the helper tool later, go to Preference ▸ Advanced and install it from there.

Next, you’ll become familiar with the interface.

Getting Familiar With the Interface

The moment you opened Proxyman, it started inspecting all network calls on your machine. Depending on how many tabs you have open, it might be filling up the list very quickly. And you know you have more than one tab open, wink, wink.

Pause the proxying for now by clicking Pause Recording on the top-left:

Proxyman app showing where the Stop or Pause Recording button is at the top-left.

When you want to resume recording, click the same button to Start Recording again.

Proxyman has three main panels, highlighted in the screenshot below.

Proxyman app showing different parts of Proxyman's interface, the Source List, Flow List and a Flow Content panel.

Here’s what each of these panels provide:

Source List displays aggregated information about all domains and apps connected to the network on your machine. Once you start inspecting networks in the simulator or your iOS device, they’ll appear on the list.

Flow List displays detailed information about each network call on a specific domain.

But the area that interests you the most is Flow Content. It’s split into two main parts: Request and Response windows.

You look at requests and responses while you’re inspecting your network calls. You can see detailed information and even read the JSON you’re fetching in plain text. All this may look confusing at first, but it’ll get much clearer once you start using it in your app.

The top area has three buttons. The first one you already used to pause recording. The second one is for composing your own requests, and the third one clears all the network calls from the list.

Three buttons at the top of Proxyman interface.

Below them is a filtering bar where you can filter your calls by a specific format.

Setting up HTTPS Proxying

HTTPS mean using the HTTP protocol over SSL. SSL itself is a protocol designed to create authenticated and encrypted links between computers in a network. SSL was deprecated when the newer protocol, TLS, released in 1999. However, it’s still referred to as SSL or sometimes as SSL/TLS.

Click a row in the flow list where the URL starts with https://. Notice how the response tab has a lock that says This HTTPS response is encrypted and shows no information?

It’s like the Marauder’s Map — where the key to unlocking it is the magic words, “I solemnly swear that I am up to no good”.

You are actually performing a man-in-the-middle (MITM) attack on yourself when you proxy traffic. When you do it with HTTPS traffic you are technically tricking the server into believing that Proxyman is the app requesting data. However it’s not nefarious because you’re doing this to your own traffic on your machine!

Note: If you’re interested in learning more about man-in-the-middle attacks and how to prevent them, check out this Preventing Man-in-the-Middle Attacks in iOS with SSL Pinning tutorial. You’ll simulate the attack and learn how to defend against it.

To let Proxyman do its magic, you must first install a root certificate which Proxyman can use to encrypt/decrypt as it acts as the man-in-the-middle.

Setting up the Root Certificate

To show you the responses of your network calls in plain text, Proxyman requires you to install the Proxyman Root Certificate. The certificate is locally generated on your machine and stored and trusted in your Keychain.

Go to Certificate ▸ Install Certificate on this Mac…

Proxyman app showing how to navigate to Installing your Proxyman Root Certificate on your macOS

You’ll see a new Mac Setup Guide window with instructions to set up your macOS certificate:

Proxyman app showing the window of the Installing your Proxyman Root Certificate setup guide

If you have administrator privileges, it’s easiest to install the certificate automatically on the default selected Automatic. If you don’t, you can still do it manually by following the instructions in the Manual tab.

On the Automatic tab, click Install & Trust. When prompted, enter your password. You should now see Installed & Trusted!, which means you’ve completed the process:

Mac Setup Guide window in Proxyman showing Installed and Trusted for the Proxyman root certificate

Start recording network calls if you are still paused. You’ll notice that, while you’re able to see the responses, some of them are still locked.

You’ve done everything. But to decrypt encrypted responses you still need to enable SSL proxying for whatever domains you need to inspect connections to.

Note: It’s recommended you delete the Proxyman Root Certificate from your Keychain once you stop using Proxyman. Anyone who has the Proxyman Certificate can intercept your HTTP/HTTPS requests on your macOS machine.

Enabling SSL Proxying

You can enable SSL proxying for a single or multiple domains. You can even enable it for all your network calls without worrying about a domain. All you have to do is specify a wildcard symbol.

In regular expressions, a wildcard symbol is the *. It matches any number of any characters.

Go to Tools ▸ SSL Proxying List…:

Proxyman and SSL Proxying List window showing a + button to add the new entry

Click + at the bottom-left and then select Add Wildcard:

Proxyman and SSL Proxying List window prompting to enter the wildcard

Type * in the field and click Add:

Proxyman and SSL Proxying List window showing a new wildcard entry added to the list

A new wildcard entry will appear in the list. With this set up, you’re now able to read encrypted responses in plain text from any domain. Clear the list using Clear and then Start Recording again. You’re now able to read all your network calls.

Now that you’ve got HTTPS traffic proxying it’s time to learn how to inspect network calls on your physical device.

Note: Feel free to skip the following section if you don’t have an iPhone or are unable to side-load the app on your phone. Continue reading at Proxying on the Simulator to learn how to inspect your app’s network calls on Simulator.

Proxying on a Physical Device

Proxyman has an iOS app to capture network traffic that you can install from the App Store. You can install and play with it, but you won’t use it in this tutorial.

Instead, you’ll configure a Wi-Fi Proxy on your iOS device to Proxyman and install a Proxyman CA Certificate. The process requires a few steps to set up. Once you’re done, you’ll be able to inspect your phone’s network calls and see them in Proxyman on your machine.

Go to Certificate ▸ Install Certificate on iOS ▸ Physical Devices…:

Window in Proxyman with detailed information on how to install the Proxyman CA certificate on iOS device

On your phone, open Settings then Wi-Fi and select your current Wi-Fi. Scroll down, select Configure Proxy and then turn on Manual configuration:

Settings app on an iPhone showing where to find the manual configuration for proxying

For the Server field, enter the value of the server from Proxyman. Enter 9090 for the Port and leave the Authentication toggle off. Tap Save.

Now, open Safari on your phone and navigate to the Proxyman local HTTP server: http://proxy.man/ssl.

iPhone app when you go to Proxyman local host on Safari it prompts you to allow the download of the proxy configuration

A prompt will appear asking if you want to allow download of the configuration profile. Tap Allow. If you see a prompt asking you to choose a device on which you’d like to install this profile then choose iPhone.

Then close Safari and open the Settings app.

A new Profile Downloaded option appears right below your name. Select it and a modal screen will appear asking you to Install Profile:

iPhone Settings app showing a prompt asking you to Install the downloaded certificate

Tap Install and when prompted, enter your passcode. You’ll see a warning saying you need to trust this certificate, which you’ll complete in the next step. Tap Install and then Done.

Next, in the Settings app, go to General ▸ About ▸ Certificate Trust Settings. Turn the toggle on and tap Continue.

iPhone with a prompt asking you to Trust the Root Certificate

That’s it, you’re done! Close Settings and go to Proxyman. You’ll see a new entry in Proxyman under Remote Devices where all your network calls from your phone appear:

Proxyman app showing a new line in Source List that says Remote Devices

Note: When you’re done proxying your device, you should turn it off. Go to Settings ▸ Wi-Fi, select your Wi-Fi’s name, scroll down to Configure Proxy and set it to Off.

Next, you’ll learn how to proxy the iOS Simulator.

Proxying on the Simulator

Proxying on a physical device is great when you’re testing out your app in production. But being able to inspect your app’s network calls from your iOS Simulator is a very convenient way to debug your code as you’re developing it. It’s also very simple to set up!

If you don’t have Xcode running, open Jokester.xcodeproj. Build and run the app:

Jokester app running in Simulator

In Proxyman, go to Certificate ▸ Install Certificate on iOS ▸ Simulators…:

iOS Simulator's Setup window in Proxyman with instructions on how to install the certificate on a Simulator

Click Install and Trust. Once the process finishes, it’ll say Installed successfully!

Proxyman installs a certificate only on your booted iOS Simulators. If you need to run your app on a different Simulator, you need to repeat the process.

You can now proxy your network calls from the simulator.

Now, to test this, make sure Proxyman is still recording your network calls. In the simulator, tap the card to make a network call and load a new joke with a random image.

In Proxyman, expand the Apps group. You’ll see your app’s name in the list:

Proxyman app running and inspecting network call from Simulator

There are two network calls in your app: one to get a random image from picsum.photos and a second to get a random joke from official-joke-api.appspot.com. Click each of these rows in the flow list and inspect the response.

For example, on the joke API response you might see something like this:

{
  "id": 289,
  "type": "general",
  "setup": "What’s brown and sounds like a bell?",
  "punchline": "Dung!"
}

For the image API response, you’ll see the actual image that was downloaded.

Now you’ve seen how to inspect some responses to the requests that your app is making! In the following sections, you’ll learn how to use Proxyman’s toolkit to help you debug your app.

Funny image of iPhone holding a flyswatter over a bug

Inspecting Your App’s Network Traffic

First, you’ll learn how to filter and pin a domain you’re inspecting to find it faster in a list.

Filtering and Pinning Domains

When working with Proxyman, or any other proxying tool, it’s proxying all the network calls on your machine. The list can fill up very quickly, and it may be hard to find what you need.

You apply filters using the bar at the top of the UI:

Top bar showing the filtering UI.

The first section highlighted in red is used to filter by protocol. You can select HTTP, HTTPS or WebSocket. The second section highlighted in blue will filter on a certain response format, e.g. JSON. And the final section highlighted in green will filter on the response status code. By holding down Command, you can select multiple filters.

When you’re using a filter, make sure you’ve selected All Apps or Domains, otherwise you’re only filtering your specific selection:

Proxyman showing you to select All Apps or Domains and different filter tabs

In addition to filtering, you can pin a domain or an app. In Source List, expand the list of apps and select Jokester. Right-click on Jokester and select Pin:

Proxyman showing how to navigate to Pin the Jokester app to the top for easy search

Your app is now pinned to the top and you won’t need to search for it in the list every time you need it:

Proxyman showing the Jokester app and how it is pinned to the top under Favorites

Next, you’ll see how to view your network calls in JSON format.

Adding Custom Previewer Tabs

When it comes to requests and responses, you’re interested in seeing the correct status code and format of your JSON. The default Previewer Tab in both request and response windows is Header.

The headers in a request or response provide extra information between the client and the server. Since you’re interested in seeing the JSON, you’ll add it to the tab.

In Source List, under Jokester, select the official-joke-api.appspot.com domain. Select a network call in the Flow List. In the Response window, click +:

Proxyman app showing where the option to add a new Previewer Tab is located under Response

This opens a new Custom Previewer Tab window:

Custom Previewer Tab in Proxyman

Here, you can select multiple formats you want to add to your previewer list. Under Response, select JSON and Images. Close the window.

You will notice in the Response window there are now two new tabs: JSON and Images. Select JSON:

Proxyman app showing how the JSON Previewer Tab looks and it is showing JSON in plain text

Magic! You can see the JSON response you received from the server in plain text.

Now, select the i.picsum.photos domain and a network call from the Flow List. In the Response window, select Images preview:

Proxyman app showing how the Images Previewer Tab looks and it is showing an image

You can see the exact image your response sent you!

Not only can you inspect your network calls in Proxyman, but you can also compose custom requests in the app. You’ll see how in the following section.

Composing Requests

Before you compose a new network request, make sure you pause recording and clear all the network calls with the clear button. This lets you see your composed request without searching for it.

If you don’t do this, you can still find your request under Apps ▸ Proxyman. That’s the app that sent the request after all.

Click the compose button in the top bar:

Proxyman app showing where the Compose new request button is located in the top-left

You can compose any request you choose. But since you’re inspecting your app, copy and paste https://official-joke-api.appspot.com/jokes/random into the text field.

Next to the text field is a drop-down menu where you can select the HTTP method of your request. The default is GET, and that’s what you want here, so leave that selected. When composing your request, Body, Header and Query are optional. If not defined, it uses the default configuration.

At the bottom-right, check Close window after send and click Send.

Compose window in Proxyman showing how to navigate the window

In the Flow List, you can now see your composed request:

Proxyman app showing the newly composed request in the Flow List

Click it and inspect the response using the JSON tab. You’ll see the joke that the API randomly selected for you!

Next, you’ll learn how to use the Map Local tool to edit networking responses that your app is receiving.

Using the Map Local Tool

The Map Local tool allows you to intercept a response and alter it.

In Proxyman, make sure you’re recording network traffic on your simulator. In the Jokester app on your simulator, request a new joke.

Then, in Proxyman, select a network call from the official-jokes-api.appspot.com domain. Right-click and go to Tools ▸ Map Local…:

Proxyman app showing how to navigate to the Map Local tool by right-clicking the network call

You’ll see a new Map Local Editor window:

Map Local Editor window in Proxyman

Edit the JSON body and replace setup with question:

Map Local Editor showing where to edit the JSON in place and replace setup with question

Now close both windows and tap the card in the Jokester app to generate a new random joke. What happens to the UI?

Jokester app in Simulator showing the setup saying Ready? and punchline is the same

The title of the joke says Ready? and the punchline stays the same no matter how many times you tap the card; only the image changes.

You changed the property name of a JSON object and now your code can’t decode it. So it’s defaulting to a string defined in the app’s code.

Changing responses is one of the most useful features when proxying network calls. You can use it to simulate response errors and see how your app responds.

You’ve seen how to set up your own device for proxying manually. Now, you’ll learn how to set it up in a much simpler way, using the Atlantis framework.

Using the Atlantis Framework

Atlantis makes proxying your app’s network calls simpler than setting it up manually. You only need to import the framework and add a few lines of code.

You’ll use Swift Package Manager to add Atlantis to your app.

Installing Atlantis With SwiftPM

Open Jokester.xcodeproj, if you haven’t already. In the Project navigator, select the Jokester root project. Then select Project ▸ Jokester ▸ Package Dependencies and finally click the + underneath the Packages list.

A new window will open. Copy and paste https://github.com/ProxymanApp/atlantis into the search field at the top right:

Choose package repository window in Xcode

Keep all the options at the default and then click Add Package. Xcode will perform a fetch of the repository and set up the dependency. When it has finished, click Add Package again.

Note: You may need to authenticate with GitHub and provide a personal access token if you’re not already authenticated with GitHub. If prompted, enter the latest build for Atlantis, which is version 1.11.2 as of this tutorial.

You’ll see Atlantis added under Package Dependencies:

Atlantis now appears as a package dependency in the Project navigator

Now you need to add Atlantis to the app. The first step is to initialize Atlantis when your app launches.

Initializing Atlantis Upon App Launch

In Xcode, open AppMain.swift and add the following line below import SwiftUI:

import Atlantis

Then add the following at the beginning of AppMain before body:

init() {
  Atlantis.start()
}

With a few lines of code, you tell your app to start using Atlantis when your app finishes launching.

Build and run. You’ll see the following lines in Xcode console:

--------------------------------------------------------------------------------
--------- [Atlantis] MISSING REQUIRED CONFIG from Info.plist for iOS 14+ -------
--------------------------------------------------------------------------------
Read more at: https://docs.proxyman.io/atlantis/atlantis-for-ios
Please add the following config to your MainApp's Info.plist

Now that Atlantis is up and running, a step is required for Atlantis to work on iOS 14 or later. Don’t skip this step, or Atlantis may not work.

Adding Required Configuration for iOS 14 and Above

In Xcode, find your Info.plist file in Document Outline. Right-click the file then Open As ▸ Source Code:

Xcode showing how to open Info.plist file as Source Code

Add a new line below dict on line 4, then copy and paste the following:

<key>NSLocalNetworkUsageDescription</key>
<string>Atlantis would use Bonjour Service to discover Proxyman app from your local network.</string>
<key>NSBonjourServices</key>
<array>
    <string>_Proxyman._tcp</string>
</array>

Your Info.plist file will look like this:

Info.plist opened as Source Code and how it looks after adding the required new lines

Run the Jokester app again, and you’ll see this in your Xcode console:

--------------------------------------------------------------------------------
----------  Atlantis is running (version 1.0)
---------- Github: https://github.com/ProxymanApp/atlantis
--------------------------------------------------------------------------------
[Atlantis] Looking for Proxyman app in the network...

You’re done with the setup. Now, you can inspect your app’s network calls on your device.

Inspecting Your App’s Network Calls on Your iOS Device

Build and run Jokester on your phone. In Proxyman, make sure you’re recording your network calls. Now, get your daily dose of dad jokes and tap the card a few times:

Jokester app displaying a joke in Simulator

In Proxyman, you’ll see your iPhone and your app added to the Source List:

Proxyman showing how the Jokester app is added to the list after adding the Atlantis framework to the code

Using the Atlantis framework instead of manually setting up Proxyman on your device comes with a few perks. The setup is simpler, and when you’re done, you don’t have to remove any profiles from your device.

If you’re using multiple devices, you don’t have to install profiles on each. All you need to do is install your app on the device you want to inspect your network on.

Mischief managed!

Where to Go From Here?

You can download the completed project files by clicking Download Materials at the top or bottom of this tutorial.

Well done — now you’re a networking wizard!

While networking errors aren’t everyone’s favorite, debugging them should now be a breeze for you. You’ve learned to navigate through some basic networking features that Proxyman offers. Check out Proxyman’s Official Documentation to explore all its other features and keep track of new updates that come along.

In the world of proxies, there’s another popular app called Charles Proxy. Check out the Charles Proxy Tutorial for iOS to learn the basics. And if you feel up for it, check out the Advanced Charles Proxy Tutorial for iOS, where you can learn about all the advanced features.

We hope you enjoyed this tutorial. If you have any questions as you navigate your way through this magical world of network debugging, don’t hesitate to leave a comment in the forum discussion below.

Average Rating

4.5/5

Add a rating for this content

11 ratings

More like this

Contributors

Comments