Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions static/app/gettingStartedDocs/apple/ios.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,26 @@ describe('apple-ios onboarding docs', function () {
expect(screen.getByRole('heading', {name: 'Verify'})).toBeInTheDocument();
});

it('renders swift onboarding docs correctly', async function () {
renderWithOnboardingLayout(docs, {
selectedProducts: [ProductSolution.ERROR_MONITORING],
selectedOptions: {
installationMode: InstallationMode.MANUAL_SWIFT,
},
});

expect(
await screen.findAllByText(
textWithMarkupMatcher(/throw MyCustomError\.myFirstIssue/)
)
).toHaveLength(1);
});

it('renders performance onboarding docs correctly', async function () {
renderWithOnboardingLayout(docs, {
selectedProducts: [ProductSolution.PERFORMANCE_MONITORING],
selectedOptions: {
installationMode: InstallationMode.MANUAL,
installationMode: InstallationMode.MANUAL_SWIFT,
},
});

Expand All @@ -34,7 +49,7 @@ describe('apple-ios onboarding docs', function () {
it('renders transaction profiling', async function () {
renderWithOnboardingLayout(docs, {
selectedOptions: {
installationMode: InstallationMode.MANUAL,
installationMode: InstallationMode.MANUAL_SWIFT,
},
});

Expand All @@ -61,7 +76,7 @@ describe('apple-ios onboarding docs', function () {
docs,
{
selectedOptions: {
installationMode: InstallationMode.MANUAL,
installationMode: InstallationMode.MANUAL_SWIFT,
},
},
{
Expand All @@ -87,4 +102,17 @@ describe('apple-ios onboarding docs', function () {
expect(lifecycleElements).toHaveLength(2);
lifecycleElements.forEach(element => expect(element).toBeInTheDocument());
});

it('renders manual objective-c docs correctly', async function () {
renderWithOnboardingLayout(docs, {
selectedProducts: [ProductSolution.ERROR_MONITORING],
selectedOptions: {
installationMode: InstallationMode.MANUAL_OBJECTIVE_C,
},
});

expect(
await screen.findAllByText(textWithMarkupMatcher(/@import Sentry;/))
).toHaveLength(1);
});
});
167 changes: 129 additions & 38 deletions static/app/gettingStartedDocs/apple/ios.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import {getWizardInstallSnippet} from 'sentry/utils/gettingStartedDocs/mobileWiz

export enum InstallationMode {
AUTO = 'auto',
MANUAL = 'manual',
MANUAL_SWIFT = 'manual-swift',
MANUAL_OBJECTIVE_C = 'manual-objective-c',
}

const platformOptions = {
Expand All @@ -32,8 +33,12 @@ const platformOptions = {
value: InstallationMode.AUTO,
},
{
label: t('Manual'),
value: InstallationMode.MANUAL,
label: t('Manual (Swift)'),
value: InstallationMode.MANUAL_SWIFT,
},
{
label: t('Manual (Objective-C)'),
value: InstallationMode.MANUAL_OBJECTIVE_C,
},
],
defaultValue: InstallationMode.AUTO,
Expand All @@ -46,14 +51,19 @@ type Params = DocsParams<PlatformOptions>;
const isAutoInstall = (params: Params) =>
params.platformOptions.installationMode === InstallationMode.AUTO;

const isManualSwift = (params: Params) =>
params.platformOptions.installationMode === InstallationMode.MANUAL_SWIFT;

const selectedLanguage = (params: Params) => (isManualSwift(params) ? 'swift' : 'objc');

const getManualInstallSnippet = (params: Params) => `
.package(url: "https://github.com/getsentry/sentry-cocoa", from: "${getPackageVersion(
params,
'sentry.cocoa',
'8.49.0'
)}"),`;

const getConfigurationSnippet = (params: Params) => `
const getConfigurationSnippetSwift = (params: Params) => `
import Sentry

// ....
Expand Down Expand Up @@ -108,6 +118,58 @@ func application(_ application: UIApplication,
return true
}`;

const getConfigurationSnippetObjectiveC = (params: Params) => `
@import Sentry;

// ....

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[SentrySDK startWithConfigureOptions:^(SentryOptions *options) {
options.dsn = "${params.dsn.public}";
options.debug = YES; // Enabling debug when first installing is always helpful

// Adds IP for users.
// For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
options.sendDefaultPii = YES;${
params.isPerformanceSelected
? `

// Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
// We recommend adjusting this value in production.
options.tracesSampleRate = @1.0;`
: ''
}${
params.isProfilingSelected &&
params.profilingOptions?.defaultProfilingMode !== 'continuous'
? `

// Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
// We recommend adjusting this value in production.
options.tracesSampleRate = @1.0;`
: params.isProfilingSelected &&
params.profilingOptions?.defaultProfilingMode === 'continuous'
? `

// Configure the profiler to start profiling when there is an active root span
// For more information, visit: https://docs.sentry.io/platforms/apple/profiling/
[options setConfigureProfiling:^(SentryProfileOptions * _Nonnull profiling) {
profiling.lifecycle = SentryProfileLifecycleTrace;
profiling.sessionSampleRate = 1.0;
}];`
: ''
}${
params.isReplaySelected
? `

// Record Session Replays for 100% of Errors and 10% of Sessions
options.sessionReplay.onErrorSampleRate = 1.0;
options.sessionReplay.sessionSampleRate = 0.1;`
: ''
}
}];
return YES;
}`;

const getConfigurationSnippetSwiftUi = (params: Params) => `
import Sentry

Expand Down Expand Up @@ -160,15 +222,37 @@ struct SwiftUIApp: App {
}
}`;

const getVerifySnippet = () => `
let button = UIButton(type: .roundedRect)
button.frame = CGRect(x: 20, y: 50, width: 100, height: 30)
button.setTitle("Break the world", for: [])
button.addTarget(self, action: #selector(self.breakTheWorld(_:)), for: .touchUpInside)
view.addSubview(button)
const getVerifySnippet = (params: Params) =>
isManualSwift(params)
? `
enum MyCustomError: Error {
case myFirstIssue
}

func thisFunctionThrows() throws {
throw MyCustomError.myFirstIssue
}

@IBAction func breakTheWorld(_ sender: AnyObject) {
fatalError("Break the world")
func verifySentrySDK() {
do {
try thisFunctionThrows()
} catch {
SentrySDK.capture(error: error)
}
}`
: `
- (void)thisFunctionReturnsAnError:(NSError **)error {
*error = [NSError errorWithDomain:@"com.example.myapp"
code:1001
userInfo:@{
NSLocalizedDescriptionKey: @"Something went wrong."
}];
}

- (void)verifySentrySDK {
NSError *error = nil;
[self thisFunctionReturnsAnError:&error];
[SentrySDK captureError:error];
}`;

const getReplaySetupSnippet = (params: Params) => `
Expand Down Expand Up @@ -314,28 +398,35 @@ const onboarding: OnboardingConfig<PlatformOptions> = {
)}
</p>
),
configurations: [
{
language: 'swift',
code: getConfigurationSnippet(params),
},
{
description: (
<p>
{tct(
"When using SwiftUI and your app doesn't implement an app delegate, initialize the SDK within the [initializer: App conformer's initializer]:",
{
initializer: (
<ExternalLink href="https://developer.apple.com/documentation/swiftui/app/main()" />
),
}
)}
</p>
),
language: 'swift',
code: getConfigurationSnippetSwiftUi(params),
},
],
configurations: isManualSwift(params)
? [
{
language: 'swift',
code: getConfigurationSnippetSwift(params),
},
{
description: (
<p>
{tct(
"When using SwiftUI and your app doesn't implement an app delegate, initialize the SDK within the [initializer: App conformer's initializer]:",
{
initializer: (
<ExternalLink href="https://developer.apple.com/documentation/swiftui/app/main()" />
),
}
)}
</p>
),
language: 'swift',
code: getConfigurationSnippetSwiftUi(params),
},
]
: [
{
language: 'objc',
code: getConfigurationSnippetObjectiveC(params),
},
],
},
],
verify: params =>
Expand All @@ -354,17 +445,17 @@ const onboarding: OnboardingConfig<PlatformOptions> = {
description: (
<p>
{tct(
'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].',
'This snippet contains an intentional error you can use to test that errors are uploaded to Sentry correctly. You can call [verifySentrySDK: verifySentrySDK()] from where you want to test it.',
{
viewController: <code />,
verifySentrySDK: <code />,
}
)}
</p>
),
configurations: [
{
language: 'swift',
code: getVerifySnippet(),
language: selectedLanguage(params),
code: getVerifySnippet(params),
},
],
},
Expand Down
Loading