VNRequest — What It Is, How Vision Requests Work in iOS

Author: IT Sectr Published: 2026-07-20 Reading time: 8 min

VNRequest is an abstract base class of the Vision framework that represents a unit of image or video stream analysis. Each type of analysis — face detection, text recognition, barcode search, classification — is implemented as a concrete subclass of VNRequest. According to Apple Developer Documentation (2024), a developer creates a request instance, configures its parameters, passes an image through VNImageRequestHandler, and receives results as an array of VNObservation.

Key Takeaways

  • VNRequest — the base class for all Vision requests: image analysis, video, and ML models.
  • A request is executed through VNImageRequestHandler (image) or VNSequenceRequestHandler (video).
  • Results are returned as an array of VNObservation — each subclass contains specific data.
  • Completion handler allows processing results asynchronously after analysis completes.
  • Multiple requests can be executed with a single call of handler.perform() for one image.

What Is VNRequest in Vision?

VNRequest is a fundamental element of the Vision architecture, implementing the Request-Response pattern for image and video analysis. Each VNRequest subclass is responsible for a specific computer vision task: face detection, text recognition, content classification.

The VNRequest architecture separates “what to analyze” (the request) from “how to process” (the handler). The developer configures the request (analysis type, additional parameters) and passes it to the handler along with the image. The handler executes the request and returns results without requiring the developer to understand the internal ML algorithms.

All VNRequest subclasses follow a unified structure: initialization with an optional completion handler, property configuration (region of interest, accuracy level), and passing to the handler. This makes the API predictable and easily extensible — adding a new type of analysis means creating a new VNRequest subclass.

swift
import Vision

// 1. Create request
let request = VNDetectFaceRectanglesRequest { req, _ in
    // 3. Process results
    guard let faces = req.results as? [VNFaceObservation]
    else { return }
    print("Found \\(faces.count) faces")
}

// 2. Execute via handler
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try handler.perform([request])

Key VNRequest properties: regionOfInterest (area of interest on the image to speed up analysis), preferBackgroundProcessing (background mode), revision (algorithm version), and cancellationSupport. Proper configuration of these properties allows optimizing performance for a specific task.

According to Apple WWDC 2024, over 7 years of Vision’s existence, the number of available VNRequest subclasses grew from 8 (iOS 11) to 25+ (iOS 18), covering all major computer vision tasks on mobile devices.

Main Types of VNRequest for Analysis

Vision includes over 25 VNRequest subclasses divided into categories: detection, recognition, tracking, and classification. Each subclass inherits VNRequest and adds task-specific properties.

Detection and Recognition

VNDetectFaceRectanglesRequest — face detection in images. Returns VNFaceObservation with bounding box coordinates and confidence. VNDetectHumanRectanglesRequest — similarly for people. VNDetectHumanBodyPoseRequest — human pose estimation (skeletal keypoints).

Text Analysis

VNRecognizeTextRequest — text recognition with support for 13 languages and two accuracy levels. VNReadCodeRequest — for specialized codes. VNDetectTextRectanglesRequest — finding text regions without recognition (faster, but only rectangles).

Classification and Analysis

VNClassifyImageRequest — image classification across 1,000 ImageNet categories. VNGenerateImageFeaturePrintRequest — feature vector extraction for image comparison. VNDetectContoursRequest — object contour detection.

CategoryExample RequestResult
Face DetectionVNDetectFaceRectanglesRequestVNFaceObservation
Text RecognitionVNRecognizeTextRequestVNRecognizedTextObservation
BarcodesVNDetectBarcodesRequestVNBarcodeObservation
ClassificationVNClassifyImageRequestVNClassificationObservation
TrackingVNTrackObjectRequestVNDetectedObjectObservation
ContoursVNDetectContoursRequestVNContoursObservation

VNImageRequestHandler and VNSequenceRequestHandler

VNImageRequestHandler — a handler for static images. It accepts CGImage, CIImage, or Data (JPEG/PNG) and executes one or more VNRequest instances. This is the primary way to use Vision for photos, screenshots, and uploaded images.

VNSequenceRequestHandler — a handler for image sequences (video frames). It accepts the same set of image types but is designed for frame-by-frame processing while maintaining state between frames (necessary for object tracking).

swift
// VNImageRequestHandler for single image
let imageHandler = VNImageRequestHandler(
    cgImage: cgImage,
    orientation: orientation,
    options: [:])

// VNSequenceRequestHandler for video
let sequenceHandler = VNSequenceRequestHandler()
try sequenceHandler.perform([trackingRequest],
    on: cgImage)

Important difference: VNSequenceRequestHandler does not support parallel execution of multiple requests — each perform() call processes one set of requests for one frame. For multi-threaded video processing, create separate handler instances for different threads.

VNImageRequestHandler can run on a background queue. Apple recommends DispatchQueue.global(qos: .userInitiated) for interactive scenarios (user awaits results) and .background for batch processing (e.g., analyzing an entire photo library).

VNObservation: Structure of Results

VNObservation — the base class for all Vision request results. Each VNObservation subclass contains data specific to the analysis type: bounding box coordinates, recognized text, confidence, unique identifier (uuid), and timestamp (timeRange).

Key VNObservation subclasses: VNFaceObservation (face detection result with bounding box and landmarks), VNRecognizedTextObservation (recognized text with candidates), VNBarcodeObservation (decoded barcode with payload and symbology), VNClassificationObservation (classification category with confidence).

swift
func handleTextResults(request: VNRequest) {
    guard let observations = request.results
        as? [VNRecognizedTextObservation]
    else { return }

    for observation in observations {
        let bbox = observation.boundingBox
        let text = observation.topCandidates(1).first ?? ""
        print("\\(text) at \\(bbox)")
    }
}

