Ian
Ian

Reputation: 7558

CGPointMakeWithDictionaryRepresentation in Swift

I'm using AVCaptureSession to scan for QR codes in a Swift app. I'd like to draw a box around the detected QR code but I'm having trouble converting the "corners" property of AVMetadataMachineReadableCodeObject into something usable.

var corners: [AnyObject]! { get }

The value of this property is an array of CFDictionary objects, each of which has been created from a CGPoint struct using the CGPointCreateDictionaryRepresentation function, representing the coordinates of the corners of the object with respect to the image in which it resides.

I've tried this (based on a project by werner77) but I get the following compiler error "'CGPoint?' is not identical to 'CGPoint'"

// MARK: - AVCaptureMetadataOutputObjectsDelegate
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {

    let metadataObject = metadataObjects[0] as AVMetadataMachineReadableCodeObject;
    var corners = metadataObject.corners as Array<NSDictionary>;
    var topLeftDict = corners[0] as NSDictionary;
    var topLeft : CGPoint?

    // COMPILE ERROR: 'CGPoint?' is not identical to 'CGPoint'
    CGPointMakeWithDictionaryRepresentation(topLeftDict, &topLeft)   
}

Any help with this would be greatly appreciated.

Upvotes: 0

Views: 1317

Answers (3)

wj2061
wj2061

Reputation: 6885

try this snippet :

    let corners = metadataObject.corners.map{(point)->CGPoint in
                let dict = point as! NSDictionary
                let x = dict["X"]!.doubleValue
                let y = dict["Y"]!.doubleValue

                return CGPoint(x: x, y: y)
            }

Upvotes: 0

Mundi
Mundi

Reputation: 80273

Understand optionals.

Any type can have a ? appended, which means that it can also be nil. The great thing about this is that you have to address or ignore nil objects explicitly, unlike in Objective-C where a nil object could lead to untraceable bugs.

When getting an object from a dictionary, it has to be optional because it is possible that the key is not present in the dictionary. CGPointMakeWithDictionaryRepresentation expects a non-optional, therefore you have to use an initialized non-optional.

// Playground:
var point = CGPointMake(1, 2)
var dictionary = CGPointCreateDictionaryRepresentation(point)
var aPoint = CGPointZero
CGPointMakeWithDictionaryRepresentation(dictionary, &aPoint)
aPoint // x 1, y 2

Upvotes: 1

rob mayoff
rob mayoff

Reputation: 385690

You're passing an UnsafeMutablePointer<Optional<CGPoint>>, but it wants an UnsafeMutablePointer<CGPoint>.

var topLeft: CGPoint?
var point = CGPointZero
if CGPointMakeWithDictionaryRepresentation(topLeftDict, &point) {
    topLeft = point
}

Upvotes: 0

Related Questions