Tuesday 15 May 2012

objective c - Simulating CoreMotion iOS Simulator -



objective c - Simulating CoreMotion iOS Simulator -

i trying hand @ developing application makes utilize of coremotion framework. not want maintain having run out test out application, instead find technique allows me send false can seek out lots of different scenarios. wish test scenarios such user walking, driving, stopping etc. not want have go out walk, drive, stop etc everytime want test application.

edit: know coremotion not yet supported in simulator. hoping give me ideas on how false this

update: have achieved far using method swizzling. have swapped objective-c this, figure best seek , figure out in language first, seek , translate swift

i have set method swizzle class so

+ (void)swizzleclass:(class)class method:(nsstring*)methodname { sel originalselector = nsselectorfromstring(methodname); sel newselector = nsselectorfromstring([nsstring stringwithformat:@"%@%@", @"override_", methodname]); method originalmethod = class_getinstancemethod(class, originalselector); method newmethod = class_getinstancemethod(class, newselector); method_exchangeimplementations(originalmethod, newmethod); }

i have created category cmmotion , cmaccelerometerdata

- (void) simx_setacceleration:(cmacceleration)acceleration { nsvalue *value = [nsvalue value:&acceleration withobjctype:@encode(cmacceleration)]; objc_setassociatedobject(self, acceleration_identifier, value, objc_association_retain); } - (cmacceleration)override_acceleration { nsvalue *value = objc_getassociatedobject(self, acceleration_identifier); cmacceleration acc; [value getvalue:&acc]; homecoming acc; }

then category cmmotionmanager class.

- (void) simx_setaccelerationdata:(cmacceleration )accelerationdata { nsvalue *value = [nsvalue value:&accelerationdata withobjctype:@encode(cmacceleration)]; objc_setassociatedobject(self, handler_identifier, value, objc_association_retain); } - (cmaccelerometerdata *)override_accelerometerdata { nsvalue *value = objc_getassociatedobject(self, handler_identifier); cmacceleration acc; [value getvalue:&acc]; cmaccelerometerdata *data = [[cmaccelerometerdata alloc] init]; //add [data simx_setacceleration:acc]; homecoming data; }

swizzling methods done this

[ceswizzleutils swizzleclass:[cmmotionmanager class] method:@"insert method name swizzled here"];

this allows me pass in own info

//add cmaccelerometerdata *data = [[cmaccelerometerdata alloc] init]; [data simx_setacceleration:acc]; [motionmanager simx_setaccelerationdata:acc];

so can retrieve info this

motionmanager.accelerometerdata.acceleration.x;

i have method swizzled devicemotion class well. here quick illustration app have pulls info accelerometer , gyroscope using method swizzle techniques

when test button clicked, randomly generates accelerometer , gyroscope info , updates labels.

code looks this

-(ibaction)testing:(id)sender { //random double generates random double between 0 , 1 cmacceleration acc; acc.x = [self randomdouble:0 :1]; acc.y = [self randomdouble:0 :1]; acc.z = [self randomdouble:0 :1]; //add cmaccelerometerdata *data = [[cmaccelerometerdata alloc] init]; [data simx_setacceleration:acc]; [motionmanager simx_setaccelerationdata:acc]; //sim gravity , useracel cmacceleration grav; grav.x = [self randomdouble:0 :1]; grav.y = [self randomdouble:0 :1]; grav.z = [self randomdouble:0 :1]; cmacceleration useracel; useracel.x = [self randomdouble:0 :1]; useracel.y = [self randomdouble:0 :1]; useracel.z = [self randomdouble:0 :1]; cmdevicemotion *devicemotion = [[cmdevicemotion alloc] init]; [devicemotion simx_setuseracceleration:useracel]; [devicemotion simx_setgravity:grav]; [motionmanager simx_setdevicemotion:devicemotion]; accellabael.text = [nsstring stringwithformat:@"accelerometer: %.02f %.02f %.02f", motionmanager.accelerometerdata.acceleration.x,motionmanager.accelerometerdata.acceleration.y,motionmanager.accelerometerdata.acceleration.z]; gravitylabel.text = [nsstring stringwithformat:@"gravity: %.02f %.02f %.02f", motionmanager.devicemotion.gravity.x,motionmanager.devicemotion.gravity.y,motionmanager.devicemotion.gravity.z]; accelspeedlabel.text = [nsstring stringwithformat:@"accel: %.02f %.02f %.02f", motionmanager.devicemotion.useracceleration.x,motionmanager.devicemotion.useracceleration.y,motionmanager.devicemotion.useracceleration.z]; }

what struggling figure out how methods. have swizzled many of coremotion methods, need little help one. @ nowadays on simulator, despite fact motionmanager stores info gyroscope, accelerometer etc, these block methods not fire.

[activitymanager startactivityupdatestoqueue:[[nsoperationqueue alloc] init] withhandler: ^(cmmotionactivity *activity){ }]; [motionmanager startdevicemotionupdatestoqueue:[[nsoperationqueue alloc] init] withhandler:^ (cmdevicemotion *motiondata, nserror *error) { }];

i have swizzled these methods

- (bool)override_isaccelerometeractive; - (bool)override_isdevicemotionactive; -(bool)override_isgyroavailable;

so homecoming true, still can't these blocks firing. help trying figure out how correctly swizzle these methods can begin sending , recieving mock info simulator

edit: did swizzle accelerometer update method adding next category. cmmotionmanager class

-(void)override_startaccelerometerupdatestoqueue:(nsoperationqueue *)queue withhandler:(cmaccelerometerhandler)handler{ dispatch_async(dispatch_get_main_queue(), ^{ nslog(@"test %.02f %.02f %.02f", self.accelerometerdata.acceleration.x,self.accelerometerdata.acceleration.y,self.accelerometerdata.acceleration.z); }); }

this works enough, have swizzled accel data.

i tried cmmotionactivitymanager class adding category

-(void)override_startactivityupdatestoqueue:(nsoperationqueue *)queue withhandler:(cmmotionactivity *)activity { dispatch_async(dispatch_get_main_queue(), ^ { bool walking = [activity walking]; nslog(@"%i", walking); }); }

however getting error here

[nsglobalblock walking]: unrecognized selector sent instance 0x1086cf330

any suggestions appreciated

update 2:

sorry late response, had wait till today seek this. updated method per suggestion works

-(void)override_startactivityupdatestoqueue:(nsoperationqueue *)queue withhandler:(cmmotionactivityhandler )activity { }

thing is, need access cmmotionactivity in order figure out if walking running etc. original code

[activitymanager startactivityupdatestoqueue:[[nsoperationqueue alloc] init] withhandler: ^(cmmotionactivity *activity){ dispatch_async(dispatch_get_main_queue(), ^ { [activity walking]; }); }];

allows access variable. have swizzled this, calls new declaration within category file contains no cmmotionactivity variable. ideas on how can access this. getting bit complicated, lastly roadblock me before can start mocking coremotion data. have simulated gyroscope , compass data, , have got info real journeys, can feed simulator. need have tell me if user walking, running, driving etc.

any suggestions?

your method signature override_startactivityupdatestoqueue:withhandler: incorrect. handler parameter should cmmotionactivityhandler block provides single cmmotionactivity argument:

typedef void (^cmmotionactivityhandler)(cmmotionactivity *activity)

objective-c swift ios-simulator core-motion xcode6.1

No comments:

Post a Comment