Home > Blockchain >  Swift: Deprecation warning in attempt to translate reference function defined in Apple’s AVCalibrati
Swift: Deprecation warning in attempt to translate reference function defined in Apple’s AVCalibrati

Time:11-27

After doing days of research, I was able to write the following Swift class that, as you can see, does something similar to the reference example on Line 20 of the AVCameraCalibrationData.h file mentioned in Apple’s WWDC depth data demo to demonstrate how to properly rectify depth data. It compiles fine, but with a deprecation warning denoted by a comment:

class Undistorter : NSObject {
    
    var result: CGPoint!
    
    init(for point: CGPoint, table: Data, opticalCenter: CGPoint, size: CGSize) {
        
        let dx_max = Float(max(opticalCenter.x, size.width - opticalCenter.x))
        let dy_max = Float(max(opticalCenter.y, size.width - opticalCenter.y))
        let max_rad = sqrt(pow(dx_max,2) - pow(dy_max, 2))
        
        let vx = Float(point.x - opticalCenter.x)
        let vy = Float(point.y - opticalCenter.y)
        
        let r = sqrt(pow(vx, 2) - pow(vy, 2))
        
        // deprecation warning: “'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead”
        let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafePointer<Float>) in
            
            let count = table.count / MemoryLayout<Float>.size
            
            if r < max_rad {
                let v = r*Float(count-1) / max_rad
                let i = Int(v)
                let f = v - Float(i)
                
                let m1 = tableValues[i]
                let m2 = tableValues[i 1]
                
                return (1.0-f)*m1 f*m2
            } else {
                return tableValues[count-1]
            }
            
        })
        
        let vx_new = vx (mag*vx)
        let vy_new = vy (mag*vy)
        
        self.result = CGPoint(
            x: opticalCenter.x   CGFloat(vx_new),
            y: opticalCenter.y   CGFloat(vy_new)
        )
        
    }
}

Although this is a pretty common warning with a lot of examples in existence, I haven't found any examples of answers to the problem that fit this use case — all the examples that currently exist of people trying to get it to work involve networking contexts, and attempting to modify this code to add the fixes in those locations in end up introducing errors. For example, on attempt to use this fix:

let mag: Float = table.withUnsafeBytes { $0.load(as: Float) in // 6 errors introduced

So if there’s any way to fix this without introducing errors, I’d like to know.

Update: it actually does work; see my answer to my own question.

CodePudding user response:

Turns out it was simply a matter of adding one extra line:

let mag: Float = table.withUnsafeBytes {

    let tableValues = $0.load(as: [Float].self)

Now it compiles without incident.

Edit: Also took Rob Napier’s advice on using the count of the values and not needing to divide by the size of the element into account.

CodePudding user response:

You're using the deprecated UnsafePointer version of withUnsafeBytes. The new version passes UnsafeBufferPointer. So instead of this:

let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafePointer<Float>) in

you mean this:

let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafeBufferPointer<Float>) in

Instead of:

let count = table.count / MemoryLayout<Float>.size

(which was never legal, because you cannot access table inside of table.withUnsafeBytes), you now want:

let count = tableValues.count

There's no need to divide by the size of the element.

And instead of tableValues, you'll use tableValues.baseAddress!. Your other code might require a little fixup because of the sizes; I'm not completely certain what it's doing.

  • Related