A powerful Swift package that enables easy integration of a shake-to-feedback system in iOS apps, with advanced annotation capabilities and Jira integration for comprehensive bug reporting and feedback collection.
- π± Detect device shake gestures in both UIKit and SwiftUI apps
- πΈ Automatically capture screenshots when feedback is triggered
- π Allow users to add notes to their feedback
- π Seamlessly integrate with Jira to create issues directly from your app
- π Include device metadata with each report (OS version, app version, device model, etc.)
- β¨ Modern Swift API with async/await support
- ποΈ Drawing Tools: Pen and highlighter tools for precise annotations
- π¨ Color Options: 3 carefully chosen colors (Red pen, Blue pen, Yellow highlighter)
- πΎ Persistent State: Annotations persist across sessions - edit anytime!
- β©οΈ Comprehensive Undo: Undo functionality for all annotations (current + previous sessions)
- ποΈ Clear All: Clear all annotations with confirmation dialog
- β‘ Instant Feedback: Immediate visual feedback with auto-navigation fallback
- π Smart Scaling: Annotations properly scale with screenshot dimensions
- iOS 15.0+
- Swift 6.0+
- Xcode 15.0+
Add ShakeFeedbackKit to your project using Swift Package Manager:
- In Xcode, select File > Add Packages...
- Enter the repository URL:
https://github.com/AAALI/ShakeFeedbackKit.git - Select the version you want to use
Alternatively, add it as a dependency in your Package.swift file:
dependencies: [
.package(url: "https://github.com/AAALI/ShakeFeedbackKit.git", from: "1.1.0")
]Initialize the ShakeFeedbackKit in your app delegate or at app startup:
import ShakeFeedbackKit
// In your app initialization code (e.g., app delegate or App struct)
ShakeFeedback.start(
jiraDomain: "your-domain.atlassian.net",
email: "your-jira-email@example.com",
apiToken: "your-jira-api-token",
projectKey: "YOUR_PROJECT"
)If you need to specify a custom Jira issue type ID:
ShakeFeedback.start(
jiraDomain: "your-domain.atlassian.net",
email: "your-jira-email@example.com",
apiToken: "your-jira-api-token",
projectKey: "YOUR_PROJECT",
issueTypeId: "10004" // Custom issue type ID
)It's recommended to store your Jira API token securely and not hardcode it in your application. Consider using environment variables, secure storage, or a backend service to provide the token at runtime.
When a user shakes their device:
- Shake Detection: ShakeFeedbackKit detects the motion event
- Screenshot Capture: A screenshot is automatically captured
- Feedback Form: A feedback form is presented with the screenshot preview
- Text Input: The user can add notes to describe the issue
- Annotation (Optional): Tap "π Add Annotations" to:
- Draw with pen or highlighter tools
- Choose from 6 colors (Red, Blue, Green, Orange, Purple, Black)
- Undo individual strokes or clear all annotations
- Annotations persist across sessions for editing
- Submit: The feedback is submitted to Jira as a new issue with annotated screenshot
- Confirmation: A success toast is shown to the user
The annotation system provides a seamless experience:
- Persistent Editing: Annotations are saved automatically - you can exit and return to continue editing
- Smart Undo: Undo button works for all annotations, even from previous sessions
- Clear All: Bin icon clears all annotations with confirmation dialog
- Visual Feedback: Immediate clearing or auto-navigation ensures smooth UX
- Tool Selection: Switch between pen (precise drawing) and highlighter (broader strokes)
- Color Variety: 6 carefully chosen colors for different annotation needs
Pen Tool ποΈ
- Perfect for precise annotations, arrows, and detailed markings
- 4pt line width for clear visibility
- Ideal for pointing out specific UI elements or bugs
Highlighter Tool ποΈ
- Broader 20pt width with 60% opacity for highlighting areas
- Great for marking sections, regions, or general areas of interest
- Semi-transparent to preserve underlying screenshot details
Choose from 3 carefully selected colors:
- π΄ Red Pen: Critical issues, errors, bugs (4pt precise drawing)
- π΅ Blue Pen: Information, notes, suggestions (4pt precise drawing)
- π Yellow Highlighter: Highlighting areas, general marking (20pt broad strokes with transparency)
// Annotations are automatically saved when you:
// 1. Switch tools or colors
// 2. Tap "Done" to return to feedback form
// 3. Exit the annotation view
// When you return to annotate the same screenshot:
// - All previous annotations are restored
// - You can continue editing where you left off
// - Undo works for both new and previous annotations- Use Red Pen for Critical Issues: Mark bugs, crashes, or broken functionality with precise 4pt strokes
- Use Blue Pen for Information: Add explanatory notes, arrows, or context with precise 4pt strokes
- Use Yellow Highlighter for Areas: Mark general regions, sections, or broad areas with 20pt transparent strokes
- Combine Tools: Use both pen colors for precision and highlighter for broader context
- Layer Annotations: Start with highlighter for areas, then add pen details for specifics
Bug Report:
- Use red pen to circle the problematic UI element
- Use blue pen to draw an arrow pointing to the issue
- Add text description: "Button doesn't respond to taps"
Feature Request:
- Use yellow highlighter to mark the area for improvement
- Use blue pen to sketch the desired change
- Add text description: "Add search functionality here"
UI Feedback:
- Use yellow highlighter to mark confusing sections
- Use blue pen to add detailed notes and suggestions
- Use red pen to mark critical issues
- Add comprehensive text feedback
You can also listen for shake events directly:
import Combine
import ShakeFeedbackKit
// Set up a subscriber to listen for shake events
let cancellable = NotificationCenter.default
.publisher(for: .deviceDidShake)
.sink { _ in
// Custom handling when shake is detected
print("Device was shaken!")
}
// Remember to store the cancellable referenceAnnotations not persisting
- Ensure you tap "Done" to save annotations before exiting
- Annotations are tied to the specific screenshot - new screenshots start fresh
Shake detection not working
- Make sure you've called
ShakeFeedback.start()during app initialization - Test on a physical device - shake detection doesn't work in simulator
- Check that your app has motion permissions if required
Jira integration issues
- Verify your Jira domain, email, and API token are correct
- Ensure the project key exists and you have permission to create issues
- Check that the issue type ID is valid for your project
- Memory Management: ShakeFeedbackKit automatically manages annotation data
- Storage: Annotations are stored efficiently using serialized data structures
- UI Performance: Drawing is optimized for smooth real-time annotation
import SwiftUI
import ShakeFeedbackKit
@main
struct MyApp: App {
init() {
// Initialize ShakeFeedbackKit
ShakeFeedback.start(
jiraDomain: "mycompany.atlassian.net",
email: "feedback@mycompany.com",
apiToken: ProcessInfo.processInfo.environment["JIRA_TOKEN"] ?? "",
projectKey: "MOBILE"
)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}import UIKit
import ShakeFeedbackKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize ShakeFeedbackKit
ShakeFeedback.start(
jiraDomain: "mycompany.atlassian.net",
email: "feedback@mycompany.com",
apiToken: getSecureAPIToken(), // Implement secure token retrieval
projectKey: "MOBILE",
issueTypeId: "10004" // Optional: specify custom issue type
)
return true
}
private func getSecureAPIToken() -> String {
// Implement secure token retrieval from keychain or secure storage
return "your-secure-token"
}
}import Combine
import ShakeFeedbackKit
class FeedbackManager: ObservableObject {
private var cancellables = Set<AnyCancellable>()
init() {
// Listen for shake events
NotificationCenter.default
.publisher(for: .deviceDidShake)
.sink { [weak self] _ in
self?.handleShakeDetected()
}
.store(in: &cancellables)
}
private func handleShakeDetected() {
// Custom logic before showing feedback
print("Shake detected - preparing feedback...")
// You can add custom analytics, logging, etc.
Analytics.track("shake_feedback_triggered")
}
}- Store API tokens securely using Keychain or environment variables
- Never hardcode sensitive credentials in your source code
- Consider using a backend service to proxy Jira requests
- Provide clear instructions to users about the shake-to-feedback feature
- Consider adding an alternative way to access feedback (e.g., settings menu)
- Test the annotation tools thoroughly on different screen sizes
- Test on physical devices for accurate shake detection
- Verify Jira integration in development environment first
- Use descriptive project keys and issue types for better organization
- iOS: 15.0+
- Swift: 6.0+
- Xcode: 15.0+
- Jira: Cloud or Server instances with REST API access
- Permissions: No special permissions required
ShakeFeedbackKit is available under the MIT license. See the LICENSE file for more info.