title: Simulating CoreMotion iOS Simulator
body: <p>I am trying my hand at developing an application which makes use of the CoreMotion framework. I do not want to keep having to run out to test out my application, so instead I would like to find a technique which allows me to send fake it so I can try out lots of different scenarios. I wish to test scenarios such as user walking, driving, stopping etc. I do not want to have to go out walk, drive, stop etc everytime I want to test the application.</p>
  
  <p>Edit: I know CoreMotion is not yet supported in the simulator. But was hoping someone could give me some ideas on how to fake this</p>
  
  <p>UPDATE: What I have achieved so far using method swizzling. I have swapped back to objective-c for this, as I figure best try and figure out in this language first, then try and translate it into Swift</p>
  
  <p>I have set up a method swizzle class like so</p>
  
  <pre><code>+ (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);
  }
  </code></pre>
  
  <p>I have created a category for CMMotion and CMAccelerometerData</p>
  
  <pre><code>- (void) simx_setAcceleration:(CMAcceleration)acceleration {
    NSValue *value = [NSValue value:&amp;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:&amp;acc];
    return acc;
  }
  </code></pre>
  
  <p>Then the category for CMMotionManager class.</p>
  
  <pre><code>- (void) simx_setAccelerationData:(CMAcceleration )accelerationData
  {
      NSValue *value = [NSValue value:&amp;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:&amp;acc];
  
      CMAccelerometerData *data = [[CMAccelerometerData alloc] init];
  
      //Add
      [data simx_setAcceleration:acc];
  
      return data;
  }
  </code></pre>
  
  <p>Swizzling the methods is done like this</p>
  
  <pre><code> [CESwizzleUtils swizzleClass:[CMMotionManager class]
                                method:@"INSERT METHOD NAME TO BE SWIZZLED HERE"];
  </code></pre>
  
  <p>This allows me to pass in my own data </p>
  
  <pre><code> //Add
      CMAccelerometerData *data = [[CMAccelerometerData alloc] init];
      [data simx_setAcceleration:acc];
      [motionManager simx_setAccelerationData:acc];
  </code></pre>
  
  <p>So I can retrieve data like this</p>
  
  <pre><code>motionManager.accelerometerData.acceleration.x;
  </code></pre>
  
  <p>I have also method swizzled the DeviceMotion class as well. Here is quick example app I have which pulls data from the accelerometer and gyroscope using the method swizzle techniques</p>
  
  <p><img src="https://i.stack.imgur.com/A52Zh.png" alt="enter image description here"></p>
  
  <p>When the test button is clicked, it randomly generates accelerometer and gyroscope data and updates the labels.</p>
  
  <p>Code looks like this</p>
  
  <pre><code>-(IBAction)testing:(id)sender
  {
    //random double just generates a random double between 0 and 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 and 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];
  }
  </code></pre>
  
  <p>What I am struggling to figure out is how to get this methods. I have swizzled many of the CoreMotion methods, but need a little help with this one. At present on the simulator, despite the fact that MotionManager now stores data for the gyroscope, accelerometer etc, these block methods do not fire.</p>
  
  <pre><code> [activityManager startActivityUpdatesToQueue:[[NSOperationQueue alloc] init] withHandler:   ^(CMMotionActivity *activity){
  
  }];
  
  
   [motionManager startDeviceMotionUpdatesToQueue:[[NSOperationQueue alloc] init]
                                             withHandler:^ (CMDeviceMotion *motionData, NSError *error) {
  
  }];
  </code></pre>
  
  <p>I have also swizzled these methods</p>
  
  <pre><code>- (BOOL)override_isAccelerometerActive;
  - (BOOL)override_isDeviceMotionActive;
  -(BOOL)override_isGyroAvailable;
  </code></pre>
  
  <p>So they always return true, but still can't get these blocks firing. I would like some help trying to figure out how to correctly swizzle these methods so I can begin sending and recieving mock data to the simulator</p>
  
  <p>Edit: I did swizzle the accelerometer update method  by adding the following category. to the CMMotionManager class</p>
  
  <pre><code>-(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);
  
  
      });
  }
  </code></pre>
  
  <p>This works well enough, as I have swizzled the accel data.</p>
  
  <p>I then tried this with the CMMotionActivityManager class by adding this category</p>
  
  <pre><code>-(void)override_startActivityUpdatesToQueue:(NSOperationQueue *)queue
                                  withHandler:(CMMotionActivity *)activity
  {
      dispatch_async(dispatch_get_main_queue(), ^
                     {
                        BOOL walking = [activity walking];
                         NSLog(@"%i", walking);
                     });
  }
  </code></pre>
  
  <p>However I am getting this error here</p>
  
  <blockquote>
    <p>[<strong>NSGlobalBlock</strong> walking]: unrecognized selector sent to instance
    0x1086cf330</p>
  </blockquote>
  
  <p>Any suggestions would be appreciated</p>
  
  <p>UPDATE 2:</p>
  
  <p>Sorry late response, had to wait till today to try this. I updated the method per your suggestion so it now works</p>
  
  <pre><code>-(void)override_startActivityUpdatesToQueue:(NSOperationQueue *)queue
                                  withHandler:(CMMotionActivityHandler )activity
  {
  
  }
  </code></pre>
  
  <p>Thing is, I need access to  CMMotionActivity in order to figure out if they are walking running etc. The original code </p>
  
  <pre><code> [activityManager startActivityUpdatesToQueue:[[NSOperationQueue alloc] init] withHandler:   ^(CMMotionActivity *activity){
          dispatch_async(dispatch_get_main_queue(), ^
          {
              [activity walking];
          });
      }];
  </code></pre>
  
  <p>allows you to access this variable. However now that I have swizzled this, it now calls my new declaration inside my category file which contains no CMMotionActivity variable. Any ideas on how I can access this. This is getting a bit complicated, but this is the last roadblock for me before I can finally start mocking CoreMotion data. I have already simulated the gyroscope and compass data, and I have got data from real journeys, so I can feed that into the simulator. But I need to then have it tell me if the user is walking, running, driving etc. </p>
  
  <p>Any suggestions?</p>