Instruction 01

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

The best part about most framework improvements is that you get them for “free”. Your current code just works better. Observations are more accurate and come back faster. Some of the observations provide details they didn’t provide before.

A good example of a request that evolved in iOS 18 is the unified human body pose request. Before, a VNDetectHumanBodyPoseRequest provided a structure in its observations to help your app determine where things like elbows, legs, and torsos are positioned in the image. You needed to have a separate request to get information about the hands and fingers. A VNDetectHumanHandPoseRequest provided information about the hands and fingers. You’ll recall that the request handler takes an array of requests to perform on a single image, so passing in a hand-and-body request to process at the same time was pretty easy to set up. However, it was the app’s responsibility to combine the observations that came back for the body request and the observations that came back for the hand request. Now, the HumanBodyPoseObservation returned by the DetectHumanBodyPoseRequest has a structure for the right and left hands as well as the structure from before for the torso, legs, arms, and so on.

Aesthetics and Finding the Best Image

Though many request types improved for iOS 18, only one was completely new: CalculateImageAestheticsScoresRequest, which returns an array of ImageAestheticsScoresObservation objects. This request scores an image on its overall quality and memorability based on factors like blur, exposure, and composition.

Sample images with their aesthetics score and whether or not Vision considers them to be utility images. That this awesome portrait of a dog only garnered a 0.7 rating is outrageous though!
Hehzdo orayof giwh theiz euqxcusumv gdoyi epj wnabsel es lud Homuey ganxeyupl sgak ba pi anidojf elupav. Jjal stej aqutuvo kahwdoey eh i dar onkk weglojiw o 2.4 qodapw ig eodlovaual rtuuhp!

struct ProcessedResult {
  let image: CGImage
  let observations: [VNObservation]
}

let images = <some array of cgImages>
var processedImages: [ProcessedResult] = []

for image in images {
  let handler = VNImageRequestHandler(cgImage: image, options: [:])
  let request = VNCalculateImageAestheticsScoreRequest{ result, error in
  guard let observations = request.results as?
    [VNImageAestheticsScoresObservation], error == nil else {
      //either got no observations or got an error
      return
  }

    processedImages.append(ProcessedResult(image: image,
      observations: observations))
  }

  do {
    try handler.perform([request])
  } catch {
    //do something with the error
  }
}
See forum comments
Download course materials from Github
Previous: Introduction Next: Instruction 02