macos.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. import ExternalLink from 'sentry/components/links/externalLink';
  2. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  3. import type {
  4. Docs,
  5. DocsParams,
  6. OnboardingConfig,
  7. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  8. import {
  9. getCrashReportApiIntroduction,
  10. getCrashReportInstallDescription,
  11. } from 'sentry/components/onboarding/gettingStartedDoc/utils/feedbackOnboarding';
  12. import {t, tct} from 'sentry/locale';
  13. import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion';
  14. type Params = DocsParams;
  15. const getInstallSnippet = (params: Params) => `
  16. .package(url: "https://github.com/getsentry/sentry-cocoa", from: "${getPackageVersion(
  17. params,
  18. 'sentry.cocoa',
  19. '8.9.3'
  20. )}"),`;
  21. const getConfigurationSnippet = (params: Params) => `
  22. import Sentry
  23. // ....
  24. func applicationDidFinishLaunching(_ aNotification: Notification) {
  25. SentrySDK.start { options in
  26. options.dsn = "${params.dsn.public}"
  27. options.debug = true // Enabling debug when first installing is always helpful
  28. // Adds IP for users.
  29. // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
  30. options.sendDefaultPii = true${
  31. params.isPerformanceSelected
  32. ? `
  33. // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
  34. // We recommend adjusting this value in production.
  35. options.tracesSampleRate = 1.0`
  36. : ''
  37. }${
  38. params.isProfilingSelected &&
  39. params.profilingOptions?.defaultProfilingMode !== 'continuous'
  40. ? `
  41. // Sample rate for profiling, applied on top of TracesSampleRate.
  42. // We recommend adjusting this value in production.
  43. options.profilesSampleRate = 1.0`
  44. : ''
  45. }
  46. }${
  47. params.isProfilingSelected &&
  48. params.profilingOptions?.defaultProfilingMode === 'continuous'
  49. ? `
  50. // Manually call startProfiler and stopProfiler
  51. // to profile the code in between
  52. SentrySDK.startProfiler()
  53. // this code will be profiled
  54. //
  55. // Calls to stopProfiler are optional - if you don't stop the profiler, it will keep profiling
  56. // your application until the process exits or stopProfiler is called.
  57. SentrySDK.stopProfiler()`
  58. : ''
  59. }
  60. return true
  61. }`;
  62. const getConfigurationSnippetSwiftUi = (params: Params) => `
  63. import Sentry
  64. @main
  65. struct SwiftUIApp: App {
  66. init() {
  67. SentrySDK.start { options in
  68. options.dsn = "${params.dsn.public}"
  69. options.debug = true // Enabling debug when first installing is always helpful
  70. // Adds IP for users.
  71. // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
  72. options.sendDefaultPii = true${
  73. params.isPerformanceSelected
  74. ? `
  75. // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
  76. // We recommend adjusting this value in production.
  77. options.tracesSampleRate = 1.0`
  78. : ''
  79. }${
  80. params.isProfilingSelected &&
  81. params.profilingOptions?.defaultProfilingMode !== 'continuous'
  82. ? `
  83. // Sample rate for profiling, applied on top of TracesSampleRate.
  84. // We recommend adjusting this value in production.
  85. options.profilesSampleRate = 1.0`
  86. : ''
  87. }
  88. }${
  89. params.isProfilingSelected &&
  90. params.profilingOptions?.defaultProfilingMode === 'continuous'
  91. ? `
  92. // Manually call startProfiler and stopProfiler
  93. // to profile the code in between
  94. SentrySDK.startProfiler()
  95. // do some work here
  96. SentrySDK.stopProfiler()`
  97. : ''
  98. }
  99. }
  100. }`;
  101. const getVerifySnippet = () => `
  102. let button = UIButton(type: .roundedRect)
  103. button.frame = CGRect(x: 20, y: 50, width: 100, height: 30)
  104. button.setTitle("Break the world", for: [])
  105. button.addTarget(self, action: #selector(self.breakTheWorld(_:)), for: .touchUpInside)
  106. view.addSubview(button)
  107. @IBAction func breakTheWorld(_ sender: AnyObject) {
  108. fatalError("Break the world")
  109. }`;
  110. const onboarding: OnboardingConfig = {
  111. install: params => [
  112. {
  113. type: StepType.INSTALL,
  114. description: (
  115. <p>
  116. {tct(
  117. '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:',
  118. {
  119. alternateMethods: (
  120. <ExternalLink href="https://docs.sentry.io/platforms/apple/install/" />
  121. ),
  122. addPackage: <strong />,
  123. }
  124. )}
  125. </p>
  126. ),
  127. configurations: [
  128. {
  129. language: 'url',
  130. code: `https://github.com/getsentry/sentry-cocoa.git`,
  131. },
  132. {
  133. description: (
  134. <p>
  135. {tct(
  136. 'Alternatively, when your project uses a [packageSwift: Package.swift] file to manage dependencies, you can specify the target with:',
  137. {
  138. packageSwift: <code />,
  139. }
  140. )}
  141. </p>
  142. ),
  143. language: 'swift',
  144. partialLoading: params.sourcePackageRegistries.isLoading,
  145. code: getInstallSnippet(params),
  146. },
  147. ],
  148. },
  149. ],
  150. configure: params => [
  151. {
  152. type: StepType.CONFIGURE,
  153. description: (
  154. <p>
  155. {tct(
  156. 'Make sure you initialize the SDK as soon as possible in your application lifecycle e.g. in your [appDelegate:] method:',
  157. {
  158. appDelegate: (
  159. <code>
  160. - [NSAppDelegate applicationDidFinishLaunchingWithNotification:]
  161. </code>
  162. ),
  163. }
  164. )}
  165. </p>
  166. ),
  167. configurations: [
  168. {
  169. language: 'swift',
  170. code: getConfigurationSnippet(params),
  171. },
  172. {
  173. description: (
  174. <p>
  175. {tct(
  176. "When using SwiftUI and your app doesn't implement an app delegate, initialize the SDK within the [initializer: App conformer's initializer]:",
  177. {
  178. initializer: (
  179. <ExternalLink href="https://developer.apple.com/documentation/swiftui/app/main()" />
  180. ),
  181. }
  182. )}
  183. </p>
  184. ),
  185. language: 'swift',
  186. code: getConfigurationSnippetSwiftUi(params),
  187. },
  188. ],
  189. },
  190. ],
  191. verify: () => [
  192. {
  193. type: StepType.VERIFY,
  194. description: (
  195. <p>
  196. {tct(
  197. '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].',
  198. {
  199. viewController: <code />,
  200. }
  201. )}
  202. </p>
  203. ),
  204. configurations: [
  205. {
  206. language: 'swift',
  207. code: getVerifySnippet(),
  208. },
  209. ],
  210. },
  211. ],
  212. nextSteps: () => [
  213. {
  214. id: 'cocoapods-carthage',
  215. name: t('CocoaPods/Carthage'),
  216. description: t(
  217. 'Learn about integrating Sentry into your project using CocoaPods or Carthage.'
  218. ),
  219. link: 'https://docs.sentry.io/platforms/apple/install/',
  220. },
  221. {
  222. id: 'debug-symbols',
  223. name: t('Debug Symbols'),
  224. description: t('Symbolicate and get readable stacktraces in your Sentry errors.'),
  225. link: 'https://docs.sentry.io/platforms/apple/dsym/',
  226. },
  227. {
  228. id: 'swiftui',
  229. name: t('SwiftUI'),
  230. description: t('Learn about our first class integration with SwiftUI.'),
  231. link: 'https://docs.sentry.io/platforms/apple/tracing/instrumentation/swiftui-instrumentation/',
  232. },
  233. ],
  234. };
  235. export const appleFeedbackOnboarding: OnboardingConfig = {
  236. introduction: () => getCrashReportApiIntroduction(),
  237. install: (params: Params) => [
  238. {
  239. type: StepType.INSTALL,
  240. description: getCrashReportInstallDescription(),
  241. configurations: [
  242. {
  243. code: [
  244. {
  245. label: 'Swift',
  246. value: 'swift',
  247. language: 'swift',
  248. code: `import Sentry
  249. let eventId = SentrySDK.capture(message: "My message.")
  250. let userFeedback = UserFeedback(eventId: eventId)
  251. userFeedback.comments = "It broke."
  252. userFeedback.email = "john.doe@example.com"
  253. userFeedback.name = "John Doe"
  254. SentrySDK.capture(userFeedback: userFeedback)`,
  255. },
  256. {
  257. label: 'Objective-C',
  258. value: 'c',
  259. language: 'c',
  260. code: `@import Sentry;
  261. SentryId *eventId = [SentrySDK captureMessage:@"My message"];
  262. SentryUserFeedback *userFeedback = [[SentryUserFeedback alloc] initWithEventId:eventId];
  263. userFeedback.comments = @"It broke.";
  264. userFeedback.email = @"john.doe@example.com";
  265. userFeedback.name = @"John Doe";
  266. [SentrySDK captureUserFeedback:userFeedback];`,
  267. },
  268. ],
  269. },
  270. {
  271. description: tct(
  272. 'To capture user feedback regarding a crash, use the [code:SentryOptions.onCrashedLastRun] callback. This callback gets called shortly after the initialization of the SDK when the last program execution terminated with a crash. It is not guaranteed that this is called on the main thread.',
  273. {code: <code />}
  274. ),
  275. code: [
  276. {
  277. label: 'Swift',
  278. value: 'swift',
  279. language: 'swift',
  280. code: `import Sentry
  281. SentrySDK.start { options in
  282. options.dsn = "${params.dsn.public}"
  283. options.onCrashedLastRun = { event in
  284. // capture user feedback
  285. }
  286. }
  287. `,
  288. },
  289. {
  290. label: 'Objective-C',
  291. value: 'c',
  292. language: 'c',
  293. code: `@import Sentry;
  294. [SentrySDK startWithConfigureOptions:^(SentryOptions *options) {
  295. options.dsn = @"${params.dsn.public}";
  296. options.onCrashedLastRun = ^void(SentryEvent * _Nonnull event) {
  297. // capture user feedback
  298. };
  299. }];`,
  300. },
  301. ],
  302. },
  303. ],
  304. },
  305. ],
  306. configure: () => [],
  307. verify: () => [],
  308. nextSteps: () => [],
  309. };
  310. const docs: Docs = {
  311. onboarding,
  312. feedbackOnboardingCrashApi: appleFeedbackOnboarding,
  313. crashReportOnboarding: appleFeedbackOnboarding,
  314. };
  315. export default docs;