diff --git a/docs/ai/agent-skills/sdk/ios/v7/SKILL.md b/docs/ai/agent-skills/sdk/ios/v7/SKILL.md
index e8158ea..b60c583 100644
--- a/docs/ai/agent-skills/sdk/ios/v7/SKILL.md
+++ b/docs/ai/agent-skills/sdk/ios/v7/SKILL.md
@@ -55,7 +55,7 @@ find . -name "AppDelegate.swift" -o -name "AppDelegate.m" 2>/dev/null | head -3
grep -r "@main" --include="*.swift" 2>/dev/null | head -3
# 6.x call sites that will not compile against 7.x
-grep -rnE "showReportController|showFeedbackController|setDefaultFeedbackGreeting|didReceiveNewFeedback|setView:.*asHidden|setView\(.*asHidden|addSecureRect\b|removeSecureRect\b|removeAllSecureRects|getAllSecureRects|isViewHidden|registerEvent|traceKey|registerNetworkEvent|removeNetworkEventFilter|setEmail|getEmail|clearEmail|getDeviceId|logAssert|hideKeyboard|testExceptionCrash|testSignalCrash|setDefaultCrashPriority|setDefaultErrorPriority|setDefaultBugPriority|Bugsee\.pause|Bugsee\.resume|\[Bugsee pause\]|\[Bugsee resume\]" \
+grep -rnE "showReportController|showFeedbackController|setDefaultFeedbackGreeting|didReceiveNewFeedback|setView:.*asHidden|setView\(.*asHidden|addSecureRect\b|removeSecureRect\b|removeAllSecureRects|getAllSecureRects|isViewHidden|registerEvent|traceKey|registerNetworkEvent|removeNetworkEventFilter|setEmail|getEmail|clearEmail|getDeviceId|logAssert|hideKeyboard|testExceptionCrash|testSignalCrash|BugseeExceptionLoggingOptions|BugseeMergingRulesSkipFramesKey|logException.*options:|logError:[^;]*labels:|logError\(error:.*labels:|setDefaultCrashPriority|setDefaultErrorPriority|setDefaultBugPriority|Bugsee\.pause|Bugsee\.resume|\[Bugsee pause\]|\[Bugsee resume\]" \
--include="*.swift" --include="*.m" --include="*.mm" . 2>/dev/null | grep -v "/Pods/" | head -40
# Raw option-key strings — the ONLY silent break in 7.x
@@ -171,7 +171,10 @@ Raising the deployment target to iOS 15 is a prerequisite for all of the above.
| `testExceptionCrash` / `testSignalCrash` | `testCrash` |
| `deleteCollectedDataOnDevice:` | `deleteCollectedDataOnDevice:completion:` |
| `uploadWithSummary:…:includeVideo:` | `uploadWithSummary:description:severity:labels:` |
-| `logError:labels:includeVideo:` | `logError:labels:` |
+| `logError:labels:includeVideo:` / `logError:labels:` | `logError:`; labels via `addLabels:` on the report in `bugseeAttachmentsForReport:` |
+| `logException:options:completion:` | `logException:completion:` / `logException:domain:skipFrames:completion:` |
+| `logException:reason:options:completion:` | `logException:reason:completion:` / `logException:reason:domain:skipFrames:completion:` |
+| `BugseeExceptionLoggingOptions` (`exceptionDomain`, `mergingRules[BugseeMergingRulesSkipFramesKey]`, `labels`) | `domain:` / `skipFrames:` parameters of `logException`; labels via `addLabels:` on the report in `bugseeAttachmentsForReport:` (applies to every error report, not one call); `includeVideo` has no replacement |
| Swift `Bugsee.launch(token:options:)` _(dictionary)_ | Swift `Bugsee.launch(token:dictionaryOptions:)` |
| Swift `Bugsee.relaunch(options:)` _(dictionary)_ | Swift `Bugsee.relaunch(dictionaryOptions:)` |
| Swift `Bugsee.uploadReport(_:)` | Swift `Bugsee.upload(_:)` |
@@ -189,7 +192,7 @@ Raising the deployment target to iOS 15 is a prerequisite for all of the above.
| `isViewHidden:` | — |
| `hideKeyboard:` | — |
| `setInternalSecureRectangles:` | — |
-| `logAssert:withLocation:` | Use `logException:reason:options:completion:` |
+| `logAssert:withLocation:` | Use `logException:reason:completion:` |
| `log:level:timestamp:` | `log:level:enforceFiltering:` takes the slot but does something different — it opts the message into the log filter |
| `setDefaultCrashPriority:` | `BugseeOptionReportingDefaultCrashPriority` at launch |
| `setDefaultErrorPriority:` | `BugseeOptionReportingDefaultErrorPriority` at launch |
diff --git a/docs/sdk/ios/v7/migration.mdx b/docs/sdk/ios/v7/migration.mdx
index 46427b1..1c17f1a 100644
--- a/docs/sdk/ios/v7/migration.mdx
+++ b/docs/sdk/ios/v7/migration.mdx
@@ -588,10 +588,12 @@ through. See [§9.3](#93-breadcrumbs).
| `showReportControllerWithSummary:description:severity:labels:` | `showReportDialogWithSummary:description:severity:labels:` |
| _(not available)_ | `showReportDialogWithSummary:description:` |
-### 7.2 `includeVideo:` overloads are gone
+### 7.2 `includeVideo:` overloads and `logError:labels:` are gone
-Both `uploadWithSummary:…:includeVideo:` and `logError:labels:includeVideo:` lose their
-last parameter. Drop the argument; the shorter overloads already exist in 6.x.
+`uploadWithSummary:…:includeVideo:` loses its last parameter. Drop the argument; the shorter
+overload already exists in 6.x. `logError:labels:includeVideo:` and `logError:labels:` are
+gone too: call `logError:`, and add labels in `bugseeAttachmentsForReport:` (see
+[§7.5](#75-bugseeexceptionloggingoptions-is-gone) for how far such a label reaches).
@@ -603,6 +605,12 @@ last parameter. Drop the argument; the shorter overloads already exist in 6.x.
// 7.x
[Bugsee uploadWithSummary:@"s" description:@"d" severity:BugseeSeverityHigh labels:nil];
+
+// 6.x
+[Bugsee logError:error labels:@[@"checkout"]];
+
+// 7.x: labels in bugseeAttachmentsForReport:, see §7.5
+[Bugsee logError:error];
```
@@ -615,6 +623,12 @@ Bugsee.upload(summary: "s", description: "d", severity: BugseeSeverityHigh,
// 7.x
Bugsee.upload(summary: "s", description: "d", severity: BugseeSeverityHigh, labels: nil)
+
+// 6.x
+Bugsee.logError(error: error, labels: ["checkout"])
+
+// 7.x: labels in bugsee(attachmentsFor:), see §7.5
+Bugsee.logError(error: error)
```
@@ -676,6 +690,85 @@ func bugsee(attachmentsFor report: BugseeReport) -> [BugseeAttachment] {
+### 7.5 `BugseeExceptionLoggingOptions` is gone
+
+`logException` takes the exception domain and the number of frames to skip as parameters, as
+on Android 7.x. `BugseeExceptionLoggingOptions`, `BugseeMergingRulesSkipFramesKey` and both
+`options:` overloads are removed.
+
+| 6.x | 7.x |
+| --- | --- |
+| `logException:options:completion:` with `nil` options | `logException:completion:` |
+| `logException:reason:options:completion:` with `nil` options | `logException:reason:completion:` |
+| `logException:options:completion:` with options | `logException:domain:skipFrames:completion:` |
+| `logException:reason:options:completion:` with options | `logException:reason:domain:skipFrames:completion:` |
+| `exceptionDomain` | `domain:` |
+| `mergingRules[BugseeMergingRulesSkipFramesKey]` | `skipFrames:` |
+| `labels` | `addLabels:` on the report in `bugseeAttachmentsForReport:` — see [§7.4](#74-the-report-the-delegate-receives-is-live) |
+| `includeVideo` | — leaving the video out of a single report is not supported |
+
+A 6.x call that passed an options object without setting `includeVideo` to `YES` filed its
+report without video. In 7.x the same call files it with video.
+
+`domain` is recorded with the report. `skipFrames` is how many top frames of the stack
+recorded for the report are left out of its signature, which groups reports into issues;
+a negative value counts as `0`.
+
+
+
+
+```objectivec
+// 6.x
+BugseeExceptionLoggingOptions *options = [BugseeExceptionLoggingOptions new];
+options.exceptionDomain = @"Payments";
+options.labels = @[@"checkout"];
+options.mergingRules = @{BugseeMergingRulesSkipFramesKey : @1};
+[Bugsee logException:exception options:options completion:nil];
+
+// 7.x
+[Bugsee logException:exception domain:@"Payments" skipFrames:1 completion:nil];
+
+// 7.x labels, in your BugseeDelegate
+- (NSArray *)bugseeAttachmentsForReport:(BugseeReport *)report {
+ if ([report.type isEqualToString:BugseeReportTypeError]) {
+ [report addLabels:@[@"checkout"]];
+ }
+ return @[];
+}
+```
+
+
+
+
+```swift
+// 6.x
+let options = BugseeExceptionLoggingOptions()
+options.exceptionDomain = "Payments"
+options.labels = ["checkout"]
+options.mergingRules = [BugseeMergingRulesSkipFramesKey: 1]
+Bugsee.logException(exception: exception, options: options, completion: nil)
+
+// 7.x
+Bugsee.logException(exception: exception, domain: "Payments", skipFrames: 1, completion: nil)
+
+// 7.x labels, in your BugseeDelegate
+func bugsee(attachmentsFor report: BugseeReport) -> [BugseeAttachment] {
+ if report.type == BugseeReportTypeError {
+ report.addLabels(["checkout"])
+ }
+ return []
+}
+```
+
+
+
+
+The delegate is asked about every report. `type` tells an error report from a bug or crash
+report, but not a `logException` report from a `logError` report or from an error report
+Bugsee files on its own, so a label added this way goes on all of them.
+
+On simulators and Mac Catalyst `logException` files nothing; its completion is still called.
+
---
## 8. Privacy and secure areas
@@ -1012,7 +1105,10 @@ Renamed — a plain search and replace does most of these.
| `testExceptionCrash` / `testSignalCrash` | `testCrash` |
| `deleteCollectedDataOnDevice:` | `deleteCollectedDataOnDevice:completion:` |
| `uploadWithSummary:…:includeVideo:` | `uploadWithSummary:description:severity:labels:` |
-| `logError:labels:includeVideo:` | `logError:labels:` |
+| `logError:labels:includeVideo:` / `logError:labels:` | `logError:`; labels through the delegate's report — see [§7.2](#72-includevideo-overloads-and-logerrorlabels-are-gone) |
+| `logException:options:completion:` | `logException:completion:` / `logException:domain:skipFrames:completion:` — see [§7.5](#75-bugseeexceptionloggingoptions-is-gone) |
+| `logException:reason:options:completion:` | `logException:reason:completion:` / `logException:reason:domain:skipFrames:completion:` |
+| `BugseeExceptionLoggingOptions` | `domain:` / `skipFrames:` parameters of `logException`; labels through the delegate's report |
| Swift `Bugsee.launch(token:options:)` _(dictionary)_ | Swift `Bugsee.launch(token:dictionaryOptions:)` |
| Swift `Bugsee.relaunch(options:)` _(dictionary)_ | Swift `Bugsee.relaunch(dictionaryOptions:)` |
| Swift `Bugsee.uploadReport(_:)` | Swift `Bugsee.upload(_:)` |
@@ -1031,7 +1127,7 @@ Removed with no direct replacement.
| `isViewHidden:` | — |
| `hideKeyboard:` | — |
| `setInternalSecureRectangles:` | — |
-| `logAssert:withLocation:` / `BUGSEE_ASSERT` | Use `logException:reason:options:completion:` |
+| `logAssert:withLocation:` / `BUGSEE_ASSERT` | Use `logException:reason:completion:` |
| `log:level:timestamp:` | `log:level:requiresFiltering:` takes the slot but does something different — it opts the message into the log filter |
| `setDefaultCrashPriority:` | `BugseeOptionReportingDefaultCrashPriority` at launch |
| `setDefaultErrorPriority:` | `BugseeOptionReportingDefaultErrorPriority` at launch |