NSGraphicsContext.current expression is ambiguous without more context

I am using the code below to learn more about drawing but I am getting an ambiguous error on the line not sure how to resolve this. Please advise how to code this. Thanks

let context = NSGraphicsContext.current()?.cgContext
 override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
       ** let context = NSGraphicsContext.current()?.cgContext**
        let length = CGPoint(x: 100, y: 100)
        let p1 = CGPoint(x: 200, y: 200)
        let shape = "square"
        context!.beginPath()
        context!.move(to: p1)
        if shape == "line" {
            let pointEnd = CGPoint(x: p1.x + length.x, y: p1.y + length.y)
            context!.addLine(to: pointEnd)
        } else if shape == "square" {
            let p2 = CGPoint(x: p1.x + length.x, y: p1.y)
            let p3 = CGPoint(x: p1.x + length.x, y: p1.y + length.y)
            let p4 = CGPoint(x: p1.x, y: p1.y + length.y)
            context!.addLine(to: p2)
            context!.addLine(to: p3)
            context!.addLine(to: p4)
            context!.addLine(to: p1)
        }
       
        context!.setStrokeColor(red: 1, green: 1, blue: 1, alpha: 1.0)
        context!.setFillColor(red: 0, green: 1, blue: 0, alpha: 1)
        context!.setLineWidth(2.0)
        context!.strokePath()
       
        let textColor = NSColor(calibratedRed: 1, green: 1, blue: 1, alpha: 1.0)
        let textColorB = NSColor(calibratedRed: 1, green: 1, blue: 1, alpha: 0.0)
        let rect = CGRect(x: 200, y: 200, width: 30, height: 130)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .center
        let attr = [NSAttributedString.Key.paragraphStyle: paragraphStyle, NSAttributedString.Key.foregroundColor: textColor, NSAttributedString.Key.backgroundColor: textColorB, NSAttributedString.Key.font:NSFont.init(name: "HelveticaNeue-Thin", size: 14)]
      
        let q: NSString = "hello, world"
        let center = CGPoint(x: 0, y: 0)
        q.draw(at: center, withAttributes: attr as [NSAttributedString.Key : Any])
    }
}
Answered by DTS Engineer in 725086022

In Swift, NSGraphicsContext.current is a class property, not a function, so you can't have () after it:

        let context = NSGraphicsContext.current?.cgContext

Also, it's (strictly speaking) correct to store the optional result as context and to reference it later as context!, but it's poor Swift coding practice, even if you're sure that it will never be nil. Instead, you could do something like this:

        guard let context = NSGraphicsContext.current?.cgContext else {
             // handle the error somehow
        }

Or, you can avoid having to deal with an error by making the drawing conditional, something like:

        if let context = NSGraphicsContext.current?.cgContext {
            let length = CGPoint(x: 100, y: 100)
            let p1 = CGPoint(x: 200, y: 200)
            let shape = "square"
            context.beginPath()
            context.move(to: p1)
            if shape == "line" {
                let pointEnd = CGPoint(x: p1.x + length.x, y: p1.y + length.y)
                context.addLine(to: pointEnd)
            } else if shape == "square" {
                let p2 = CGPoint(x: p1.x + length.x, y: p1.y)
                let p3 = CGPoint(x: p1.x + length.x, y: p1.y + length.y)
                let p4 = CGPoint(x: p1.x, y: p1.y + length.y)
                context.addLine(to: p2)
                context.addLine(to: p3)
                context.addLine(to: p4)
                context.addLine(to: p1)
            }

            context.setStrokeColor(red: 1, green: 1, blue: 1, alpha: 1.0)
            context.setFillColor(red: 0, green: 1, blue: 0, alpha: 1)
            context.setLineWidth(2.0)
            context.strokePath()
        }
        …
Accepted Answer

In Swift, NSGraphicsContext.current is a class property, not a function, so you can't have () after it:

        let context = NSGraphicsContext.current?.cgContext

Also, it's (strictly speaking) correct to store the optional result as context and to reference it later as context!, but it's poor Swift coding practice, even if you're sure that it will never be nil. Instead, you could do something like this:

        guard let context = NSGraphicsContext.current?.cgContext else {
             // handle the error somehow
        }

Or, you can avoid having to deal with an error by making the drawing conditional, something like:

        if let context = NSGraphicsContext.current?.cgContext {
            let length = CGPoint(x: 100, y: 100)
            let p1 = CGPoint(x: 200, y: 200)
            let shape = "square"
            context.beginPath()
            context.move(to: p1)
            if shape == "line" {
                let pointEnd = CGPoint(x: p1.x + length.x, y: p1.y + length.y)
                context.addLine(to: pointEnd)
            } else if shape == "square" {
                let p2 = CGPoint(x: p1.x + length.x, y: p1.y)
                let p3 = CGPoint(x: p1.x + length.x, y: p1.y + length.y)
                let p4 = CGPoint(x: p1.x, y: p1.y + length.y)
                context.addLine(to: p2)
                context.addLine(to: p3)
                context.addLine(to: p4)
                context.addLine(to: p1)
            }

            context.setStrokeColor(red: 1, green: 1, blue: 1, alpha: 1.0)
            context.setFillColor(red: 0, green: 1, blue: 0, alpha: 1)
            context.setLineWidth(2.0)
            context.strokePath()
        }
        …
NSGraphicsContext.current expression is ambiguous without more context
 
 
Q