Swift 4, macOS 10.13
I have read a variety of answers on SO and still can't get an NSImageView to spin at its center instead of one of its corners.
Right now, the image looks like this (video): http://d.pr/v/kwiuwS
Here is my code:
//`loader` is an NSImageView on my storyboard positioned with auto layout
loader.wantsLayer = true
let oldFrame = loader.layer?.frame
loader.layer?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
loader.layer?.position = CGPoint(x: 0.5, y: 0.5)
loader.layer?.frame = oldFrame!
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = 0.0
rotateAnimation.toValue = CGFloat(-1 * .pi * 2.0)
rotateAnimation.duration = 2
rotateAnimation.repeatCount = .infinity
loader.layer?.add(rotateAnimation, forKey: nil)
Any ideas what I am still missing?
I just created a simple demo which contains the handy setAnchorPoint extension for all views. 
The main reason you see your rotation from a corner is that your anchor point is somehow reset to 0,0.
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
var imageView: NSImageView!
func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Insert code here to initialize your application
    // Create red NSImageView
    imageView = NSImageView(frame: NSRect(x: 100, y: 100, width: 100, height: 100))
    imageView.wantsLayer = true
    imageView.layer?.backgroundColor = NSColor.red.cgColor
    window.contentView?.addSubview(imageView)
}
func applicationWillTerminate(_ aNotification: Notification) {
    // Insert code here to tear down your application
}
func applicationDidBecomeActive(_ notification: Notification) {
    // Before animate, reset the anchor point
    imageView.setAnchorPoint(anchorPoint: CGPoint(x: 0.5, y: 0.5))
    // Start animation
    if imageView.layer?.animationKeys()?.count == 0 || imageView.layer?.animationKeys() == nil {
        let rotate = CABasicAnimation(keyPath: "transform.rotation")
        rotate.fromValue = 0
        rotate.toValue = CGFloat(-1 * .pi * 2.0)
        rotate.duration = 2
        rotate.repeatCount = Float.infinity
        imageView.layer?.add(rotate, forKey: "rotation")
    }
}
}
extension NSView {
    func setAnchorPoint(anchorPoint:CGPoint) {
        if let layer = self.layer {
            var newPoint = NSPoint(x: self.bounds.size.width * anchorPoint.x, y: self.bounds.size.height * anchorPoint.y)
            var oldPoint = NSPoint(x: self.bounds.size.width * layer.anchorPoint.x, y: self.bounds.size.height * layer.anchorPoint.y)
        newPoint = newPoint.applying(layer.affineTransform())
        oldPoint = oldPoint.applying(layer.affineTransform())
        var position = layer.position
        position.x -= oldPoint.x
        position.x += newPoint.x
        position.y -= oldPoint.y
        position.y += newPoint.y
        layer.anchorPoint = anchorPoint
        layer.position = position
    }
}
}

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With