Shake Event in iOS
Add framework : -
- CoreLocation
- AudioToolbox
Background Mode in Capabilities : -
Add In info.plist : -
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Your location is shared with Campus Security Staff to give them Route instructions on map so that they can reach you. </string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Your location is shared with Campus Security Staff to give them Route instructions on map so that they can reach you. </string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location is shared with Campus Security Staff to give them Route instructions on map so that they can reach you. </string>
ViewController.m : -
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#import <CoreMotion/CoreMotion.h>
#import <AudioToolbox/AudioToolbox.h>
#define FORMAT(format, ...) [NSString stringWithFormat:(format), ##__VA_ARGS__]
#define MAX_TIME_STAMP_DURATION 3
#define MIN_TIME_STAMP_DURATION 0.25
@interface ViewController () <CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
CMMotionManager *motionManager;
NSOperationQueue *motionUpdateQueue;
CMAcceleration lastAcceleration;
int shakeCount;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
motionManager = [[CMMotionManager alloc] init];
motionManager.deviceMotionUpdateInterval = 1.0/60.0;
motionUpdateQueue = [[NSOperationQueue alloc] init];
motionUpdateQueue.name = @"core-motion-updates";
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(restartMotionUpdates)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(restartMotionUpdates)
name:UIApplicationDidBecomeActiveNotification
object:nil];
//Lat long code
locationManager = [[CLLocationManager alloc] init];
[locationManager requestAlwaysAuthorization];
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//-----------------------------
locationManager.allowsBackgroundLocationUpdates = true;
if (@available(iOS 11.0, *)) {
locationManager.showsBackgroundLocationIndicator = false;
} else {
// Fallback on earlier versions
}
locationManager.delegate = self;
[locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:CLTimeIntervalMax];
//-----------------------------
[locationManager startUpdatingLocation];
//-----------------------------
[self updateOnShakeEvent];
}
-(void) appDidEnterBackground{
[self restartMotionUpdates];
}
-(void) appDidBecomeActive {
[self restartMotionUpdates];
}
-(void) restartMotionUpdates{
[motionManager stopDeviceMotionUpdates];
[self updateOnShakeEvent];
}
-(void)updateOnShakeEvent{
__block int countShake = 0;
__block double startTimeStamp = 0.1;
__block double totalTimeStamp = 0.1;
__block bool lockStartTimeStamp = true;
[motionManager startDeviceMotionUpdatesToQueue:motionUpdateQueue withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
float accelerationThreshold = 0.30;
CMAcceleration userAcceleration = motionManager.deviceMotion.userAcceleration;
if (fabs(userAcceleration.x) > accelerationThreshold || fabs(userAcceleration.y) > accelerationThreshold || fabs(userAcceleration.z) > accelerationThreshold)
{
float sensitivity = 1.0;
float x1 = 0, x2 = 0, y1 = 0, y2 = 0, z1 = 0, z2 = 0;
double totalAccelerationInXY = sqrt(userAcceleration.x * userAcceleration.x +
userAcceleration.y * userAcceleration.y);
// if ( totalAccelerationInXY > 0.85 && totalAccelerationInXY < 3.45) {
if ( totalAccelerationInXY > 4 && totalAccelerationInXY < 8) {
x1 = userAcceleration.x;
y1 = userAcceleration.y;
z1 = userAcceleration.z;
float change = fabs(x1-x2+y1-y2+z1-z2);
if (sensitivity < change) {
if (countShake == 0) {
if (lockStartTimeStamp){
NSLog(@"shakeStarted");
startTimeStamp = motion.timestamp;
lockStartTimeStamp = false;
}
}
if (countShake < 3) {
totalTimeStamp = startTimeStamp - motion.timestamp;
if (fabs(totalTimeStamp) < MAX_TIME_STAMP_DURATION && fabs(totalTimeStamp) > MIN_TIME_STAMP_DURATION) {//0.4 minimum difference between timestamp // 3 maximum difference between timestamp
countShake = countShake + 1;
startTimeStamp = motion.timestamp;
NSLog(@"currentShakeCount : %d", countShake);
if (countShake >= 3 ){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
countShake = 0;
lockStartTimeStamp = true;
});
NSLog(@"Please send local notification");
//-----------------------------------------
AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate
, ^{
NSLog(@"Called 1");
});
@try {
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:@"Shake Method Done"
message:@""
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Handel your yes please button action here
}];
[alert addAction:yesButton];
[self presentViewController:alert animated:YES completion:nil];
} @catch (NSException *exception) {
NSLog(@"%@",exception.reason);
} @finally {
}
//-----------------------------------------
}
}else if (fabs(totalTimeStamp) > MAX_TIME_STAMP_DURATION ){
countShake = 0;
lockStartTimeStamp = true;
totalTimeStamp = 0.0;
// NSLog(@"totalTimeStamp");
}
}
x2 = x1;
y2 = y1;
z2 = z1;
}
}
}else {
double newtotalTimeStamp = startTimeStamp - motion.timestamp;
if (newtotalTimeStamp > 3){
countShake = 0;
lockStartTimeStamp = true;
totalTimeStamp = 0.0;
}
}
}];
}
#pragma mark - CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
// CLLocation *location = locations[0];
// NSLog(@"location.coordinate.latitude :%f, location.coordinate.longitude : %f", location.coordinate.latitude, location.coordinate.longitude);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end

No comments:
Post a Comment