0

I'm trying to use Ruby Motion to add an entry to the AddressBook. I can't figure out how to properly instantiate the CFErrorRef parameter.

error = nil # compiles but won't capture an error properly
# Here are my numerous attempts:
#error = Pointer.new( :object ) expected instance of Pointer of type `^{__CFError}', got `@' (TypeError)
#error = Pointer.new( '^{__CFError}' ) Can't find pointer description for type `^{__CFError}'
#error = Pointer.new( '{__CFError}' ) Can't find pointer description for type `{__CFError}'
#error = Pointer.new( '__CFError' ) Can't find pointer description for type `__CFError'
#error = Pointer.new( CFError.type ) uninitialized constant AppDelegate::CFError (NameError)
#error = Pointer.new( CFErrorRef.type ) uninitialized constant AppDelegate::CFErrorRef 
p = ABPersonCreate()
raise error[0] unless ABRecordSetValue( p, KABPersonFirstNameProperty, "Guy", error )
raise error[0] unless ABRecordSetValue( p, KABPersonLastNameProperty, "Argo", error )
ab = ABAddressBookCreate()
raise error[0] unless ABAddressBookAddRecord( ab, p, error )
raise error[0] unless ABAddressBookSave( ab, error )
NSLog( "Record successfully added." )

Suggestions welcome. Guy

Guy Argo
  • 397
  • 4
  • 10
  • Are any of your calls `ABRecordSetValue()` actually failing? or are you getting to "Record successfully added."? – Paul.s May 29 '12 at 20:19
  • @Paul.s when I try his code, it's the `ABRecordSetValue(...)` is that's throwing the exception: `expected instance of Pointer of type '^{__CFError}', got `@' (TypeError)` – Dylan Markow May 29 '12 at 21:30
  • @DylanMarkow if I copy this exactly its works just fine :S – Paul.s May 29 '12 at 21:35
  • @Paul.s Yes, because that's with `error = nil` -- which is fine, unless there actually is an error, in which case there's no way to capture it. I tested using `error = Pointer.new(:object)` and got the exception. – Dylan Markow May 29 '12 at 21:39
  • I submitted a support ticket to RubyMotion on this. The docs say that RubyMotion is supposed to "automatically handle" all CoreFoundation-style APIs. – Dylan Markow May 29 '12 at 21:43
  • @DylanMarkow sorry I had a moment there. Curiously I can't even call something as simple as `CFSTR("test")` – Paul.s May 29 '12 at 22:50
  • Yeah, I banged my head against the wall for a couple of hours trying various variations of the above to no avail. Wasn't sure if I was missing some subtlety about how names from MFC/iOS map to Ruby. So I thought I try StackOverflow before submitting an issue. @DylanMarkow thanks for confirming that I hadn't overlooked something trivial. – Guy Argo May 31 '12 at 02:29
  • 1
    @GuyArgo this is now fixed in motion 1.9. It worked for me using `error = Pointer.new(:id)` – Paul.s May 31 '12 at 22:55

1 Answers1

1

Upgrading to RubyMotion 1.9 includes this fix:

  • Fixed a bug in the compiler where APIs accepting pointers to CoreFoundation types could not be given Pointer objects of the :object type (ex. CFErrorRef*).

sudo motion update will get this for you.

Dylan Markow
  • 123,080
  • 26
  • 284
  • 201