How to make a user defined method in main viewcontroller that updates values continuously in iOS?

142 Views Asked by At

I learned objective c myself and haven't taken any courses for it. Hence, some times I get confused with minor things while writing iOS app. This question may be very lame, but I could not find any solution or I could not understand the solution. Here is my situation:

My app contains single view controller (the default one). I want to get continuous values from accelerometer, gyroscope and magnetometer and use the values to estimate user location using pedestrian dead reckoning (PDR). For this purpose, I used CoreMotion and made a CLMotionManager (motionManager) property in header file. Using this manager, I can check whether the sensors are available and get their values, for example:

if([_motionManager isAccelerometerAvailable])
{
    _motionManager.accelerometerUpdateInterval = 0.1;
    [_motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc]init] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {
            x=accelerometerData.acceleration.x;
            y = accelerometerData.acceleration.y;
            z = accelerometerData.acceleration.z;

    }];}

Similarly, I can get values from gyroscope and magnetometer. I get these values inside a IBAction method after pressing a button as:

-(IBAction)startSensor:(id)sender
{
//Getting accelerometer, gyroscope, and magnetometer values.
}

The PDR operation happens in my next method as:

-(void)thePDROperationWith:(NSArray*)accelerometerValues gyroscopeValues:(NSArray*)gyros magnetometerValues:(NSArray*)magneto
{
//The PDR operations with accelerometer, gyroscope and magnetometer values
}

Now, my question is:

1) How to get continuous PDR operation value from thePDROperationWith:: method? I called this method inside the startSensor method, however I get the value just once when I press the button. Moreover, am I supposed to declare this method in header file too (as in user defined NSObject subclass)?

2) What is the difference between user defined method and delegate methods like

//a method in CLBeaconManager delegate -(void)beaconManager:(CLBeaconManager*)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region { //code } ?

This delegate method (I expect I am using the correct term) runs continuously to range the beacons in the defined CLBeaconRegion. How can I make such method for my purpose?

Thank you.

1

There are 1 best solutions below

0
On BEST ANSWER

startAccelerometerUpdatesToQueue does what the name says — it begins a sequence of accelerometer update methods, and communicates them to you on the nominated queue, which in your case is an arbitrary background queue.

Therefore the code where you currently store values to x, y and z will be performed every time the OS spots a change in the accelerometer. You've likely got a similar sequence of perpetual updates coming from the gyroscope and magnetometer.

So those streams of information can be the triggers for your updates. Each time a new accelerometer, gyroscope or magnetometer update arrives, update your knowledge.

(Quick aside warning though: if you're creating a separate queue for each of those three things then it's likely you'll end up servicing them on different threads. So you'll need to worry about concurrent data access. Or you could instead use [NSOperationQueue mainQueue] to have all updates received on the same queue, which is also the one that UIKit operates on, if you just wanted the OS to serialise everything for you).

A delegate method is one that represents a function that one class delegates to another. In this case the beacon manager knows how to track beacons, but not what's appropriate in this application to do as a result of tracked beacons. So it delegates the decisions that flow from beacon changes.

Objective-C lets you be really loose about these things so you might see some very informal approaches if looking at older code, but the normal way nowadays is to declare a delegate protocol, e.g.:

@class MyClass; // Declare that there is a class called MyClass.

// Define a protocol for delegates.
@protocol MyProtocol
- (void)thisClass:(MyClass *)class learntFact:(Fact *)fact;
@end

// Here's MyClass for real
@interface MyClass
@property(nonatomic, weak) id<MyProtocol> factDelegate;
@end

Then when an instance of MyClass has something to say it just tells the delegate:

[self.factDelegate thisClass:self learntFact:...fact here...];

And somebody that wants to be a delegate sets instanceOfMyClass.factDelegate = self, having announced support for the relevant protocol.