macos.tsx 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  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. params.isPerformanceSelected
  29. ? `
  30. // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
  31. // We recommend adjusting this value in production.
  32. options.tracesSampleRate = 1.0`
  33. : ''
  34. }${
  35. params.isProfilingSelected
  36. ? `
  37. // Sample rate for profiling, applied on top of TracesSampleRate.
  38. // We recommend adjusting this value in production.
  39. options.profilesSampleRate = 1.0`
  40. : ''
  41. }
  42. }
  43. return true
  44. }`;
  45. const getConfigurationSnippetSwiftUi = (params: Params) => `
  46. import Sentry
  47. @main
  48. struct SwiftUIApp: App {
  49. init() {
  50. SentrySDK.start { options in
  51. options.dsn = "${params.dsn.public}"
  52. options.debug = true // Enabling debug when first installing is always helpful${
  53. params.isPerformanceSelected
  54. ? `
  55. // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
  56. // We recommend adjusting this value in production.
  57. options.tracesSampleRate = 1.0`
  58. : ''
  59. }${
  60. params.isProfilingSelected
  61. ? `
  62. // Sample rate for profiling, applied on top of TracesSampleRate.
  63. // We recommend adjusting this value in production.
  64. options.profilesSampleRate = 1.0`
  65. : ''
  66. }
  67. }
  68. }
  69. }`;
  70. const getVerifySnippet = () => `
  71. let button = UIButton(type: .roundedRect)
  72. button.frame = CGRect(x: 20, y: 50, width: 100, height: 30)
  73. button.setTitle("Break the world", for: [])
  74. button.addTarget(self, action: #selector(self.breakTheWorld(_:)), for: .touchUpInside)
  75. view.addSubview(button)
  76. @IBAction func breakTheWorld(_ sender: AnyObject) {
  77. fatalError("Break the world")
  78. }`;
  79. const onboarding: OnboardingConfig = {
  80. install: params => [
  81. {
  82. type: StepType.INSTALL,
  83. description: (
  84. <p>
  85. {tct(
  86. '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:',
  87. {
  88. alternateMethods: (
  89. <ExternalLink href="https://docs.sentry.io/platforms/apple/install/" />
  90. ),
  91. addPackage: <strong />,
  92. }
  93. )}
  94. </p>
  95. ),
  96. configurations: [
  97. {
  98. language: 'url',
  99. code: `https://github.com/getsentry/sentry-cocoa.git`,
  100. },
  101. {
  102. description: (
  103. <p>
  104. {tct(
  105. 'Alternatively, when your project uses a [packageSwift: Package.swift] file to manage dependencies, you can specify the target with:',
  106. {
  107. packageSwift: <code />,
  108. }
  109. )}
  110. </p>
  111. ),
  112. language: 'swift',
  113. partialLoading: params.sourcePackageRegistries.isLoading,
  114. code: getInstallSnippet(params),
  115. },
  116. ],
  117. },
  118. ],
  119. configure: params => [
  120. {
  121. type: StepType.CONFIGURE,
  122. description: (
  123. <p>
  124. {tct(
  125. 'Make sure you initialize the SDK as soon as possible in your application lifecycle e.g. in your [appDelegate:] method:',
  126. {
  127. appDelegate: (
  128. <code>
  129. - [NSAppDelegate applicationDidFinishLaunchingWithNotification:]
  130. </code>
  131. ),
  132. }
  133. )}
  134. </p>
  135. ),
  136. configurations: [
  137. {
  138. language: 'swift',
  139. code: getConfigurationSnippet(params),
  140. },
  141. {
  142. description: (
  143. <p>
  144. {tct(
  145. "When using SwiftUI and your app doesn't implement an app delegate, initialize the SDK within the [initializer: App conformer's initializer]:",
  146. {
  147. initializer: (
  148. <ExternalLink href="https://developer.apple.com/documentation/swiftui/app/main()" />
  149. ),
  150. }
  151. )}
  152. </p>
  153. ),
  154. language: 'swift',
  155. code: getConfigurationSnippetSwiftUi(params),
  156. },
  157. ],
  158. },
  159. ],
  160. verify: () => [
  161. {
  162. type: StepType.VERIFY,
  163. description: (
  164. <p>
  165. {tct(
  166. '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].',
  167. {
  168. viewController: <code />,
  169. }
  170. )}
  171. </p>
  172. ),
  173. configurations: [
  174. {
  175. language: 'swift',
  176. code: getVerifySnippet(),
  177. },
  178. ],
  179. },
  180. ],
  181. nextSteps: () => [
  182. {
  183. id: 'cocoapods-carthage',
  184. name: t('CocoaPods/Carthage'),
  185. description: t(
  186. 'Learn about integrating Sentry into your project using CocoaPods or Carthage.'
  187. ),
  188. link: 'https://docs.sentry.io/platforms/apple/install/',
  189. },
  190. {
  191. id: 'debug-symbols',
  192. name: t('Debug Symbols'),
  193. description: t('Symbolicate and get readable stacktraces in your Sentry errors.'),
  194. link: 'https://docs.sentry.io/platforms/apple/dsym/',
  195. },
  196. {
  197. id: 'swiftui',
  198. name: t('SwiftUI'),
  199. description: t('Learn about our first class integration with SwiftUI.'),
  200. link: 'https://docs.sentry.io/platforms/apple/tracing/instrumentation/swiftui-instrumentation/',
  201. },
  202. ],
  203. };
  204. export const appleFeedbackOnboarding: OnboardingConfig = {
  205. introduction: () => getCrashReportApiIntroduction(),
  206. install: (params: Params) => [
  207. {
  208. type: StepType.INSTALL,
  209. description: getCrashReportInstallDescription(),
  210. configurations: [
  211. {
  212. code: [
  213. {
  214. label: 'Swift',
  215. value: 'swift',
  216. language: 'swift',
  217. code: `import Sentry
  218. let eventId = SentrySDK.capture(message: "My message.")
  219. let userFeedback = UserFeedback(eventId: eventId)
  220. userFeedback.comments = "It broke."
  221. userFeedback.email = "john.doe@example.com"
  222. userFeedback.name = "John Doe"
  223. SentrySDK.capture(userFeedback: userFeedback)`,
  224. },
  225. {
  226. label: 'Objective-C',
  227. value: 'c',
  228. language: 'c',
  229. code: `@import Sentry;
  230. SentryId *eventId = [SentrySDK captureMessage:@"My message"];
  231. SentryUserFeedback *userFeedback = [[SentryUserFeedback alloc] initWithEventId:eventId];
  232. userFeedback.comments = @"It broke.";
  233. userFeedback.email = @"john.doe@example.com";
  234. userFeedback.name = @"John Doe";
  235. [SentrySDK captureUserFeedback:userFeedback];`,
  236. },
  237. ],
  238. },
  239. {
  240. description: tct(
  241. '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.',
  242. {code: <code />}
  243. ),
  244. code: [
  245. {
  246. label: 'Swift',
  247. value: 'swift',
  248. language: 'swift',
  249. code: `import Sentry
  250. SentrySDK.start { options in
  251. options.dsn = "${params.dsn.public}"
  252. options.onCrashedLastRun = { event in
  253. // capture user feedback
  254. }
  255. }
  256. `,
  257. },
  258. {
  259. label: 'Objective-C',
  260. value: 'c',
  261. language: 'c',
  262. code: `@import Sentry;
  263. [SentrySDK startWithConfigureOptions:^(SentryOptions *options) {
  264. options.dsn = @"${params.dsn.public}";
  265. options.onCrashedLastRun = ^void(SentryEvent * _Nonnull event) {
  266. // capture user feedback
  267. };
  268. }];`,
  269. },
  270. ],
  271. },
  272. ],
  273. },
  274. ],
  275. configure: () => [],
  276. verify: () => [],
  277. nextSteps: () => [],
  278. };
  279. const docs: Docs = {
  280. onboarding,
  281. feedbackOnboardingCrashApi: appleFeedbackOnboarding,
  282. crashReportOnboarding: appleFeedbackOnboarding,
  283. };
  284. export default docs;