Pergunta

I am having trouble using the ABPersonViewController with RubyMotion. The error I'm getting is

Objective-C stub for message setDisplayedPerson:' typev@:^v' not precompiled. Make sure you properly link with the framework or library that defines this message.

I suspect this is due to RubyMotion not casting to the type IOS expects. I think ABPersonCreate() is returning a CFType but the displayedPerson setter is expecting it to be cast as a ABRecordRef (that's just a guess from the error messages)

Here's the sample code to see the problem (based on Apple's QuickContacts sample):

#Rakefile
$:.unshift("/Library/RubyMotion/lib")
require 'motion/project'

Motion::Project::App.setup do |app|
  # Use `rake config' to see complete project settings.
  app.name = 'contacts'
  app.frameworks += ['AddressBook', 'AddressBookUI']
end

and

# app/app_delegate.rb
class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.applicationFrame)
    window.rootViewController = UINavigationController.alloc.init
    window.rootViewController.wantsFullScreenLayout = true
    window.makeKeyAndVisible
    true

    # This works
    add_person('Alex', 'Rothenberg')

    # This fails (is it a type casting problem?)
    show_person_view_controller('Rothenberg')
  end

  def show_person_view_controller(name)
    anError = nil

    address_book = ABAddressBookCreate();
    people = ABAddressBookCopyPeopleWithName(address_book, name);
    person = people.first
    picker = ABPersonViewController.alloc.init.autorelease

    picker.personViewDelegate = self
    puts "Should this be an AddressBookRef? #{person.inspect}" # => #<__NSCFType:0x8c3bec0>
    picker.displayedPerson = person
    # The previous line fails
    puts "We never reach this line!"

    self.navigationController.pushViewController(picker, animated:true)
  end

  def add_person(first_name, last_name)
    error = nil
    contact = ABPersonCreate()
    ABRecordSetValue( contact, KABPersonFirstNameProperty, first_name, error )
    ABRecordSetValue( contact, KABPersonLastNameProperty, last_name, error )

    address_book = ABAddressBookCreate()
    ABAddressBookAddRecord( address_book, contact, error )
    ABAddressBookSave( address_book, error )
  end
end

When you run it we are able to add to the address book in the add_person method but it fails in show_person_view_controller on the line picker.displayedPerson = person

$ rake
     Build ./build/iPhoneSimulator-5.1-Development
  Simulate ./build/iPhoneSimulator-5.1-Development/contacts.app
Should this be an AddressBookRef? #<__NSCFType:0x8da2900>
Objective-C stub for message `setDisplayedPerson:' type `v@:^v' not precompiled. Make sure you properly link with the framework or library that defines this message.

Any suggestions would be appreciated

Foi útil?

Solução

This will work properly as of RubyMotion 1.12 (run sudo motion update).

  • Fixed a bug where performing Objective-C methods that accept CFType objects would crash the program (ex. [ABPersonViewController setDisplayedPerson:]).
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top