summaryrefslogtreecommitdiff
path: root/test/ios/LocationMocker/CLLocationManager+MockLocation.m
blob: ad95e5219d037e0f542a020e36205b87ea3d68b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//
// Based on gist by Eric Allam
// https://gist.github.com/ericallam/5689235
//

#import "CLLocationManager+MockLocation.h"
#import "LocationMocker.h"

// This category implements methods that will be swizzled to replace key methods
// in CLLocationManager to mock out the user location.
@implementation CLLocationManager (MockLocation)

// Replaces startUpdatingLocation, will send the locationManager:didUpdateLocations: message
// to the delegate after a wait of 0.1 seconds using dispatch_after to simulate how 
// startUpdatingLocation actually works. This will not simulate any kind of location errors.
- (void)custom_startUpdatingLocation
{
    if (self.delegate)
    {
        if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateLocations:)])
        {
            // delay the locationManager:didUpdateLocations: message 0.1 seconds
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
                NSArray *locations = @[self.location];
                [self.delegate locationManager:self didUpdateLocations:locations];
            });
        }
        
        if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateToLocation:fromLocation:)])
        {
            // delay the locationManager:didUpdateToLocation:fromLocation: message 0.1 seconds
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
                #pragma clang diagnostic push
                #pragma clang diagnostic ignored "-Wdeprecated-declarations"
                #pragma clang diagnostic ignored "-Wnonnull"
                [self.delegate locationManager:self didUpdateToLocation:self.location fromLocation:nil];
                #pragma clang diagnostic pop
            });
        }
    }
}

// Replaces location, returns the mocked CLLocation object
- (CLLocation *)custom_location;
{
    return [[CLLocation alloc] initWithLatitude:kMockedLatitude longitude:kMockedLongitude];
}


// Replaces startUpdatingHeading, sends locationManager:didUpdateHeading:
- (void)custom_startUpdatingHeading
{
    if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateHeading:)])
    {
        // delay the locationManager:didUpdateHeading: message 0.1 seconds
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
            [self.delegate locationManager:self didUpdateHeading:self.heading];
        });
    }
}

// Replaces heading, returns the mocked CLHeading object
- (CLHeading *)custom_heading;
{
    CLHeadingStruct heading;
    heading.accuracy = kMockedHeadingAccuracy;
    heading.trueHeading = kMockedHeadingTrueHeading;
    heading.magneticHeading = kMockedHeadingMagneticHeading;
    heading.x = kMockedHeadingX;
    heading.y = kMockedHeadingY;
    heading.z = kMockedHeadingZ;
    
    return [[CLHeading alloc] initWithClientHeading:heading];
}

+ (BOOL)custom_headingAvailable
{
    return YES;
}

@end