SupportCenter is the indie developer's solution to in app support. It provides a lightweight UI library that integrates with the SendGrid API so there is no need to need to integrate 3rd party libraries that bloat your app size and expose your users to unwanted tracking.
- SendGrid integration
- Stand-alone UI components
- Automatic device metadata gathering
- Image and video attachments
- Custom support options
- Dark/Light Interface
- SwiftUI Support
- Localization
SupportCenter uses Swift Package Manager.
Repository URL
https://github.com/aasatt/SupportCenter.git
To add a package dependency to your Xcode project, select File > Swift Packages > Add Package Dependency and enter its repository URL. You can also navigate to your target’s General pane, and in the “Frameworks, Libraries, and Embedded Content” section, click the + button. In the “Choose frameworks and libraries to add” dialog, select Add Other, and choose Add Package Dependency. See Adding Package Dependencies to Your App - developer.apple.com
Configure the SDK with your SendGrid API Key, support email and from email.
SupportCenter.setup(
sendgridToken: <#Sendgrid API Key#>,
supportEmail: <#Support Email#>,
fromEmail: <#From Email#>
)
sendgridToken
Your SendGrid API Key.
supportEmail
The email where you would like support requests to be sent to.
fromEmail
This must be a authenticated sender within SendGrid.
More information - SendGrid Documentation
Showing SupportCenter is simple. Be sure you have configured SupportCenter before attempting to present it.
UIKit
SupportCenter.present(from: self)
// Note: self is the current UIViewController
SwiftUI
Easily present from SwiftUI via a wrapping UIViewControllerRepresentable
view.
struct SupportView: UIViewControllerRepresentable {
@Binding var presentingSupport: Bool
func makeUIViewController(context: Context) -> some WrappingViewController {
let controller = WrappingViewController()
controller.onDismiss = {
presentingSupport = false
}
return controller
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
if presentingSupport {
uiViewController.present()
}
}
}
class WrappingViewController: UIViewController, SupportCenterViewControllerDelegate {
var onDismiss: (() -> Void)?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
present()
}
func present() {
SupportCenter.present(from: self, delegate: self)
}
func supportCenterDidDismiss() {
onDismiss?()
}
}
Then put you're view's content and the support view in a ZStack
and show the support view based on a presentingSupport
State
variable.
struct DemoView: View {
@State var presentingSupport = false
var body: some View {
ZStack {
Button {
presentingSupport = true
} label: {
Text("Support")
}
if presentingSupport {
SupportView(presentingSupport: $presentingSupport)
}
}
}
}
Conform to the ReportOption
protocol to customize the support options shown in the popup.
Protocol
public protocol ReportOption {
var icon: UIImage { get }
var title: String { get }
var description: String { get }
var emailSubject: String { get }
}
Example
Conform to ReportOption
enum MySupportOption: ReportOption, CaseIterable {
case betaFeedback
var icon: UIImage {
switch self {
case .betaFeedback:
return UIImage(systemName: "bubble.left.fill")!
}
}
var title: String {
switch self {
case .betaFeedback:
return "Send Feedback"
}
}
var description: String {
switch self {
case .betaFeedback:
return "Provide feedback for our app"
}
}
var emailSubject: String {
switch self {
case .betaFeedback:
return "Beta Feedback"
}
}
}
Now just present SupportCenter
SupportCenter.present(from: self, reportOptions: MySupportOption.allCases)