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.
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
andz
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.:
Then when an instance of
MyClass
has something to say it just tells the delegate:And somebody that wants to be a delegate sets
instanceOfMyClass.factDelegate = self
, having announced support for the relevant protocol.