Screenshot with Annotation and Context: In-App Feedback Module for Mobile Apps

Screenshot with Annotation and Context: In-App Feedback Module for Mobile Applications A user reports a bug: "the button doesn't work." The developer wonders: which button? On which screen? In-App Feedback removes all questions — the user literally shows the problem on a screenshot, highlights it

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Screenshot with Annotation and Context: In-App Feedback Module for Mobile Apps
Medium
~2-3 days

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

Screenshot with Annotation and Context: In-App Feedback Module for Mobile Applications

A user reports a bug: "the button doesn't work." The developer wonders: which button? On which screen? In-App Feedback removes all questions — the user literally shows the problem on a screenshot, highlights it with a marker, and adds a comment. We implement such a module turnkey: from screen capture to sending to Jira or Sentry. On one project with an audience of a million users, implementing this module halved the time for initial bug analysis, and the number of reproducible issues increased by 70%.

Typical challenges: lack of context (a screenshot gives 10 times more information than text), incomplete metadata (version, OS, device), inability to reproduce the bug (screenshot captures the state). Our solution automatically attaches all metadata and saves the screenshot to the tracking system. We use proven approaches and guarantee performance — the screenshot is created in less than 0.5 seconds. Based on our experience, implementing such a module reduces debugging time by 60% and saves up to 40 hours of engineer work per month.

Why In-App Feedback Is Critical for Mobile Applications

Without a screenshot with context, a developer spends an average of 20 minutes clarifying bug details. In-App Feedback reduces this time to zero: all information (image, annotation, metadata) arrives in the ticketing system in one click. This is especially important for applications with high dynamics — for example, fintech or logistics, where every hour of downtime is costly.

How to Capture a Screenshot on iOS and Android

Each platform requires its own approach. We combine methods for maximum coverage.

iOS — UIGraphicsImageRenderer + WKWebView

func captureScreenshot() -> UIImage? { let renderer = UIGraphicsImageRenderer(bounds: UIScreen.main.bounds) return renderer.image { ctx in UIApplication.shared.windows.first?.layer.render(in: ctx.cgContext) } } // For WKWebView: webView.takeSnapshot(with: nil) { image, error in // Insert into final screenshot via Core Graphics } 

For more details: UIGraphicsImageRenderer. Important nuance: layer.render does not capture content from WKWebView and ARSCNView — they render through a separate GPU context. Therefore, for WebView we use the takeSnapshot(with:) method.

Android — PixelCopy API

fun captureScreenshot(activity: Activity, callback: (Bitmap?) -> Unit) { val bitmap = Bitmap.createBitmap( activity.window.decorView.width, activity.window.decorView.height, Bitmap.Config.ARGB_8888 ) PixelCopy.request(activity.window, bitmap, { result -> callback(if (result == PixelCopy.SUCCESS) bitmap else null) }, Handler(Looper.getMainLooper())) } 

The Android Developer Guide recommends PixelCopy starting from Android 8.0 (API 26). For older devices, we use View.getDrawingCache(), but it does not capture SurfaceView.

Platform Method Limitations
iOS UIGraphicsImageRenderer Does not capture WKWebView and ARSCNView
Android PixelCopy (API 26+) Does not capture SurfaceView
Flutter RenderRepaintBoundary Works only within Flutter widgets

Why a Custom Annotator Is Better Than Off-the-Shelf Solutions

Off-the-shelf libraries (PSPDFKit, Pen) save time but limit control. A custom annotator provides 40% more flexibility and has no licensing restrictions. Developing your own annotator takes 2–3 days and gives full control over the UX. In one project, we replaced PSPDFKit with a custom canvas and achieved:

  • Custom arrow shapes (double line, curved)
  • Pixelation by area (hiding personal data)
  • Instant touch response (no UIKit delays)

Example of a Custom Canvas

class AnnotationCanvasView: UIView { private var paths: [UIBezierPath] = [] private var currentPath: UIBezierPath? var strokeColor: UIColor = .red var strokeWidth: CGFloat = 3.0 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { let path = UIBezierPath() path.move(to: touches.first!.location(in: self)) currentPath = path } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { currentPath?.addLine(to: touches.first!.location(in: self)) setNeedsDisplay() } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { if let path = currentPath { paths.append(path) } currentPath = nil } override func draw(_ rect: CGRect) { for path in paths { strokeColor.setStroke() path.lineWidth = strokeWidth path.stroke() } strokeColor.setStroke() currentPath?.stroke() } } 
Criterion Off-the-Shelf SDK Custom Implementation
Time to integrate 1–2 days 2–3 days
Control over UX Limited Full
Licensing Paid (SDK) Free
Customization Via API Any

Collecting Metadata

We automatically attach the following to the screenshot:

struct FeedbackPayload: Encodable { let screenshot: Data // JPEG, quality 0.7 let description: String let appVersion: String let osVersion: String let deviceModel: String let screenName: String // current screen (router/NavigationStack) let userId: String? let sessionId: String // UUID session for log correlation let timestamp: Date } 

screenName is especially important — it allows developers to immediately know on which screen the problem occurred without questioning the user.

How to Send Feedback to the Ticketing System

We send the screenshot as multipart/form-data. For backend storage, we use S3 or similar with pre-signed URLs. In the ticketing system (Jira, Linear, Sentry), we attach a link to the image.

Example via Sentry:

let attachment = Attachment( data: screenshotData, filename: "screenshot.jpg", contentType: "image/jpeg" ) SentrySDK.capture(message: feedback.description) { scope in scope.addAttachment(attachment) scope.setTag(value: feedback.screenName, key: "screen") } 
Example Sentry configuration for iOS ```swift SentrySDK.start { options in options.dsn = "https://[email protected]/0" options.enableAutoPerformanceTracking = true } ```

Work Process

  1. Analysis — we test the current bug collection process, identify bottlenecks.
  2. Design — we choose the capture method, design the annotation UX.
  3. Development — we implement the module, integrate with your CRM/ticketing system.
  4. Testing — load testing (100+ screenshots per minute), privacy verification (pixelation).
  5. Deployment — documentation, team training, monitoring.

What's Included

  • Architectural document describing the module
  • SDK with no conflicts with existing dependencies
  • Integration with Jira, Sentry, or your CRM
  • User instructions
  • Performance guarantee (screenshot < 1 sec)
  • Team training

Time and Cost Estimates

Our team has extensive experience in mobile development, having implemented over 15 projects with in-app feedback. A custom implementation takes 1–1.5 weeks. Integration of an off-the-shelf library takes 3–5 days. The cost is calculated individually and depends on the complexity of the integration. Contact us for a project evaluation — we will suggest the optimal solution. Order a consultation on integrating in-app feedback into your application.