COLocation Swizzle in Dylib - PullRequest
       21

COLocation Swizzle in Dylib

0 голосов
/ 22 февраля 2019

Я пытался создать библиотеку (Dylib), которую затем вставлял в ipa, чтобы имитировать местоположение приложения на iphone.Я могу изменить позицию при запуске приложения и на несколько секунд, но затем позиция обновляется больше.Я должен выйти из приложения и повторно запустить его для обновления.Я не понимаю почему.Не могли бы вы помочь мне, пожалуйста?

Спасибо

#import <QuartzCore/QuartzCore.h>
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <objc/runtime.h>
#import "MapKit/MapKit.h"
#import "POControlView.h"

@interface CLLocation(Swizzle)

@end

@implementation CLLocation(Swizzle)

static float x = -1;
static float y = -1;

static float controlOffsetX = 0;
static float controlOffsetY = 0;

static POControlView *controlV;

static MKMapView *myMapView;
static UIButton *leavebutton;
static UILabel *coordinateLabel;

CLLocation *goLoc;

bool tag = false;

CLLocationDegrees kMockedLatitude = 28.5388;
CLLocationDegrees kMockedLongitude = -81.3756;

CLLocationCoordinate2D pos;


+ (void) load {
Method m1 = class_getInstanceMethod(self, @selector(coordinate));
Method m2 = class_getInstanceMethod(self, @selector(coordinate_));

method_exchangeImplementations(m1, m2);

Method m3 = class_getInstanceMethod(self,         
@selector(onClientEventLocation));
Method m4 = class_getInstanceMethod(self, 
@selector(onClientEventLocation_));

method_exchangeImplementations(m3, m4);

Method m5 = class_getInstanceMethod(self, @selector(setDelegate));
Method m6 = class_getInstanceMethod(self, @selector(setDelegate_));

method_exchangeImplementations(m5, m6);

Method m7 = class_getInstanceMethod([CLLocationManager alloc], 
@selector(didUpdateLocations));
Method m8 = class_getInstanceMethod(self, 
@selector(didUpdateLocations_));

method_exchangeImplementations(m7, m8);

Method m9 = class_getInstanceMethod([CLLocationManager class], 
@selector(startUpdatingLocation));
Method m10 = class_getInstanceMethod(self, 
@selector(startUpdatingLocation_));

method_exchangeImplementations(m9, m10);


if ([self  respondsToSelector:@selector(locationManager:didUpdateLocations:)]){
    [self locationManager:self didUpdateLocations:@[]];
}

if ([[NSUserDefaults standardUserDefaults] valueForKey:@"_fake_x"]) {
    x = [[[NSUserDefaults standardUserDefaults] valueForKey:@"_fake_x"] floatValue];
};

if ([[NSUserDefaults standardUserDefaults] valueForKey:@"_fake_y"]) {
    y = [[[NSUserDefaults standardUserDefaults] valueForKey:@"_fake_y"] floatValue];
};


// init
[self controlView];
}



-(void)setDelegate_:(id<CLLocationManagerDelegate>)delegate {
[self setDelegate_:delegate];
}

- (CLLocationCoordinate2D) coordinate_ {

pos = [self coordinate_];
//Default location
if (x == -1 && y == -1) {
    x = pos.latitude - (49.4458519);
    y = pos.longitude - (2.0045565);
    [[NSUserDefaults standardUserDefaults] setValue:@(x) forKey:@"_fake_x"];
    [[NSUserDefaults standardUserDefaults] setValue:@(y) forKey:@"_fake_y"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

return CLLocationCoordinate2DMake(pos.latitude+x + (controlOffsetX), pos.longitude+y + (controlOffsetY));
}

- (void)onClientEventLocation_:(id)foo {
int i = 0;
i++;
}

+ (float)randSetpDistance:(float)max to:(float)min {
return (((float)rand() / RAND_MAX) * (max - min)) + min;
}



+(POControlView *)controlView{
if (!controlV) {

   //NSString* directionsURL = @"http://maps.apple.com/?saddr=49.1111,2.4555&daddr=49.1111,2.4555";

    controlV = [[POControlView alloc] init];
    controlV.controlCallback =  ^(POControlViewDirection direction){
        switch (direction) {
            case POControlViewDirectionUp:
                x += self.controlOffset;
                break;
            case POControlViewDirectionDown:
                x-=self.controlOffset;
                break;
            case POControlViewDirectionLeft:
                y-=self.controlOffset;
                break;
            case POControlViewDirectionRight:
                y+=self.controlOffset;
                break;
            default:
                break;
        }
    };

    // add to key window
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        [[[UIApplication sharedApplication] keyWindow] addSubview:controlV];
        controlV.layer.cornerRadius = 5;
        controlV.layer.masksToBounds = YES;

        //add an info button
        UIButton *helpButton =  [UIButton buttonWithType:UIButtonTypeInfoDark ] ;
        CGRect buttonRect = helpButton.frame;

        CGRect screenRect = [[UIScreen mainScreen] bounds];
        CGFloat screenHeight = screenRect.size.height;

        buttonRect.origin.x = 30;
        buttonRect.origin.y = screenHeight - 110;
        [helpButton setFrame:buttonRect];

        [helpButton addTarget:self action:@selector(doMap) forControlEvents:UIControlEventTouchUpInside];
        [[[UIApplication sharedApplication] keyWindow] addSubview:helpButton];

        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
        [helpButton addGestureRecognizer:longPress];
        [longPress release];

    });

}
return controlV;
}

