Skip to content

Commit 11bbfa6

Browse files
committed
WIP
1 parent d1abd69 commit 11bbfa6

27 files changed

+235
-2210
lines changed

Samples/SentrySampleShared/SentrySampleShared/SentrySDKOverrides.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,6 @@ public enum SentrySDKOverrides: String, CaseIterable {
159159
case tracing = "Tracing"
160160

161161
public enum Profiling: String, SentrySDKOverride {
162-
#if !SDK_V9
163-
case sampleRate = "--io.sentry.profiling.profilesSampleRate"
164-
case samplerValue = "--io.sentry.profiling.profilesSamplerValue"
165-
#endif // !SDK_V9
166162
case disableAppStartProfiling = "--io.sentry.profiling.disable-app-start-profiling"
167163
case manualLifecycle = "--io.sentry.profiling.profile-lifecycle-manual"
168164
case sessionSampleRate = "--io.sentry.profiling.profile-session-sample-rate"
@@ -266,11 +262,7 @@ private extension SentrySDKOverride {
266262
extension SentrySDKOverrides.Profiling {
267263
public var overrideType: OverrideType {
268264
switch self {
269-
#if SDK_V9
270265
case .sessionSampleRate: return .float
271-
#else
272-
case .sampleRate, .samplerValue, .sessionSampleRate: return .float
273-
#endif // !SDK_V9
274266
case .disableAppStartProfiling, .manualLifecycle, .disableUIProfiling, .slowLoadMethod, .immediateStop: return .boolean
275267
}
276268
}
@@ -363,11 +355,7 @@ extension SentrySDKOverrides.Special {
363355
extension SentrySDKOverrides.Profiling {
364356
public var ignoresDisableEverything: Bool {
365357
switch self {
366-
#if SDK_V9
367358
case .sessionSampleRate, .manualLifecycle, .slowLoadMethod, .immediateStop: return true
368-
#else
369-
case .sampleRate, .samplerValue, .sessionSampleRate, .manualLifecycle, .slowLoadMethod, .immediateStop: return true
370-
#endif // SDK_V9
371359
case .disableAppStartProfiling, .disableUIProfiling: return false
372360
}
373361
}

Samples/SentrySampleShared/SentrySampleShared/SentrySDKWrapper.swift

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,136 @@ extension SentrySDKWrapper {
348348
config.onSubmitSuccess = { info in
349349
let name = info["name"] ?? "$shakespearean_insult_name"
350350
let alert = UIAlertController(title: "Thanks?", message: "We have enough jank of our own, we really didn't need yours too, \(name).", preferredStyle: .alert)
351+
alert.addAction(.init(title: "Deal with it 🕶️", style: .default))
352+
UIApplication.shared.delegate?.window??.rootViewController?.present(alert, animated: true)
353+
354+
// if there's a screenshot's Data in this dictionary, JSONSerialization crashes _even though_ there's a `try?`, so we'll write the base64 encoding of it
355+
var infoToWriteToFile = info
356+
if let attachments = info["attachments"] as? [Any], let screenshot = attachments.first as? Data {
357+
infoToWriteToFile["attachments"] = [screenshot.base64EncodedString()]
358+
}
359+
360+
let jsonData = (try? JSONSerialization.data(withJSONObject: infoToWriteToFile, options: .sortedKeys)) ?? Data()
361+
updateHookMarkers(forEvent: "onSubmitSuccess", with: jsonData.base64EncodedString())
362+
}
363+
config.onSubmitError = { error in
364+
let alert = UIAlertController(title: "D'oh", message: "You tried to report jank, and encountered more jank. The jank has you now: \(error).", preferredStyle: .alert)
365+
alert.addAction(.init(title: "Derp", style: .default))
366+
UIApplication.shared.delegate?.window??.rootViewController?.present(alert, animated: true)
367+
let nserror = error as NSError
368+
let missingFieldsSorted = (nserror.userInfo["missing_fields"] as? [String])?.sorted().joined(separator: ";") ?? ""
369+
updateHookMarkers(forEvent: "onSubmitError", with: "\(nserror.domain);\(nserror.code);\(nserror.localizedDescription);\(missingFieldsSorted)")
370+
}
371+
}
372+
373+
func updateHookMarkers(forEvent name: String, with contents: String? = nil) {
374+
guard let appSupportDirectory = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).first else {
375+
print("[iOS-Swift] Couldn't retrieve path to application support directory.")
376+
return
377+
}
378+
379+
let fm = FileManager.default
380+
let dir = "\(appSupportDirectory)/io.sentry/feedback"
381+
let isDirectory = UnsafeMutablePointer<ObjCBool>.allocate(capacity: 1)
382+
isDirectory.initialize(to: ObjCBool(false))
383+
let exists = fm.fileExists(atPath: dir, isDirectory: isDirectory)
384+
if exists, !isDirectory.pointee.boolValue {
385+
print("[iOS-Swift] Found a file named \(dir) which is not a directory. Removing it...")
386+
do {
387+
try fm.removeItem(atPath: dir)
388+
} catch {
389+
print("[iOS-Swift] Couldn't remove existing file \(dir): \(error).")
390+
return
391+
}
392+
} else if !exists {
393+
do {
394+
try fm.createDirectory(atPath: dir, withIntermediateDirectories: true)
395+
} catch {
396+
print("[iOS-Swift] Couldn't create directory structure for user feedback form hook marker files: \(error).")
397+
return
398+
}
399+
}
400+
401+
createHookFile(path: "\(dir)/\(name)", contents: contents)
402+
403+
switch name {
404+
case "onFormOpen": removeHookFile(path: "\(dir)/onFormClose")
405+
case "onFormClose": removeHookFile(path: "\(dir)/onFormOpen")
406+
case "onSubmitSuccess": removeHookFile(path: "\(dir)/onSubmitError")
407+
case "onSubmitError": removeHookFile(path: "\(dir)/onSubmitSuccess")
408+
default: fatalError("Unexpected marker file name")
409+
}
410+
}
411+
412+
func createHookFile(path: String, contents: String?) {
413+
if let contents = contents {
414+
do {
415+
try contents.write(to: URL(fileURLWithPath: path), atomically: false, encoding: .utf8)
416+
} catch {
417+
print("[iOS-Swift] Couldn't write contents into user feedback form hook marker file at \(path).")
418+
}
419+
} else if !FileManager.default.createFile(atPath: path, contents: nil) {
420+
print("[iOS-Swift] Couldn't create user feedback form hook marker file at \(path).")
421+
} else {
422+
print("[iOS-Swift] Created user feedback form hook marker file at \(path).")
423+
}
424+
}
425+
426+
func removeHookFile(path: String) {
427+
let fm = FileManager.default
428+
guard fm.fileExists(atPath: path) else { return }
429+
do {
430+
try fm.removeItem(atPath: path)
431+
} catch {
432+
print("[iOS-Swift] Couldn't remove user feedback form hook marker file \(path): \(error).")
433+
}
434+
}
435+
}
436+
#endif // !os(macOS) && !os(tvOS) && !os(watchOS) && !os(visionOS)
437+
438+
// MARK: Convenience access to SDK configuration via launch arg / environment variable
439+
extension SentrySDKWrapper {
440+
public static let defaultDSN = "https://[email protected]/5428557"
441+
442+
var args: [String] {
443+
return ProcessInfo.processInfo.arguments
444+
}
445+
446+
var env: [String: String] {
447+
return ProcessInfo.processInfo.environment
448+
}
449+
450+
/// For testing purposes, we want to be able to change the DSN and store it to disk. In a real app, you shouldn't need this behavior.
451+
var dsn: String? {
452+
do {
453+
if let dsn = env[SentrySDKOverrides.Special.dsn.rawValue] {
454+
try DSNStorage.shared.saveDSN(dsn: dsn)
455+
}
456+
return try DSNStorage.shared.getDSN() ?? SentrySDKWrapper.defaultDSN
457+
} catch {
458+
print("[iOS-Swift] Error encountered while reading stored DSN: \(error)")
459+
}
460+
return nil
461+
}
462+
463+
/// Whether or not profiling benchmarks are being run; this requires disabling certain other features for proper functionality.
464+
var isBenchmarking: Bool { args.contains("--io.sentry.test.benchmarking") }
465+
var isUITest: Bool { env[SentrySDKOverrides.Other.environment.rawValue] == "ui-tests" }
466+
}
467+
468+
// MARK: Profiling configuration
469+
#if !os(tvOS) && !os(watchOS) && !os(visionOS)
470+
extension SentrySDKWrapper {
471+
func configureProfiling(_ options: Options) {
472+
if !SentrySDKOverrides.Profiling.disableUIProfiling.boolValue {
473+
options.configureProfiling = {
474+
$0.lifecycle = SentrySDKOverrides.Profiling.manualLifecycle.boolValue ? .manual : .trace
475+
$0.sessionSampleRate = SentrySDKOverrides.Profiling.sessionSampleRate.floatValue ?? 1
476+
$0.profileAppStarts = !SentrySDKOverrides.Profiling.disableAppStartProfiling.boolValue
477+
}
478+
}
479+
}
480+
}
481+
#endif // !os(tvOS) && !os(watchOS) && !os(visionOS)
482+
483+
// swiftlint:enable file_length function_body_length

Samples/iOS-ObjectiveC/iOS-ObjectiveC/AppDelegate.m

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,27 +51,6 @@ - (BOOL)application:(UIApplication *)application
5151
};
5252
}
5353

54-
#if !SDK_V9
55-
if (env[@"--io.sentry.profiling.profilesSampleRate"] != nil) {
56-
# pragma clang diagnostic push
57-
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
58-
options.profilesSampleRate =
59-
@([env[@"--io.sentry.profiling.profilesSampleRate"] floatValue]);
60-
# pragma clang diagnostic pop
61-
}
62-
63-
if (env[@"--io.sentry.profilesSamplerValue"] != nil) {
64-
# pragma clang diagnostic push
65-
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
66-
options.profilesSampler
67-
= ^NSNumber *_Nullable(SentrySamplingContext *_Nonnull samplingContext)
68-
{
69-
return @([env[@"--io.sentry.profilesSamplerValue"] floatValue]);
70-
};
71-
# pragma clang diagnostic pop
72-
}
73-
#endif // !SDK_V9
74-
7554
SentryHttpStatusCodeRange *httpStatusCodeRange =
7655
[[SentryHttpStatusCodeRange alloc] initWithMin:400 max:599];
7756
options.failedRequestStatusCodes = @[ httpStatusCodeRange ];

Samples/iOS-Swift/iOS-Swift/Profiling/ProfilingViewController.swift

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ class ProfilingViewController: UIViewController, UITextFieldDelegate {
5959
}
6060

6161
@IBAction func sampleRateEdited(_ sender: UITextField) {
62-
#if !SDK_V9
63-
var sampleRate = SentrySDKOverrides.Profiling.sampleRate
64-
sampleRate.floatValue = getSampleRateOverride(field: sender)
65-
#endif // !SDK_V9
6662
}
6763

6864
@IBAction func tracesSampleRateEdited(_ sender: UITextField) {
@@ -77,11 +73,6 @@ class ProfilingViewController: UIViewController, UITextFieldDelegate {
7773

7874
@IBAction func defineProfilesSampleRateToggled(_ sender: UISwitch) {
7975
sampleRateField.isEnabled = sender.isOn
80-
81-
#if !SDK_V9
82-
var sampleRate = SentrySDKOverrides.Profiling.sampleRate
83-
sampleRate.floatValue = getSampleRateOverride(field: sampleRateField)
84-
#endif // !SDK_V9
8576
}
8677

8778
@IBAction func defineTracesSampleRateToggled(_ sender: UISwitch) {
@@ -169,18 +160,6 @@ private extension ProfilingViewController {
169160
func optionsConfiguration() {
170161
guard let options = SentrySDKInternal.currentHub().getClient()?.options else { return }
171162

172-
#if !SDK_V9
173-
if let sampleRate = options.profilesSampleRate {
174-
sampleRateField.text = String(format: "%.2f", sampleRate.floatValue)
175-
sampleRateField.isEnabled = true
176-
profilesSampleRateSwitch.isOn = true
177-
} else {
178-
sampleRateField.isEnabled = false
179-
sampleRateField.text = "nil"
180-
profilesSampleRateSwitch.isOn = false
181-
}
182-
#endif // !SDK_V9
183-
184163
if let sampleRate = options.tracesSampleRate {
185164
tracesSampleRateField.text = String(format: "%.2f", sampleRate.floatValue)
186165
tracesSampleRateField.isEnabled = true

Sources/Sentry/Profiling/SentryLaunchProfiling.m

Lines changed: 12 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@
2929
NSString *const kSentryLaunchProfileConfigKeyTracesSampleRand = @"traces.sample_rand";
3030
NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate = @"profiles";
3131
NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRand = @"profiles.sample_rand";
32-
# if !SDK_V9
33-
NSString *const kSentryLaunchProfileConfigKeyContinuousProfiling = @"continuous-profiling";
34-
# endif // !SDK_V9
3532
NSString *const kSentryLaunchProfileConfigKeyContinuousProfilingV2
3633
= @"continuous-profiling-v2-enabled";
3734
NSString *const kSentryLaunchProfileConfigKeyContinuousProfilingV2Lifecycle
@@ -84,15 +81,6 @@
8481
profileOptions:profileOptions];
8582
}
8683

87-
void
88-
_sentry_continuousProfilingV1_startLaunchProfile(BOOL shouldWaitForFullDisplay)
89-
{
90-
sentry_profileConfiguration =
91-
[[SentryProfileConfiguration alloc] initWaitingForFullDisplay:shouldWaitForFullDisplay
92-
continuousV1:YES];
93-
[SentryContinuousProfiler start];
94-
}
95-
9684
/**
9785
* Hydrate any relevant launch profiling options persisted from the previous launch and start a
9886
* trace that will automatically start a manual lifecycle continuous profile (v2)
@@ -270,22 +258,10 @@
270258
BOOL isContinuousV2 =
271259
[persistedLaunchConfigOptionsDict[kSentryLaunchProfileConfigKeyContinuousProfilingV2]
272260
boolValue];
273-
# if !SDK_V9
274-
BOOL isContinuousV1 =
275-
[persistedLaunchConfigOptionsDict[kSentryLaunchProfileConfigKeyContinuousProfiling]
276-
boolValue];
277-
if (isContinuousV1 && isContinuousV2) {
278-
SENTRY_LOG_WARN(@"Launch profile misconfiguration detected.");
279-
_sentry_cleanUpConfigFile();
280-
return;
281-
}
282-
# else
283-
BOOL isContinuousV1 = false;
284-
# endif // !SDK_V9
285261

286262
SentrySamplerDecision *decision
287263
= _sentry_profileSampleDecision(persistedLaunchConfigOptionsDict);
288-
if (!isContinuousV1 && nil == decision) {
264+
if (nil == decision) {
289265
SENTRY_LOG_DEBUG(@"Couldn't hydrate the persisted sample decision.");
290266
_sentry_cleanUpConfigFile();
291267
return;
@@ -303,13 +279,6 @@
303279

304280
BOOL shouldWaitForFullDisplay = shouldWaitForFullDisplayValue.boolValue;
305281

306-
if (isContinuousV1) {
307-
SENTRY_LOG_DEBUG(@"Starting continuous launch profile v1.");
308-
_sentry_continuousProfilingV1_startLaunchProfile(shouldWaitForFullDisplay);
309-
_sentry_cleanUpConfigFile();
310-
return;
311-
}
312-
313282
SentryProfileOptions *profileOptions = nil;
314283
if (isContinuousV2) {
315284
SENTRY_LOG_DEBUG(@"Starting continuous launch profile v2.");
@@ -337,8 +306,7 @@
337306
SentryProfileLifecycleTrace, shouldWaitForFullDisplay);
338307
} else {
339308
sentry_profileConfiguration =
340-
[[SentryProfileConfiguration alloc] initWaitingForFullDisplay:shouldWaitForFullDisplay
341-
continuousV1:NO];
309+
[[SentryProfileConfiguration alloc] initWaitingForFullDisplay:shouldWaitForFullDisplay];
342310
}
343311

344312
// trace lifecycle UI profiling (continuous profiling v2) and trace-based profiling both join
@@ -366,43 +334,22 @@
366334
[NSMutableDictionary<NSString *, NSNumber *> dictionary];
367335
configDict[kSentryLaunchProfileConfigKeyWaitForFullDisplay] =
368336
@(options.enableTimeToFullDisplayTracing);
369-
# if !SDK_V9
370-
if ([options isContinuousProfilingEnabled]) {
371-
# endif // !SDK_V9
372-
if ([options isContinuousProfilingV2Enabled]) {
373-
SENTRY_LOG_DEBUG(@"Configuring continuous launch profile v2.");
374-
configDict[kSentryLaunchProfileConfigKeyContinuousProfilingV2] = @YES;
375-
configDict[kSentryLaunchProfileConfigKeyContinuousProfilingV2Lifecycle] =
376-
@(options.profiling.lifecycle);
377-
if (options.profiling.lifecycle == SentryProfileLifecycleTrace) {
378-
configDict[kSentryLaunchProfileConfigKeyTracesSampleRate]
379-
= config.tracesDecision.sampleRate;
380-
configDict[kSentryLaunchProfileConfigKeyTracesSampleRand]
381-
= config.tracesDecision.sampleRand;
382-
}
383-
configDict[kSentryLaunchProfileConfigKeyProfilesSampleRate]
384-
= config.profilesDecision.sampleRate;
385-
configDict[kSentryLaunchProfileConfigKeyProfilesSampleRand]
386-
= config.profilesDecision.sampleRand;
387-
} else {
388-
# if !SDK_V9
389-
SENTRY_LOG_DEBUG(@"Configuring continuous launch profile.");
390-
configDict[kSentryLaunchProfileConfigKeyContinuousProfiling] = @YES;
391-
# endif // !SDK_V9
337+
if ([options isContinuousProfilingV2Enabled]) {
338+
SENTRY_LOG_DEBUG(@"Configuring continuous launch profile v2.");
339+
configDict[kSentryLaunchProfileConfigKeyContinuousProfilingV2] = @YES;
340+
configDict[kSentryLaunchProfileConfigKeyContinuousProfilingV2Lifecycle] =
341+
@(options.profiling.lifecycle);
342+
if (options.profiling.lifecycle == SentryProfileLifecycleTrace) {
343+
configDict[kSentryLaunchProfileConfigKeyTracesSampleRate]
344+
= config.tracesDecision.sampleRate;
345+
configDict[kSentryLaunchProfileConfigKeyTracesSampleRand]
346+
= config.tracesDecision.sampleRand;
392347
}
393-
# if !SDK_V9
394-
} else {
395-
SENTRY_LOG_DEBUG(@"Configuring trace launch profile.");
396-
configDict[kSentryLaunchProfileConfigKeyTracesSampleRate]
397-
= config.tracesDecision.sampleRate;
398-
configDict[kSentryLaunchProfileConfigKeyTracesSampleRand]
399-
= config.tracesDecision.sampleRand;
400348
configDict[kSentryLaunchProfileConfigKeyProfilesSampleRate]
401349
= config.profilesDecision.sampleRate;
402350
configDict[kSentryLaunchProfileConfigKeyProfilesSampleRand]
403351
= config.profilesDecision.sampleRand;
404352
}
405-
# endif // !SDK_V9
406353
writeAppLaunchProfilingConfigFile(configDict);
407354
}];
408355
}

Sources/Sentry/Profiling/SentryProfileConfiguration.m

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,12 @@ - (instancetype)initWithProfileOptions:(SentryProfileOptions *)options
2323
}
2424

2525
- (instancetype)initWaitingForFullDisplay:(BOOL)shouldWaitForFullDisplay
26-
continuousV1:(BOOL)continuousV1
2726
{
2827
if (!(self = [super init])) {
2928
return nil;
3029
}
3130

3231
_waitForFullDisplay = shouldWaitForFullDisplay;
33-
_isContinuousV1 = continuousV1;
3432
_isProfilingThisLaunch = YES;
3533
return self;
3634
}
@@ -39,7 +37,7 @@ - (instancetype)initContinuousProfilingV2WaitingForFullDisplay:(BOOL)shouldWaitF
3937
samplerDecision:(SentrySamplerDecision *)decision
4038
profileOptions:(SentryProfileOptions *)options
4139
{
42-
if (!(self = [self initWaitingForFullDisplay:shouldWaitForFullDisplay continuousV1:NO])) {
40+
if (!(self = [self initWaitingForFullDisplay:shouldWaitForFullDisplay])) {
4341
return nil;
4442
}
4543

0 commit comments

Comments
 (0)