ios.tsx 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. import ExternalLink from 'sentry/components/links/externalLink';
  2. import Link from 'sentry/components/links/link';
  3. import List from 'sentry/components/list/';
  4. import ListItem from 'sentry/components/list/listItem';
  5. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  6. import type {
  7. BasePlatformOptions,
  8. Docs,
  9. DocsParams,
  10. OnboardingConfig,
  11. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  12. import {MobileBetaBanner} from 'sentry/components/onboarding/gettingStartedDoc/utils';
  13. import {metricTagsExplanation} from 'sentry/components/onboarding/gettingStartedDoc/utils/metricsOnboarding';
  14. import {
  15. getReplayMobileConfigureDescription,
  16. getReplayVerifyStep,
  17. } from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding';
  18. import {appleFeedbackOnboarding} from 'sentry/gettingStartedDocs/apple/macos';
  19. import {t, tct} from 'sentry/locale';
  20. import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion';
  21. export enum InstallationMode {
  22. AUTO = 'auto',
  23. MANUAL = 'manual',
  24. }
  25. const platformOptions = {
  26. installationMode: {
  27. label: t('Installation Mode'),
  28. items: [
  29. {
  30. label: t('Auto'),
  31. value: InstallationMode.AUTO,
  32. },
  33. {
  34. label: t('Manual'),
  35. value: InstallationMode.MANUAL,
  36. },
  37. ],
  38. defaultValue:
  39. navigator.userAgent.indexOf('Win') !== -1
  40. ? InstallationMode.MANUAL
  41. : InstallationMode.AUTO,
  42. },
  43. } satisfies BasePlatformOptions;
  44. type PlatformOptions = typeof platformOptions;
  45. type Params = DocsParams<PlatformOptions>;
  46. const isAutoInstall = (params: Params) =>
  47. params.platformOptions.installationMode === InstallationMode.AUTO;
  48. const getAutoInstallSnippet = () =>
  49. `brew install getsentry/tools/sentry-wizard && sentry-wizard -i ios`;
  50. const getManualInstallSnippet = (params: Params) => `
  51. .package(url: "https://github.com/getsentry/sentry-cocoa", from: "${getPackageVersion(
  52. params,
  53. 'sentry.cocoa',
  54. '8.9.3'
  55. )}"),`;
  56. const getConfigurationSnippet = (params: Params) => `
  57. import Sentry
  58. // ....
  59. func application(_ application: UIApplication,
  60. didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  61. SentrySDK.start { options in
  62. options.dsn = "${params.dsn.public}"
  63. options.debug = true // Enabling debug when first installing is always helpful${
  64. params.isPerformanceSelected
  65. ? `
  66. // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
  67. // We recommend adjusting this value in production.
  68. options.tracesSampleRate = 1.0`
  69. : ''
  70. }${
  71. params.isProfilingSelected
  72. ? `
  73. // Sample rate for profiling, applied on top of TracesSampleRate.
  74. // We recommend adjusting this value in production.
  75. options.profilesSampleRate = 1.0`
  76. : ''
  77. }
  78. }
  79. return true
  80. }`;
  81. const getConfigurationSnippetSwiftUi = (params: Params) => `
  82. import Sentry
  83. @main
  84. struct SwiftUIApp: App {
  85. init() {
  86. SentrySDK.start { options in
  87. options.dsn = "${params.dsn.public}"
  88. options.debug = true // Enabling debug when first installing is always helpful${
  89. params.isPerformanceSelected
  90. ? `
  91. // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
  92. // We recommend adjusting this value in production.
  93. options.tracesSampleRate = 1.0`
  94. : ''
  95. }${
  96. params.isProfilingSelected
  97. ? `
  98. // Sample rate for profiling, applied on top of TracesSampleRate.
  99. // We recommend adjusting this value in production.
  100. options.profilesSampleRate = 1.0`
  101. : ''
  102. }
  103. }
  104. }
  105. }`;
  106. const getVerifySnippet = () => `
  107. let button = UIButton(type: .roundedRect)
  108. button.frame = CGRect(x: 20, y: 50, width: 100, height: 30)
  109. button.setTitle("Break the world", for: [])
  110. button.addTarget(self, action: #selector(self.breakTheWorld(_:)), for: .touchUpInside)
  111. view.addSubview(button)
  112. @IBAction func breakTheWorld(_ sender: AnyObject) {
  113. fatalError("Break the world")
  114. }`;
  115. const getExperimentalFeaturesSnippetSwift = () => `
  116. import Sentry
  117. SentrySDK.start { options in
  118. // ...
  119. // Enable all experimental features
  120. options.attachViewHierarchy = true
  121. options.enableMetricKit = true
  122. options.enableTimeToFullDisplayTracing = true
  123. options.swiftAsyncStacktraces = true
  124. options.enableAppLaunchProfiling = true
  125. }`;
  126. const getExperimentalFeaturesSnippetObjC = () => `
  127. @import Sentry;
  128. [SentrySDK startWithConfigureOptions:^(SentryOptions *options) {
  129. // ...
  130. // Enable all experimental features
  131. options.attachViewHierarchy = YES;
  132. options.enableMetricKit = YES;
  133. options.enableTimeToFullDisplayTracing = YES;
  134. options.swiftAsyncStacktraces = YES;
  135. options.enableAppLaunchProfiling = YES;
  136. }];`;
  137. const getConfigureMetricsSnippetSwift = (params: Params) => `
  138. import Sentry
  139. SentrySDK.start { options in
  140. options.dsn = "${params.dsn.public}"
  141. options.enableMetrics = true
  142. }`;
  143. const getConfigureMetricsSnippetObjC = (params: Params) => `
  144. @import Sentry;
  145. [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {
  146. options.Dsn = @"${params.dsn.public}";
  147. options.enableMetrics = YES;
  148. }];`;
  149. const getVerifyMetricsSnippetSwift = () => `
  150. import Sentry
  151. // Incrementing a counter by one for each button click.
  152. SentrySDK.metrics
  153. .increment(key: "button_login_click",
  154. value: 1.0,
  155. tags: ["screen": "login"]
  156. )
  157. // Add '150' to a distribution used to track the loading time.
  158. SentrySDK.metrics
  159. .distribution(key: "image_download_duration",
  160. value: 150.0,
  161. unit: MeasurementUnitDuration.millisecond,
  162. tags: ["screen": "login"]
  163. )
  164. // Adding '1' to a gauge used to track the loading time.
  165. SentrySDK.metrics
  166. .gauge(key: "page_load",
  167. value: 1.0,
  168. unit: MeasurementUnitDuration.millisecond,
  169. tags: ["screen": "login"]
  170. )
  171. // Add 'jane' to a set
  172. // used for tracking the number of users that viewed a page.
  173. SentrySDK.metrics
  174. .set(key: "user_view",
  175. value: "jane",
  176. unit: MeasurementUnit(unit: "username"),
  177. tags: ["screen": "login"]
  178. )`;
  179. const getVerifyMetricsSnippetObjC = () => `
  180. @import Sentry;
  181. // Incrementing a counter by one for each button click.
  182. [SentrySDK.metrics
  183. incrementWithKey :@"button_login_click"
  184. value: 1.0
  185. unit: SentryMeasurementUnit.none
  186. tags: @{ @"screen" : @"login" }
  187. ];
  188. // Add '150' to a distribution used to track the loading time.
  189. [SentrySDK.metrics
  190. distributionWithKey: @"image_download_duration"
  191. value: 150.0
  192. unit: SentryMeasurementUnitDuration.millisecond
  193. tags: @{ @"screen" : @"login" }
  194. ];
  195. // Adding '1' to a gauge used to track the loading time.
  196. [SentrySDK.metrics
  197. gaugeWithKey: @"page_load"
  198. value: 1.0
  199. unit: SentryMeasurementUnitDuration.millisecond
  200. tags: @{ @"screen" : @"login" }
  201. ];
  202. // Add 'jane' to a set
  203. // used for tracking the number of users that viewed a page.
  204. [SentrySDK.metrics
  205. setWithKey :@"user_view"
  206. value: @"jane"
  207. unit: [[SentryMeasurementUnit alloc] initWithUnit:@"username"]
  208. tags: @{ @"screen" : @"login" }
  209. ];`;
  210. const getReplaySetupSnippet = (params: Params) => `
  211. SentrySDK.start(configureOptions: { options in
  212. options.dsn = "${params.dsn.public}"
  213. options.debug = true
  214. // Currently under experimental options:
  215. options.experimental.sessionReplay.onErrorSampleRate = 1.0
  216. options.experimental.sessionReplay.sessionSampleRate = 1.0
  217. })`;
  218. const getReplayConfigurationSnippet = () => `
  219. options.experimental.sessionReplay.redactAllText = true
  220. options.experimental.sessionReplay.redactAllImages = true`;
  221. const onboarding: OnboardingConfig<PlatformOptions> = {
  222. install: params =>
  223. isAutoInstall(params)
  224. ? [
  225. {
  226. type: StepType.INSTALL,
  227. description: (
  228. <p>
  229. {tct(
  230. 'Add Sentry automatically to your app with the [wizardLink:Sentry wizard] (call this inside your project directory).',
  231. {
  232. wizardLink: (
  233. <ExternalLink href="https://docs.sentry.io/platforms/apple/guides/ios/#install" />
  234. ),
  235. }
  236. )}
  237. </p>
  238. ),
  239. configurations: [
  240. {
  241. language: 'bash',
  242. code: getAutoInstallSnippet(),
  243. },
  244. ],
  245. },
  246. ]
  247. : [
  248. {
  249. type: StepType.INSTALL,
  250. description: tct(
  251. 'We recommend installing the SDK with Swift Package Manager (SPM), but we also support [alternateMethods: alternate installation methods]. To integrate Sentry into your Xcode project using SPM, open your App in Xcode and open [addPackage: File > Add Packages]. Then add the SDK by entering the Git repo url in the top right search field:',
  252. {
  253. alternateMethods: (
  254. <ExternalLink href="https://docs.sentry.io/platforms/apple/install/" />
  255. ),
  256. addPackage: <strong />,
  257. }
  258. ),
  259. configurations: [
  260. {
  261. language: 'url',
  262. code: `https://github.com/getsentry/sentry-cocoa.git`,
  263. },
  264. {
  265. description: (
  266. <p>
  267. {tct(
  268. 'Alternatively, when your project uses a [packageSwift: Package.swift] file to manage dependencies, you can specify the target with:',
  269. {
  270. packageSwift: <code />,
  271. }
  272. )}
  273. </p>
  274. ),
  275. language: 'swift',
  276. partialLoading: params.sourcePackageRegistries.isLoading,
  277. code: getManualInstallSnippet(params),
  278. },
  279. ],
  280. },
  281. ],
  282. configure: params =>
  283. isAutoInstall(params)
  284. ? [
  285. {
  286. type: StepType.CONFIGURE,
  287. description: t(
  288. 'The Sentry wizard will automatically patch your application:'
  289. ),
  290. configurations: [
  291. {
  292. description: (
  293. <List symbol="bullet">
  294. <ListItem>
  295. {t('Install the Sentry SDK via Swift Package Manager or Cocoapods')}
  296. </ListItem>
  297. <ListItem>
  298. {tct(
  299. 'Update your [appDelegate: AppDelegate] or SwiftUI App Initializer with the default Sentry configuration and an example error',
  300. {
  301. appDelegate: <code />,
  302. }
  303. )}
  304. </ListItem>
  305. <ListItem>
  306. {tct(
  307. 'Add a new [code: Upload Debug Symbols] phase to your [code: xcodebuild] build script',
  308. {
  309. code: <code />,
  310. }
  311. )}
  312. </ListItem>
  313. <ListItem>
  314. {tct(
  315. 'Create [code: .sentryclirc] with an auth token to upload debug symbols (this file is automatically added to [code: .gitignore])',
  316. {
  317. code: <code />,
  318. }
  319. )}
  320. </ListItem>
  321. <ListItem>
  322. {t(
  323. "When you're using Fastlane, it will add a Sentry lane for uploading debug symbols"
  324. )}
  325. </ListItem>
  326. </List>
  327. ),
  328. additionalInfo: tct(
  329. 'Alternatively, you can also [manualSetupLink:set up the SDK manually].',
  330. {
  331. manualSetupLink: (
  332. <ExternalLink href="https://docs.sentry.io/platforms/apple/guides/ios/manual-setup/" />
  333. ),
  334. stepsBelow: <strong />,
  335. }
  336. ),
  337. },
  338. ],
  339. },
  340. ]
  341. : [
  342. {
  343. type: StepType.CONFIGURE,
  344. description: (
  345. <p>
  346. {tct(
  347. 'Make sure you initialize the SDK as soon as possible in your application lifecycle e.g. in your [appDelegate:] method:',
  348. {
  349. appDelegate: (
  350. <code>
  351. - [UIAppDelegate application:didFinishLaunchingWithOptions:]
  352. </code>
  353. ),
  354. }
  355. )}
  356. </p>
  357. ),
  358. configurations: [
  359. {
  360. language: 'swift',
  361. code: getConfigurationSnippet(params),
  362. },
  363. {
  364. description: (
  365. <p>
  366. {tct(
  367. "When using SwiftUI and your app doesn't implement an app delegate, initialize the SDK within the [initializer: App conformer's initializer]:",
  368. {
  369. initializer: (
  370. <ExternalLink href="https://developer.apple.com/documentation/swiftui/app/main()" />
  371. ),
  372. }
  373. )}
  374. </p>
  375. ),
  376. language: 'swift',
  377. code: getConfigurationSnippetSwiftUi(params),
  378. },
  379. ],
  380. },
  381. ],
  382. verify: params =>
  383. isAutoInstall(params)
  384. ? [
  385. {
  386. type: StepType.VERIFY,
  387. description: t(
  388. 'The Sentry wizard automatically adds a code snippet that captures a message to your project. Simply run your app and you should see this message in your Sentry project.'
  389. ),
  390. },
  391. {
  392. title: t('Experimental Features'),
  393. description: tct(
  394. 'Want to play with some new features? Try out our experimental features for [vh: View Hierarchy], [ttfd: Time to Full Display (TTFD)], [metricKit: MetricKit], [prewarmedAppStart: Prewarmed App Start Tracing], and [asyncStacktraces: Swift Async Stacktraces]. Experimental features are still a work-in-progress and may have bugs. We recognize the irony. [break] Let us know if you have feedback through [gh: GitHub issues].',
  395. {
  396. vh: (
  397. <ExternalLink href="https://docs.sentry.io/platforms/apple/guides/ios/enriching-events/viewhierarchy/" />
  398. ),
  399. ttfd: (
  400. <ExternalLink href="https://docs.sentry.io/platforms/apple/guides/ios/tracing/instrumentation/automatic-instrumentation/#time-to-full-display" />
  401. ),
  402. metricKit: (
  403. <ExternalLink href="https://docs.sentry.io/platforms/apple/guides/watchos/configuration/metric-kit/" />
  404. ),
  405. prewarmedAppStart: (
  406. <ExternalLink href="https://docs.sentry.io/platforms/apple/tracing/instrumentation/automatic-instrumentation/#prewarmed-app-start-tracing" />
  407. ),
  408. asyncStacktraces: (
  409. <ExternalLink href="https://docs.sentry.io/platforms/apple/guides/ios/#stitch-together-swift-concurrency-stack-traces" />
  410. ),
  411. gh: (
  412. <ExternalLink href="https://github.com/getsentry/sentry-cocoa/issues" />
  413. ),
  414. break: <br />,
  415. }
  416. ),
  417. configurations: [
  418. {
  419. code: [
  420. {
  421. label: 'Swift',
  422. value: 'swift',
  423. language: 'swift',
  424. code: getExperimentalFeaturesSnippetSwift(),
  425. },
  426. {
  427. label: 'Objective-C',
  428. value: 'c',
  429. language: 'c',
  430. code: getExperimentalFeaturesSnippetObjC(),
  431. },
  432. ],
  433. },
  434. ],
  435. },
  436. ]
  437. : [
  438. {
  439. type: StepType.VERIFY,
  440. description: (
  441. <p>
  442. {tct(
  443. 'This snippet contains an intentional error you can use to test that errors are uploaded to Sentry correctly. You can add it to your main [viewController: ViewController].',
  444. {
  445. viewController: <code />,
  446. }
  447. )}
  448. </p>
  449. ),
  450. configurations: [
  451. {
  452. language: 'swift',
  453. code: getVerifySnippet(),
  454. },
  455. ],
  456. },
  457. ],
  458. nextSteps: () => [
  459. {
  460. id: 'cocoapods-carthage',
  461. name: t('CocoaPods/Carthage'),
  462. description: t(
  463. 'Learn about integrating Sentry into your project using CocoaPods or Carthage.'
  464. ),
  465. link: 'https://docs.sentry.io/platforms/apple/install/',
  466. },
  467. {
  468. id: 'debug-symbols',
  469. name: t('Debug Symbols'),
  470. description: t('Symbolicate and get readable stacktraces in your Sentry errors.'),
  471. link: 'https://docs.sentry.io/platforms/apple/dsym/',
  472. },
  473. {
  474. id: 'swiftui',
  475. name: t('SwiftUI'),
  476. description: t('Learn about our first class integration with SwiftUI.'),
  477. link: 'https://docs.sentry.io/platforms/apple/tracing/instrumentation/swiftui-instrumentation/',
  478. },
  479. ],
  480. };
  481. const metricsOnboarding: OnboardingConfig<PlatformOptions> = {
  482. install: (params: Params) => [
  483. {
  484. type: StepType.INSTALL,
  485. description: tct(
  486. 'You need Sentry Cocoa SDK version [codeVersion:8.23.0] or higher. Learn more about installation methods in our [docsLink:full documentation].',
  487. {
  488. codeVersion: <code />,
  489. docsLink: <Link to={`/projects/${params.projectSlug}/getting-started/`} />,
  490. }
  491. ),
  492. configurations: [
  493. {
  494. language: 'yml',
  495. partialLoading: params.sourcePackageRegistries?.isLoading,
  496. code: getAutoInstallSnippet(),
  497. },
  498. ],
  499. },
  500. ],
  501. configure: (params: Params) => [
  502. {
  503. type: StepType.CONFIGURE,
  504. description: t(
  505. 'To enable capturing metrics, you need to enable the metrics feature.'
  506. ),
  507. configurations: [
  508. {
  509. code: [
  510. {
  511. label: 'Swift',
  512. value: 'swift',
  513. language: 'swift',
  514. code: getConfigureMetricsSnippetSwift(params),
  515. },
  516. {
  517. label: 'Objective-C',
  518. value: 'c',
  519. language: 'c',
  520. code: getConfigureMetricsSnippetObjC(params),
  521. },
  522. ],
  523. },
  524. ],
  525. },
  526. ],
  527. verify: () => [
  528. {
  529. type: StepType.VERIFY,
  530. description: tct(
  531. "Then you'll be able to add metrics as [code:counters], [code:sets], [code:distributions], and [code:gauges]. These are available under the [code:SentrySDK.metrics()] namespace.",
  532. {
  533. code: <code />,
  534. }
  535. ),
  536. configurations: [
  537. {
  538. description: metricTagsExplanation,
  539. },
  540. {
  541. description: t('Try out these examples:'),
  542. code: [
  543. {
  544. label: 'Swift',
  545. value: 'swift',
  546. language: 'swift',
  547. code: getVerifyMetricsSnippetSwift(),
  548. },
  549. {
  550. label: 'Objective-C',
  551. value: 'c',
  552. language: 'c',
  553. code: getVerifyMetricsSnippetObjC(),
  554. },
  555. ],
  556. },
  557. {
  558. description: t(
  559. 'It can take up to 3 minutes for the data to appear in the Sentry UI.'
  560. ),
  561. },
  562. {
  563. description: tct(
  564. 'Learn more about metrics and how to configure them, by reading the [docsLink:docs].',
  565. {
  566. docsLink: (
  567. <ExternalLink href="https://docs.sentry.io/platforms/apple/metrics/" />
  568. ),
  569. }
  570. ),
  571. },
  572. ],
  573. },
  574. ],
  575. };
  576. const replayOnboarding: OnboardingConfig<PlatformOptions> = {
  577. introduction: () => (
  578. <MobileBetaBanner link="https://docs.sentry.io/platforms/android/session-replay/" />
  579. ),
  580. install: (params: Params) => [
  581. {
  582. type: StepType.INSTALL,
  583. description: t(
  584. 'Make sure your Sentry Cocoa SDK version is at least 8.31.1. If you already have the SDK installed, you can update it to the latest version with:'
  585. ),
  586. configurations: [
  587. {
  588. code: [
  589. {
  590. label: 'SPM',
  591. value: 'spm',
  592. language: 'swift',
  593. code: `.package(url: "https://github.com/getsentry/sentry-cocoa", from: "${getPackageVersion(
  594. params,
  595. 'sentry.cocoa',
  596. '8.36.0'
  597. )}"),`,
  598. },
  599. {
  600. label: 'CocoaPods',
  601. value: 'cocoapods',
  602. language: 'ruby',
  603. code: `pod update`,
  604. },
  605. {
  606. label: 'Carthage',
  607. value: 'carthage',
  608. language: 'swift',
  609. code: `github "getsentry/sentry-cocoa" "${getPackageVersion(
  610. params,
  611. 'sentry.cocoa',
  612. '8.36.0'
  613. )}"`,
  614. },
  615. ],
  616. },
  617. {
  618. description: t(
  619. 'To set up the integration, add the following to your Sentry initialization:'
  620. ),
  621. },
  622. {
  623. code: [
  624. {
  625. label: 'Swift',
  626. value: 'swift',
  627. language: 'swift',
  628. code: getReplaySetupSnippet(params),
  629. },
  630. ],
  631. },
  632. ],
  633. },
  634. ],
  635. configure: () => [
  636. {
  637. type: StepType.CONFIGURE,
  638. description: getReplayMobileConfigureDescription({
  639. link: 'https://docs.sentry.io/platforms/apple/guides/ios/session-replay/#privacy',
  640. }),
  641. configurations: [
  642. {
  643. description: t(
  644. 'The following code is the default configuration, which masks and blocks everything.'
  645. ),
  646. code: [
  647. {
  648. label: 'Swift',
  649. value: 'swift',
  650. language: 'swift',
  651. code: getReplayConfigurationSnippet(),
  652. },
  653. ],
  654. },
  655. ],
  656. },
  657. ],
  658. verify: getReplayVerifyStep({
  659. replayOnErrorSampleRateName:
  660. 'options\u200b.experimental\u200b.sessionReplay\u200b.onErrorSampleRate',
  661. replaySessionSampleRateName:
  662. 'options\u200b.experimental\u200b.sessionReplay\u200b.sessionSampleRate',
  663. }),
  664. nextSteps: () => [],
  665. };
  666. const docs: Docs<PlatformOptions> = {
  667. onboarding,
  668. feedbackOnboardingCrashApi: appleFeedbackOnboarding,
  669. crashReportOnboarding: appleFeedbackOnboarding,
  670. customMetricsOnboarding: metricsOnboarding,
  671. platformOptions,
  672. replayOnboarding,
  673. };
  674. export default docs;