+(void)longPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateEnded ) {
    NSLog(@"Long Press");

    if(tag == false) {
        controlV.hidden = true;
        tag = true;
    }
    else {
        controlV.hidden = false;
        tag = false;
    }
}
}

+(float)controlOffset{
return [self randFloatBetween:0.000250 to:0.000300];
}

+(float) randFloatBetween:(float)low to:(float)high
{
float diff = high - low;
return (((float) rand() / RAND_MAX) * diff) + low;
}

+(void)doMap{
myMapView = [[MKMapView alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
//myMapView.alpha = 0.85;



coordinateLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 70, 50, 50)];
[coordinateLabel setBackgroundColor:[UIColor lightGrayColor]];//Set background color of label.
[coordinateLabel setText:@"Label"];//Set text in label.
[coordinateLabel setTextColor:[UIColor blackColor]];//Set text color in label.
[coordinateLabel setTextAlignment:NSTextAlignmentCenter];//Set text alignment in label.
[coordinateLabel setBaselineAdjustment:UIBaselineAdjustmentAlignBaselines];//Set line adjustment.
[coordinateLabel setLineBreakMode:NSLineBreakByCharWrapping];//Set linebreaking mode..
[coordinateLabel setNumberOfLines:1];//Set number of lines in label.
[coordinateLabel.layer setCornerRadius:25.0];//Set corner radius of label to change the shape.
[coordinateLabel.layer setBorderWidth:2.0f];//Set border width of label.
[coordinateLabel setClipsToBounds:YES];//Set its to YES for Corner radius to work.
[coordinateLabel.layer setBorderColor:[UIColor blackColor].CGColor];//Set Border color.


leavebutton = [[UIButton alloc]initWithFrame:CGRectMake(0, 20, 50, 50)];
[leavebutton setTitle:@"Close" forState:UIControlStateNormal];
[leavebutton addTarget:self action:@selector(leaveMap) forControlEvents:UIControlEventTouchUpInside];
[leavebutton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal ];

myMapView.showsUserLocation = YES;
myMapView.userTrackingMode = MKUserTrackingModeFollow;

[[[UIApplication sharedApplication] keyWindow] addSubview:myMapView];
[[[UIApplication sharedApplication] keyWindow] addSubview:leavebutton];
[[[UIApplication sharedApplication] keyWindow] addSubview:coordinateLabel];

//set the long press gesture recognizer
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture:)];
[myMapView addGestureRecognizer:longPressGesture];
}

+(void)leaveMap{
[myMapView removeFromSuperview];
[leavebutton removeFromSuperview];
}

+(void)handleLongPressGesture:(UIGestureRecognizer*)sender {


// This is important if you only want to receive one tap and hold event
if (sender.state == UIGestureRecognizerStateEnded)
{
    [myMapView removeGestureRecognizer:sender];
    //dismiss view as well
    [myMapView removeFromSuperview];
    [leavebutton removeFromSuperview];
}
else
{

    // Here we get the CGPoint for the touch and convert it to latitude and longitude coordinates to display on the map
    CGPoint point = [sender locationInView:myMapView];
    CLLocationCoordinate2D locCoord = [myMapView convertPoint:point toCoordinateFromView:myMapView];

    NSNumber *latitude = [NSNumber numberWithFloat:locCoord.latitude];
    NSNumber *longitude = [NSNumber numberWithFloat:locCoord.longitude];
    NSLog(@"lat: %@ long: %@", latitude, longitude);

    x = latitude.floatValue - pos.latitude;
    y = longitude.floatValue - pos.longitude;


}
}

@end
...