🚧 NOTE: iOS session replay is considered
beta
and is free while in beta. We are keen to gather as much feedback as possible so if you try this out please let us know. You can send feedback via the in-app support panel or one of our other support options.
Installation
Install and configure PostHog as you normally would. Ensure you've enabled session recordings in your project settings and then add config.sessionReplay = true
to your PostHog configuration alongside any of your other configuration options.
Requires PostHog iOS SDK version >= 3.6.0, and it's recommended to always use the latest version.
let config = PostHogConfig(apiKey: apiKey)// Enable session recording. Requires enabling in your project settings as well.// Default is false.config.sessionReplay = true// Whether text inputs are masked. Default is true.// Password inputs are always masked regardlessconfig.sessionReplayConfig.maskAllTextInputs = true// Whether images are masked. Default is true.config.sessionReplayConfig.maskAllImages = true// Whether network requests are captured in recordings. Default is true// Only metric-like data like speed, size, and response code are captured.// No data is captured from the request or response body.config.sessionReplayConfig.captureNetworkTelemetry = true// Whether replays are created using high quality screenshots. Default is false.// Required for SwiftUI.// If disabled, replays are created using wireframes instead.// The screenshot may contain sensitive information, so use with cautionconfig.sessionReplayConfig.screenshotMode = true// Deboucer delay used to reduce the number of snapshots captured and reduce performance impact. Default is 1sconfig.sessionReplayConfig.debouncerDelay = 1.0
Additional options
Capture network telemetry
In iOS, PostHog uses method swizzling on URLSession methods, which allows for the out-of-the-box collection of network data.
However, URLSession’s async/await-powered APIs which are not exposed to the objc
runtime and cannot be swizzled. As a result, network telemetry cannot be automatically captured.
For apps using async URLSession
methods, PostHog provides wrapper functions that you can use to manually capture network logs.
import PostHogfunc fetchData(from url: URL) async throws -> Data {// let (data, _) = try await URLSession.shared.data(from: url) // ⬅ replace thislet (data, _) = try await URLSession.shared.postHogData(from: url) // 🦔 with this// your logic here...return data}
You can find a list of available methods to use manually here.
Note: Only metric-like data like speed, size, and response code are captured. No data is captured from the request or response body.
Masking and redacting
Your replays may contain sensitive information. For example, if you're building a banking app you may not want to capture how much money a user has in their account.
To replace any type of UIView
with a redacted version in the replay, set the accessibilityIdentifier to ph-no-capture
:
let imvProfilePhoto = UIImageView(frame: CGRect(x: 50, y: 50, width: 100, height: 100))imvProfilePhoto.accessibilityIdentifier = "ph-no-capture"
Note: For SwiftUI please refer to the Masking in SwiftUI section below
Note: A technical issue is causing the SwiftUI Text view to be detected as a
SwiftUI Image
view. This means that it'll be automatically masked ifmaskAllImages
is set totrue
, even if themaskAllTextInputs
is disabled. We're investigating this issue.
Masking in SwiftUI
When using the SwiftUI TextField with UITextInputTraits, setting traits such as
TextField("Email", text: ...).keyboardType(.emailAddress)
will always be automatically masked since it's for private text.The SwiftUI SecureField view is always automatically masked.
You can manually mark a SwiftUI View for masking using the
postHogMask(_:)
view modifier:Swift// This view will be masked in session replay recordingsMyCoolView().postHogMask()
Limitations
- On iOS, minimum deployment target is iOS13
- SwiftUI is only supported if the
screenshotMode
option is enabled.Text
views in SwiftUI are considered images, so they are masked unlessmaskAllImages
is disabled.
- Custom views are not fully supported if
screenshotMode
is disabled. - WebView is not supported. A placeholder will be shown.
- Flutter for iOS isn't supported.