Skip to content

Commit

Permalink
chore: add ios session replay onboarding (#23190)
Browse files Browse the repository at this point in the history
  • Loading branch information
marandaneto authored Jun 24, 2024
1 parent ca0bf0b commit abb9a9a
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 7 deletions.
6 changes: 4 additions & 2 deletions frontend/src/scenes/onboarding/Onboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { OnboardingReverseProxy } from './OnboardingReverseProxy'
import { FeatureFlagsSDKInstructions } from './sdks/feature-flags/FeatureFlagsSDKInstructions'
import { ProductAnalyticsSDKInstructions } from './sdks/product-analytics/ProductAnalyticsSDKInstructions'
import { SDKs } from './sdks/SDKs'
import { iOSInstructions } from './sdks/session-replay/ios'
import { SessionReplaySDKInstructions } from './sdks/session-replay/SessionReplaySDKInstructions'
import { SurveysSDKInstructions } from './sdks/surveys/SurveysSDKInstructions'

Expand Down Expand Up @@ -155,7 +156,7 @@ const SessionReplayOnboarding = (): JSX.Element => {
const { currentTeam } = useValues(teamLogic)

const { featureFlags } = useValues(featureFlagLogic)
const hasAndroidOnBoarding = !!featureFlags[FEATURE_FLAGS.SESSION_REPLAY_MOBILE_ONBOARDING]
const hasMobileOnBoarding = !!featureFlags[FEATURE_FLAGS.SESSION_REPLAY_MOBILE_ONBOARDING]

const configOptions: ProductConfigOption[] = [
{
Expand Down Expand Up @@ -192,8 +193,9 @@ const SessionReplayOnboarding = (): JSX.Element => {
}

const sdkInstructionMap = SessionReplaySDKInstructions
if (hasAndroidOnBoarding) {
if (hasMobileOnBoarding) {
sdkInstructionMap[SDKKey.ANDROID] = AndroidInstructions
sdkInstructionMap[SDKKey.IOS] = iOSInstructions
}

return (
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/scenes/onboarding/sdks/feature-flags/ios.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { FlaggedFeature } from 'lib/components/FlaggedFeature'
import { FEATURE_FLAGS } from 'lib/constants'
import { AdvertiseiOSReplay } from 'scenes/onboarding/sdks/product-analytics'

import { SDKKey } from '~/types'

import { SDKInstallIOSInstructions } from '../sdk-install-instructions'
Expand All @@ -8,6 +12,9 @@ export function FeatureFlagsIOSInstructions(): JSX.Element {
<>
<SDKInstallIOSInstructions />
<FlagImplementationSnippet sdkKey={SDKKey.IOS} />
<FlaggedFeature flag={FEATURE_FLAGS.SESSION_REPLAY_MOBILE_ONBOARDING} match={true}>
<AdvertiseiOSReplay context="product-analytics-onboarding" />
</FlaggedFeature>
</>
)
}
39 changes: 39 additions & 0 deletions frontend/src/scenes/onboarding/sdks/product-analytics/ios.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import { CodeSnippet, Language } from 'lib/components/CodeSnippet'
import { FlaggedFeature } from 'lib/components/FlaggedFeature'
import { FEATURE_FLAGS } from 'lib/constants'
import { LemonBanner } from 'lib/lemon-ui/LemonBanner'
import { LemonDivider } from 'lib/lemon-ui/LemonDivider'
import { LemonTag } from 'lib/lemon-ui/LemonTag'
import { Link } from 'lib/lemon-ui/Link'
import { OnboardingStepKey } from 'scenes/onboarding/onboardingLogic'
import { urls } from 'scenes/urls'

import { SDKKey } from '~/types'

import { SDKInstallIOSInstructions } from '../sdk-install-instructions'
import { PersonModeEventPropertyInstructions } from '../shared-snippets'
Expand All @@ -7,13 +17,42 @@ function IOSCaptureSnippet(): JSX.Element {
return <CodeSnippet language={Language.Swift}>{`PostHogSDK.shared.capture("Test Event")`}</CodeSnippet>
}

export function AdvertiseiOSReplay({
context,
}: {
context: 'product-analytics-onboarding' | 'flags-onboarding'
}): JSX.Element {
return (
<div>
<LemonDivider className="my-8" />
<LemonBanner type="info">
<h3>
Session Replay for iOS <LemonTag type="highlight">NEW</LemonTag>
</h3>
<div>
Session replay is now in beta for iOS.{' '}
<Link
to={urls.onboarding('session_replay', OnboardingStepKey.INSTALL, SDKKey.IOS)}
data-attr={`${context}-ios-replay-cta`}
>
Learn how to set it up
</Link>
</div>
</LemonBanner>
</div>
)
}

export function ProductAnalyticsIOSInstructions(): JSX.Element {
return (
<>
<SDKInstallIOSInstructions />
<h3>Send an event</h3>
<IOSCaptureSnippet />
<PersonModeEventPropertyInstructions />
<FlaggedFeature flag={FEATURE_FLAGS.SESSION_REPLAY_MOBILE_ONBOARDING} match={true}>
<AdvertiseiOSReplay context="product-analytics-onboarding" />
</FlaggedFeature>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,17 @@ function AndroidSetupSnippet({ includeReplay }: AndroidSetupProps): JSX.Element
config.sessionReplay = true
// choose whether to mask images or text
config.sessionReplayConfig.maskAllImages = false
config.sessionReplayConfig.maskAllTextInputs = true`
config.sessionReplayConfig.maskAllTextInputs = true
// screenshot is disabled by default
// The screenshot may contain sensitive information, use with caution
config.sessionReplayConfig.screenshot = true`
: ''
}
// Setup PostHog with the given Context and Config
PostHogAndroid.setup(this, config)
}`}
}
}`}
</CodeSnippet>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { LemonBanner, Link } from '@posthog/lemon-ui'
import { useValues } from 'kea'
import { CodeSnippet, Language } from 'lib/components/CodeSnippet'
import { apiHostOrigin } from 'lib/utils/apiHost'
import { teamLogic } from 'scenes/teamLogic'

export interface iOSSetupProps {
includeReplay?: boolean
}

function IOSInstallCocoaPodsSnippet(): JSX.Element {
return <CodeSnippet language={Language.Ruby}>{'pod "PostHog", "~> 3.0.0"'}</CodeSnippet>
}
Expand All @@ -17,7 +22,7 @@ function IOSInstallSPMSnippet(): JSX.Element {
)
}

function IOSSetupSnippet(): JSX.Element {
function IOSSetupSnippet({ includeReplay }: iOSSetupProps): JSX.Element {
const { currentTeam } = useValues(teamLogic)

return (
Expand All @@ -32,6 +37,21 @@ class AppDelegate: NSObject, UIApplicationDelegate {
let POSTHOG_HOST = "${apiHostOrigin()}"
let config = PostHogConfig(apiKey: POSTHOG_API_KEY, host: POSTHOG_HOST)
${
includeReplay
? `
// check https://posthog.com/docs/session-replay/mobile#installation
// for more config and to learn about how we capture sessions on mobile
// and what to expect
config.sessionReplay = true
// choose whether to mask images or text
config.sessionReplayConfig.maskAllImages = false
config.sessionReplayConfig.maskAllTextInputs = true
// screenshot is disabled by default
// The screenshot may contain sensitive information, use with caution
config.sessionReplayConfig.screenshotMode = true`
: ''
}
PostHogSDK.shared.setup(config)
return true
Expand All @@ -41,15 +61,26 @@ class AppDelegate: NSObject, UIApplicationDelegate {
)
}

export function SDKInstallIOSInstructions(): JSX.Element {
export function SDKInstallIOSInstructions(props: iOSSetupProps): JSX.Element {
return (
<>
{props.includeReplay ? (
<LemonBanner type="info">
🚧 NOTE: <Link to="https://posthog.com/docs/session-replay/mobile">Mobile recording</Link> is
currently 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{' '}
<Link to="https://us.posthog.com/#panel=support%3Afeedback%3Asession_replay%3Alow">
in-app support panel
</Link>{' '}
or one of our other <Link to="https://posthog.com/docs/support-options">support options</Link>.
</LemonBanner>
) : null}
<h3>Install via CocoaPods</h3>
<IOSInstallCocoaPodsSnippet />
<h3>Or Install via SPM</h3>
<IOSInstallSPMSnippet />
<h3>Configure</h3>
<IOSSetupSnippet />
<IOSSetupSnippet {...props} />
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './astro'
export * from './bubble'
export * from './framer'
export * from './html-snippet'
export * from './ios'
export * from './js-web'
export * from './next-js'
export * from './nuxt'
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/scenes/onboarding/sdks/session-replay/ios.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { SDKInstallIOSInstructions } from '../sdk-install-instructions'
import { SessionReplayFinalSteps } from '../shared-snippets'

export function iOSInstructions(): JSX.Element {
return (
<>
<SDKInstallIOSInstructions includeReplay={true} />
<SessionReplayFinalSteps />
</>
)
}

0 comments on commit abb9a9a

Please sign in to comment.