Confidence property (from 0.0 to 1.0) is present in all VNObservation instances and indicates the model’s confidence in the result. Apple recommends discarding observations with confidence < 0.5 for most tasks. For critical applications (medicine, security), the threshold should be raised to 0.8–0.9.

VNObservation also contains timeRange (for video requests) and uuid (unique ID for cross-frame matching). This allows tracking the same object (e.g., a face) across a sequence of video frames.

Executing Multiple Requests Simultaneously

One of the key advantages of VNRequest is the ability to execute multiple different requests on the same image in a single handler.perform() call. Vision internally optimizes execution order and reuses common computations (e.g., image preprocessing).

This allows obtaining a complete set of data about an image in one pass: simultaneously detect faces, recognize text, find barcodes, and classify content. This approach is significantly more efficient than calling each request sequentially.

swift
import Vision

// Multiple requests in a single array
let faceRequest = VNDetectFaceRectanglesRequest()
let textRequest = VNRecognizeTextRequest()
let barcodeRequest = VNDetectBarcodesRequest()
let classifyRequest = VNClassifyImageRequest()

let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try handler.perform([
    faceRequest,
    textRequest,
    barcodeRequest,
    classifyRequest
])

// Access results from each request
print("Faces: \\(faceRequest.results?.count ?? 0)")
print("Text blocks: \\(textRequest.results?.count ?? 0)")

Limitations: not all requests can be combined with others. For example, VNGenerateImageFeaturePrintRequest must be executed separately. Apple recommends grouping requests by type (detection, recognition, classification) and testing combinations on target devices.

Performance: combining 3–4 requests in a single perform() is 30–40% faster than sequential execution because Vision reuses shared ML computations and image preprocessing (scaling, color correction).

Custom Requests with VNCoreMLRequest

VNCoreMLRequest is a bridge between Core ML and Vision, allowing any Core ML model to be run as a Vision request. The model is wrapped in VNCoreMLModel, passed to VNCoreMLRequest, and Vision automatically handles image preprocessing (scaling, cropping to model input size).

VNCoreMLRequest inherits VNRequest, so it supports all standard features: regionOfInterest, completion handler, multiple requests. This allows combining a custom ML model with built-in Vision detectors in a single pipeline.

swift
import Vision
import CoreML

// Wrap Core ML model
guard let mlModel = try VNCoreMLModel(
    for: MyCustomClassifier().model)
else { return }

// Create VNCoreMLRequest
let coreMLRequest = VNCoreMLRequest(model: mlModel) { request, _ in
    guard let results = request.results
        as? [VNClassificationObservation]
    else { return }

    for result in results.prefix(5) {
        print("\\(result.identifier): \\(result.confidence)"
    }
}
coreMLRequest.imageCropAndScaleOption = .centerCrop
coreMLRequest.regionOfInterest = faceBoundingBox

imageCropAndScaleOption determines how Vision scales the image to model input: .centerCrop (center cropping), .scaleFill (stretching), or .scaleFit (scaling while maintaining aspect ratio). The choice depends on the model type and object position in the image.

Practical example: face detection via VNDetectFaceRectanglesRequest, then classification of each face via VNCoreMLRequest with a custom model (e.g., gender or age estimation). By combining two requests in one perform(), you get a complete face analysis pipeline in a single pass.

Frequently Asked Questions

Can an executing VNRequest be cancelled?

Yes, every VNRequest has a cancel() property that cancels the request execution. However, cancellation only works before processing begins — if the ML model has already started, cancellation will not interrupt the computation. For reliable cancellation, use DispatchWorkItem.cancel() together with VNRequest.cancel() in the completion handler.

VNDetectFaceRectanglesRequest vs VNDetectFaceLandmarksRequest — what’s the difference?

VNDetectFaceRectanglesRequest only finds face bounding rectangles. VNDetectFaceLandmarksRequest additionally identifies 68 facial keypoints (eyes, eyebrows, nose, mouth, contour). VNDetectFaceLandmarksRequest is slower but provides more data for animation, masks, and AR effects. For simple face counting, VNDetectFaceRectanglesRequest is sufficient.

Which request searches for barcodes — VNDetectBarcodesRequest?

Yes, VNDetectBarcodesRequest is the correct request for all types of barcodes and QR codes. It supports EAN, UPC, Code 39, Code 128, PDF417, Aztec, QR, and other formats. The result is returned in VNBarcodeObservation with payload and symbology. For video streams, use AVCaptureMetadataOutput — it’s faster for live scanning.

Can VNRequest be executed on a CIImage instead of CGImage?

Yes, VNImageRequestHandler accepts CIImage via the init(ciImage:options:) initializer. It also supports Data (JPEG/PNG) and NSURL (file path). CIImage is convenient when the image is already loaded through the Core Image pipeline — this avoids unnecessary data copying in memory.

How many VNRequest instances can be executed in one perform()?

There is no limit on the count, but in practice 3–5 requests is optimal. More than 5 requests can cause increased memory consumption, as each request loads its own ML model. If you need to run 10+ different analyses, split them into 2–3 groups and execute sequentially.

Summary

  • VNRequest — the base Vision class for all types of image and video analysis with a unified Request-Response architecture.
  • Vision includes 25+ VNRequest subclasses for face detection, OCR, barcodes, classification, contours, tracking, and ML models.
  • VNImageRequestHandler executes requests on static images; VNSequenceRequestHandler handles frame sequences for tracking.
  • Results are returned as VNObservation with bounding box, confidence, uuid, and type-specific data.
  • Multiple requests in one perform() work 30–40% faster than sequential calls due to ML computation reuse.
  • VNCoreMLRequest integrates custom Core ML models into the Vision pipeline with automatic image preprocessing.
  • All requests execute on device without sending data to a server, ensuring privacy and offline operation.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also