Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing iPhone Accelerometer using PyObjC

I want to access the Accelerometer of my iPhone through PyObjC. Here is my Code:

@objc.signature("v@:@@")
def accelerometer_didAccelerate_(self, accelerometer, acceleration):
    msgBox = UIAlertView.alloc().initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles_("Acceleration", str(acceleration.x), self, "OK", None)
    msgBox.show()
    msgBox.release()

@objc.signature("v@:@")
def applicationDidFinishLaunching_(self, unused):
    self.accelerometer = UIAccelerometer.sharedAccelerometer()
    self.accelerometer.setUpdateInterval_(1)
    self.accelerometer.setDelegate_(self)
    #...

The problem is str(accelleration.x) returns "<native-selector x of <UIAcceleration: 0x.....>>". What can I do?

like image 652
Chris Avatar asked Mar 10 '11 21:03

Chris


1 Answers

A UIAcceleration's x-value is defined in Objective-C as a property, and accessing acceleration.x in Python gives you the method named 'x', not the attribute (ivar) named 'x' as you might expect. You need to say:

acceleration._.x

which uses PyObjC's "magic" accessor mechanism to get the attribute you want.

The reasons for this:

The way Python's class namespaces work, you can't have a method and an attribute with the same name. This is in contrast to Objective-C where a getter method often has the same name as the attribute it accesses.

This difference can cause a little confusion with Objective-C 2.0's properties feature, especially since the syntax looks identical between the two languages. In Objective-C, you write:

NSLog(@"foo's bar: %f", foo.bar);
foo.bar = 10.0;

Which automatically uses the proper setter or getter methods (-bar and -setBar:). PyObjC, because of Python's class namespace rule, can't do exactly what the Objective-C code would do, and has to pick just one thing (method or attribute) to be represented by the name foo.bar; the thing it chooses is the method.

like image 186
jscs Avatar answered Sep 23 '22 05:09

jscs