9

I'm trying to make use of the NSObject(NSKeyValueObserving) in my Swift class but I'm running into a type problem. Xcode is complaining that it doesn't understand the CMutableVoidPointer type for the 'context' argument in the following code:

override func observeValueForKeyPath(keyPath: String!, ofObject object: AnyObject!, change: NSDictionary!, context: CMutableVoidPointer)

I use CMutableVoidPointer because the Objective-C definition types the 'context' argument as a void *.

The exact error I'm getting at compile-time is: "Use of undeclared type 'CMutableVoidPointer'".

I'm using Xcode Beta 3.

Any help would be appreciated.

CodaFi
  • 43,043
  • 8
  • 107
  • 153
samonderous
  • 649
  • 1
  • 10
  • 22
  • 3
    In beta 3 they replaced `CMMutableVoidPointer`. Use `UnsafePointer` or `ConstUnsafePointer` now. See the change notes:http://adcdownload.apple.com//Developer_Tools/xcode_6_beta_3_lpw27r/xcode_6_beta_3_release_notes__.pdf – Jack Jul 08 '14 at 19:23
  • 1
    Thanks for that. I see that. But when I switch to UnsafePointer it gives me an error: Reference to generic type 'UnsafePointer' requires arguments in <...>. Why would a void * need a type? – samonderous Jul 08 '14 at 19:32
  • 6
    @samonderous: I think it is `context: UnsafePointer<()>`. Just type `func observeValueForKeyPath` in Xcode and let autocompletion do its work! – Martin R Jul 08 '14 at 19:35
  • Ugh, should have just typing it out again. I wrote that originally for Xcode Beta. Thanks guys. – samonderous Jul 08 '14 at 19:38
  • Please refer [here](http://stackoverflow.com/a/24627141/1260976) – jqgsninimo Jul 16 '14 at 02:50
  • can be marked answered – Jochen Bedersdorfer Oct 02 '14 at 09:46
  • 1
    @JochenBedersdorfer Or just "close" because it's "off topic" with a sub-reason of "This question was caused by a problem that can no longer be reproduced or a simple typographical error." – Rob Nov 14 '14 at 20:38

2 Answers2

1

Here is the current best practice according to Using Swift with Cocoa and Objective-C:

// Add the dynamic modifier to any property you want to observe
class MyObjectToObserve: NSObject {
    dynamic var myDate = NSDate()
    func updateDate() {
        myDate = NSDate()
    }
}

// Create a global context variable
private var myContext = 0

// Add an observer for the key-path, override the observeValueForKeyPath:ofObject:change:context: method, and remove the observer in deinit.
class MyObserver: NSObject {
    var objectToObserve = MyObjectToObserve()
    override init() {
        super.init()
        objectToObserve.addObserver(self, forKeyPath: "myDate", options: .New, context: &myContext)
    }
    override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject: AnyObject], context: UnsafeMutablePointer<Void>) {
        if context == &myContext {
            println("Date changed: \(change[NSKeyValueChangeNewKey])")
        } else {
            super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
        }
    }
    deinit {
        objectToObserve.removeObserver(self, forKeyPath: "myDate", context: &myContext)
    }
}
sbooth
  • 16,646
  • 2
  • 55
  • 81
1

this was close for me, but if you're running Swift 2, the change dictionary uses String keys and all the params except the context are optional now; so you'll need to make sure your func looks like this:

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    ...
    }
johnnyclem
  • 3,284
  • 1
  • 17
  • 14