Skip to content

Commit 8a919ce

Browse files
armcknightbruno-garciachargome
authored
Cocoa User Feedback (#11191)
* wip * early pr feedback * reformat code snippet, update a couple things to align with current implementation * copy over javascript config doc * convert to swift doc * remove the config image, since it's not accurate for iOS * remove redundant customization docs; remove crash dialog * update to reflect current API, fix more things from initial draft * remove attempted html comment * try <Alert></Alert> * fix javascript note * fix platform section closure * Update docs/platforms/apple/common/user-feedback/configuration/index.mdx Co-authored-by: Bruno Garcia <[email protected]> * remove weird doc about an endpoint, and fix the init for the feedback object * fix table overflow * remove mention of enabling --------- Co-authored-by: Bruno Garcia <[email protected]> Co-authored-by: Charly Gomez <[email protected]>
1 parent c371429 commit 8a919ce

File tree

3 files changed

+260
-7
lines changed

3 files changed

+260
-7
lines changed
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
---
2+
title: Configure User Feedback
3+
sidebar_order: 6900
4+
description: "Learn about general User Feedback configuration fields."
5+
---
6+
7+
<PlatformSection notSupported={["apple.macos", "apple.tvos", "apple.watchos", "apple.visionos"]}>
8+
9+
## User Feedback Widget
10+
11+
The User Feedback Widget offers many customization options, and if the available options are insufficient, you can [use your own UI](#bring-your-own-widget).
12+
13+
### General
14+
15+
The following options can be configured for the integration in `SentryUserFeedbackConfiguration`:
16+
17+
| Option | Type | Default | Description |
18+
| ------------------------ | --------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
19+
| `animations` | `Bool` | `true` | Whether or not to show animations, like for presenting and dismissing the form. |
20+
| `useShakeGesture` | `Bool` | `false` | Use a shake gesture to display the form. |
21+
| `showFormForScreenshots` | `Bool` | `false` | Any time a user takes a screenshot, bring up the form with the screenshot attached. |
22+
| `tags` | `[String: Any]` | `nil` | Tags to set on the feedback event. This is a dictionary where keys are strings and values can be different data types such as `NSNumber`, `NSString`, etc. |
23+
24+
Some hooks are available so you can react to the user opening and closing the form, when the user successfully submits the form or when there is an error:
25+
26+
| Hook | Type | Description |
27+
| ----------------- | ------------------------- | ------------------------------------------------------------------------ |
28+
| `onFormOpen` | `() -> Void` | Called when the feedback form is opened. |
29+
| `onFormClose` | `() -> Void` | Called when the feedback form is closed. |
30+
| `onSubmitSuccess` | `([String: Any]) -> Void` | Called when feedback is successfully submitted via the prepared form. |
31+
| `onSubmitError` | `(Error) -> Void` | Called when there is an error submitting feedback via the prepared form. |
32+
33+
`onSubmitSuccess` provides a dictionary with the following keys:
34+
35+
- `message`: The message the user entered in the feedback form.
36+
- `name`: The name the user entered in the feedback form.
37+
- `email`: The email the user entered in the feedback form.
38+
- `attachments`: An array of attachments to be included with the feedback; currently only one screenshot is supported.
39+
40+
Example:
41+
42+
```swift
43+
SentrySDK.start { options in
44+
options.showFormForScreenshots = true
45+
options.configureUserFeedback { config in
46+
config.onSubmitSuccess = { data in
47+
print("Feedback submitted successfully from \(data["name"]) at \(data["email"]): \(data["message"])")
48+
}
49+
}
50+
}
51+
```
52+
53+
### Widget
54+
55+
The following options can be configured for the integration in `SentryUserFeedbackWidgetConfiguration`:
56+
57+
| Option | Type | Default | Description |
58+
| ---------------- | ------------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
59+
| `location` | `[NSDirectionalRectEdge]` | `[.bottom, .trailing]` | The location of the widget on the screen. |
60+
| `autoInject` | `Bool` | `true` | Injects the Feedback widget into the application when the integration is added. Set `autoInject: false` if you want to call `feedback.attachTo()` or `feedback.openDialog()` directly, or only want to show the widget on certain views. |
61+
| `windowLevel` | `UIWindow.Level` | `UIWindow.Level.normal + 1` | The window level of the widget. |
62+
| `showIcon` | `Bool` | `true` | Whether to show the widget icon. |
63+
| `labelText` | `String?` | `"Report a Bug"` | The text of the widget label. If `nil`, then only the icon is shown. It is an error to set both `labelText` to `nil` and `showIcon` to `false`. |
64+
| `layoutUIOffset` | `UIOffset` | `UIOffset.zero` | The offset of the widget from edge(s) of the screen specified in `location`. |
65+
66+
### Form Configuration
67+
68+
You can customize which form elements are shown, whether they are required, and even prefill some info, in `SentryUserFeedbackFormConfiguration`:
69+
70+
| Option | Type | Default | Description |
71+
| ----------------------------- | -------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
72+
| `showBranding` | `Bool` | `true` | Displays the Sentry logo inside of the form |
73+
| `formTitle` | `String` | `"Report a Bug"` | The title of the feedback form. |
74+
| `messageLabel` | `String` | `"Description"` | The label of the feedback description input field. |
75+
| `messagePlaceholder` | `String` | `"What's the bug? What did you expect?"` | The placeholder in the feedback description input field. |
76+
| `isRequiredLabel` | `String` | `"(Required)"` | The text to attach to the title label for a required field. |
77+
| `successMessageText` | `String` | `"Screenshot"` | The label of the screenshot button. |
78+
| `removeScreenshotButtonLabel` | `String` | `"Remove Screenshot"` | The label of the remove screenshot button. |
79+
| `isNameRequired` | `Bool` | `false` | Requires the name field on the feedback form to be filled in. |
80+
| `showName` | `Bool` | `true` | Displays the name field on the feedback form. Ignored if `isNameRequired` is `true`. |
81+
| `nameLabel` | `String` | `"Name"` | The label next to the name input field. |
82+
| `namePlaceholder` | `String` | `"Your Name"` | The placeholder in the name input field. |
83+
| `isEmailRequired` | `Bool` | `false` | Requires the email field on the feedback form to be filled in. |
84+
| `showEmail` | `Bool` | `true` | Displays the email field on the feedback form. Ignored if `isEmailRequired` is `true`. |
85+
| `emailLabel` | `String` | `"Email"` | The label next to the email input field. |
86+
| `emailPlaceholder` | `String` | `"[email protected]"` | The placeholder in the email input field. |
87+
| `submitButtonLabel` | `String` | `"Send Bug Report"` | The label of the submit button. |
88+
| `cancelButtonLabel` | `String` | `"Cancel"` | The label of the cancel button. |
89+
| `useSentryUser` | `Bool` | `true` | Sets the `email` and `name` fields to the corresponding Sentry SDK user fields that were called with `SentrySDK.setUser`. |
90+
| `isRequiredText` | `String` | `(required)` | The text displayed next to a required field. |
91+
92+
Example:
93+
94+
```swift
95+
SentrySDK.start { options in
96+
options.configureUserFeedback { config in
97+
config.configureForm { form in
98+
form.isRequiredText = "*"
99+
form.title = "We want to hear from you!"
100+
form.useSentryUser = false
101+
}
102+
}
103+
}
104+
```
105+
106+
### Theme Customization
107+
108+
Colors can be customized via the top-level config object, configuring for both light and dark themes.
109+
110+
| Option | Light | Dark | Description |
111+
| ------------------ | ------------------------------------------- | ------------------------------------------- | -------------------------------------------------------------- |
112+
| `background` | `rgb(255, 255, 255)` | `rgb(41, 35, 47)` | Background color of the widget and form. |
113+
| `foreground` | `rgb(43, 34, 51)` | `rgb(235, 230, 239)` | Foreground text color of the widget and form. |
114+
| `submitForeground` | `rgb(255, 255, 255)` | `rgb(255, 255, 255)` | Foreground color for the form submit button. |
115+
| `submitBackground` | `rgb(88, 74, 192)` | `rgb(88, 74, 192)` | Background color for the form submit button. |
116+
| `buttonForeground` | Same as `foreground` | Same as `foreground` | Foreground color for the cancel and screenshot buttons. |
117+
| `buttonBackground` | `UIColor.clear` | `UIColor.clear` | Background color for the form cancel and screenshot buttons. |
118+
| `errorColor` | `rgb(223, 51, 56)` | `rgb(245, 84, 89)` | Color used for error-related components. |
119+
| `inputBackground` | `UIColor.`<br />`secondarySystemBackground` | `UIColor.`<br />`secondarySystemBackground` | Background color for form inputs. |
120+
| `inputForeground` | `UIColor.darkText` | `UIColor.lightText` | Foreground color for form inputs. |
121+
122+
123+
Form element outlines can be configured via the `outlineStyle` property. By default, the color is `rgb(204, 204, 204)`, the width is `0.5`, and the corner radius is `5.0`.
124+
125+
Fonts can be directly customized, but by default they will scale with the user's preferred text size using predefined font styles:
126+
127+
| Option | Default Text Style | Description |
128+
| ------------ | --------------------------- | --------------------------------------------------------------------------- |
129+
| `font` | `"UIFontTextStyleCallout"` | The font family to use for form input elements and the widget button label. |
130+
| `headerFont` | `"UIFontTextStyleTitle1"` | The font family to use for the main header title of the feedback form. |
131+
| `titleFont` | `"UIFontTextStyleHeadline"` | The font family to use for titles of text fields and buttons in the form. |
132+
133+
You can still configure the `fontFamily` setting and we will request an appropriately scaled font from the system.
134+
135+
Here is an example of customizing only the background color for the light theme using the Feedback constructor configuration:
136+
137+
```swift
138+
SentrySDK.start { options in
139+
options.configureUserFeedback { config in
140+
// configureTheme is used for light themes on iOS versions that support dark mode, and as the sole theme configuration for earlier iOS versions that don't support dark mode
141+
config.theme { theme in
142+
theme.background = .init(color: .yellow)
143+
}
144+
config.darkTheme { theme in
145+
theme.background = .init(color: .darkGray)
146+
}
147+
}
148+
}
149+
```
150+
151+
### Accessibility
152+
153+
The Feedback widget is designed to be accessible, with a set of default accessibility labels that can be overriden. The following attributes are set to ensure the widget is accessible:
154+
155+
#### `SentryUserFeedbackWidgetConfiguration`
156+
157+
| Configuration Key | Default Value |
158+
| -------------------------- | -------------------------------------------------- |
159+
| `widgetAccessibilityLabel` | `labelText` or, if that is `nil`, `"Report a Bug"` |
160+
161+
#### `SentryUserFeedbackFormConfiguration`
162+
163+
| Configuration Key | Default Value |
164+
| ------------------------------------------ | ----------------------------- |
165+
| `messageTextViewAccessibilityLabel` | `messagePlaceholder` |
166+
| `removeScreenshotButtonAccessibilityLabel` | `removeScreenshotButtonLabel` |
167+
| `nameTextFieldAccessibilityLabel` | `namePlaceholder` |
168+
| `emailTextFieldAccessibilityLabel` | `"Your email address"` |
169+
| `submitButtonAccessibilityLabel` | `submitButtonLabel` |
170+
| `cancelButtonAccessibilityLabel` | `cancelButtonLabel` |
171+
172+
Example:
173+
174+
```swift
175+
SentrySDK.start { options in
176+
options.configureUserFeedback { config in
177+
config.configureWidget { widget in
178+
widget.widgetAccessibilityLabel = "Report an Issue" // default: "Report a Bug"
179+
}
180+
config.configureForm { form in
181+
form.messageTextViewAccessibilityLabel = "What happened?" // default: "What's the bug? What did you expect?"
182+
}
183+
}
184+
}
185+
```
186+
187+
### Bring Your Own Widget
188+
189+
You can also use your own UI components to gather feedback and pass the feedback data object to the `SentrySDK.capture(feedback: SentryFeedback)` function.
190+
191+
```swift
192+
SentrySDK.capture(feedback: .init(
193+
message: "This is an example feedback", // required
194+
name: "Jane Doe", // optional
195+
email: "[email protected]", // optional
196+
source: .custom,
197+
screenshot: somePngImageData // optional
198+
));
199+
```
200+
201+
</PlatformSection>

0 commit comments

Comments
 (0)