Commit 54dcbd9d authored by luyueming's avatar luyueming

添加的文件

parent 9b7d1d72
......@@ -27,7 +27,6 @@ PODS:
- GMShareSDK
- MBProgressHUD
- SDWebImage
- SnapKit (= 4.2.0)
- "UITableView+FDTemplateLayoutCell (= 1.4)"
- GMCache (1.0.1):
- TMCache (= 2.1.0)
......@@ -161,7 +160,7 @@ SPEC CHECKSUMS:
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
BDOpenSDKKit: 3fb530ce73f85a7d6ee69e7fd3d9158444c5bd09
DouyinOpenSDK: 5ba83de22963ba7a3ba70c8ff11dfcb2885ecc2b
GMBase: 070cc24cc99b5a839174cc4cc8905f5fd6f54a69
GMBase: 2f05a06e886f8ea355e6f8be4276b667611140b4
GMCache: b78d8e46db864405e91d226ce640cc80d966c611
GMFoundation: 59cdf19ad5bdc479162da975cc739cf5cb418ab6
GMHud: 18d41f4900a204f27be14e9504fcee2060ae3b2c
......
......@@ -18,12 +18,13 @@ Pod::Spec.new do |s|
s.dependency 'GMHud'
s.dependency 'GMKit'
s.dependency 'SDWebImage'
s.dependency 'SnapKit','4.2.0'
# s.dependency 'SnapKit', '4.0.0'
s.dependency 'GMShareSDK'
# s.dependency 'PLMediaStreamingKit'
# s.dependency 'PLPlayerKit'
# s.dependency 'GMAlbum'
# SnapKit 4.2.0
s.dependency 'SnapKit', '4.2.0'
# s.dependency 'SnapKit', '4.2.0'
s.swift_version = '4.2'
s.static_framework = true
......
//
// GMBaseTool.h
// GMBase
//
// Created by 卢悦明 on 2020/5/13.
//
#import <Foundation/Foundation.h>
#import <GMbase/GMNavigationController.h>
NS_ASSUME_NONNULL_BEGIN
@interface GMBaseTool : NSObject
/// 获取当前控制器
+ (UIViewController *)getCurrentViewController;
/// 获取window
+ (UIWindow *)mainWindow;
/// 获取导航控制器
+ (GMNavigationController *)getNavigation;
+ (void)userIsAllowPush:(void (^)(BOOL))isOpenPushBlock;
@end
NS_ASSUME_NONNULL_END
//
// GMBaseTool.m
// GMBase
//
// Created by 卢悦明 on 2020/5/13.
//
#import "GMBaseTool.h"
#import <UserNotifications/UserNotifications.h>
@implementation GMBaseTool
+ (UIViewController *)getRootViewController{
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
return window.rootViewController;
}
+ (UIViewController *)getCurrentViewController{
UIViewController* currentViewController = [self getRootViewController];
BOOL runLoopFind = YES;
while (runLoopFind) {
if (currentViewController.presentedViewController) {
currentViewController = currentViewController.presentedViewController;
} else if ([currentViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController* )currentViewController;
currentViewController = [navigationController.childViewControllers lastObject];
} else if ([currentViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController* )currentViewController;
currentViewController = tabBarController.selectedViewController;
} else {
NSUInteger childViewControllerCount = currentViewController.childViewControllers.count;
if (childViewControllerCount > 0) {
currentViewController = currentViewController.childViewControllers.lastObject;
return currentViewController;
} else {
return currentViewController;
}
}
}
return currentViewController;
}
//获取当前window
+ (UIWindow *)mainWindow
{
UIApplication *app = [UIApplication sharedApplication];
if ([app.delegate respondsToSelector:@selector(window)]) {
return [app.delegate window];
} else {
return [app keyWindow];
}
}
+ (GMNavigationController *)getNavigation {
UIViewController* rootVC = [self getRootViewController];
if ([rootVC isKindOfClass:[GMNavigationController class]]) {
return (GMNavigationController *)rootVC;
} else {
return nil;
}
}
#pragma mark - 判断用户是否允许推送
+ (void)userIsAllowPush:(void (^)(BOOL))isOpenPushBlock {
if (@available(iOS 10.0, *)) {
[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
dispatch_async(dispatch_get_main_queue(), ^{
if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined){
//未选择---没有选择允许或者不允许,按不允许处理
isOpenPushBlock(NO);
} else if (settings.authorizationStatus == UNAuthorizationStatusDenied){
//未授权--不允许推送
isOpenPushBlock(NO);
} else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized){
//已授权--允许推送
isOpenPushBlock(YES);
}
});
}];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings];
BOOL isAllow = (settings.types != UIUserNotificationTypeNone);
isOpenPushBlock(isAllow);
});
}
}
@end
//
// GMFloatWindow.h
// Gengmei
//
// Created by licong on 2018/1/25.
// Copyright © 2018年 更美互动信息科技有限公司. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface GMFloatWindow : UIView <UIGestureRecognizerDelegate>
//标记当前直播/回放页面是否是浮窗状态还是全屏状态, true -> 全屏, false -> 浮窗
@property (nonatomic, assign) BOOL isExpanded;
@property (nonatomic, assign) BOOL isShowingAnimation;
@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;
- (void)showController:(UIViewController *)controller;
- (void)hide;
- (void)hideWithNoAnimation;
- (void)zoomToSmall;
- (void)videoZoomToSmall;
- (void)expandAction:(UITapGestureRecognizer *)tapGesture;
@end
//
// GMFloatWindow.m
// Gengmei
//
// Created by licong on 2018/1/25.
// Copyright © 2018年 更美互动信息科技有限公司. All rights reserved.
//
#import "GMFloatWindow.h"
//#import "GMLoginManager.h"
//#import "UITabBar+ViewConstant.h"
#import "GMFloatWindowProtocol.h"
#import "GMBaseTool.h"
@import GMKit;
@interface GMFloatWindow()<CAAnimationDelegate> {
UIViewController *_controller;
}
@property (nonatomic, strong) UIPanGestureRecognizer *panGesture;
@end
@implementation GMFloatWindow
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:[UIScreen mainScreen].bounds];
if (self) {
self.clipsToBounds = YES;
self.backgroundColor = [UIColor clearColor];
_tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(expandAction:)];
_tapGesture.delegate = self;
_panGesture =[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
_panGesture.minimumNumberOfTouches = 1;
_panGesture.maximumNumberOfTouches = 1;
_panGesture.delegate = self;
self.isExpanded = YES;
}
return self;
}
- (void)showController:(UIViewController *)controller {
if (self.superview == nil) {
[[UIApplication sharedApplication].keyWindow addSubview:self];
// [[AppDelegate shareInstance].window addSubview:self];
}
_controller = controller;
[self addSubview:controller.view];
self.isShowingAnimation = YES;
if (_isExpanded) {
//当前没有小浮窗
//transform 要设置在前面因为它会印象frame
self.transform = CGAffineTransformMakeScale(1, 1);
self.frame = CGRectMake(0, MAINSCREEN_HEIGHT, MAINSCREEN_WIDTH, MAINSCREEN_HEIGHT);
self.layer.cornerRadius = 0;
self.hidden = NO;
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.top = 0;
} completion:^(BOOL finished) {
self.isShowingAnimation = NO;
}];
}else {
//当前已经有小浮窗,需要关闭当前小浮窗,在打开新的浮窗,具体实现其实是换了window的rootCtroller
//先移除手势
[self addGestureRecognizer:self.tapGesture];
[self addGestureRecognizer:self.panGesture];
//去掉圆角
self.layer.cornerRadius = 0;
//window大小还原,将window刚好放在屏幕下面
self.transform = CGAffineTransformMakeScale(1, 1);
self.frame = CGRectMake(0, MAINSCREEN_HEIGHT, MAINSCREEN_WIDTH, MAINSCREEN_HEIGHT);
[UIView animateWithDuration:0.25 delay:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.top = 0;
} completion:^(BOOL finished) {
self.isShowingAnimation = NO;
}];
}
}
- (void)hideWithNoAnimation{
self.hidden = YES;
//恢复成默认值
self.isExpanded = YES;
}
- (void)hide {
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.top = MAINSCREEN_HEIGHT;
} completion:^(BOOL finished) {
[self hideWithNoAnimation];
_controller = nil;
}];
}
- (void)expandAction:(UITapGestureRecognizer *)tapGesture{
[[GMBaseTool getCurrentViewController].view endEditing:YES];
self.layer.cornerRadius = 0;
self.hidden = NO;
[UIView animateWithDuration:0.25f animations:^{
self.transform = CGAffineTransformMakeScale(1, 1);
self.frame = CGRectMake(0, 0, MAINSCREEN_WIDTH, MAINSCREEN_HEIGHT);
} completion:^(BOOL finished) {
[self removeGestureRecognizer:self.tapGesture];
[self removeGestureRecognizer:self.panGesture];
}];
[(id<GMFloatWindowProtocol>)_controller showOtherViews];
_isExpanded = YES;
}
-(void)panAction:(UIPanGestureRecognizer *)recognizer {
UIWindow *window = [UIApplication sharedApplication].keyWindow;
CGPoint translatedPoint = [recognizer translationInView:window];
switch (recognizer.state) {
case UIGestureRecognizerStateBegan:
{
break;
}
case UIGestureRecognizerStateChanged:
{
CGFloat x = recognizer.view.center.x + translatedPoint.x;
CGFloat y = recognizer.view.center.y + translatedPoint.y;
if (x < recognizer.view.width / 2.0) {
x = recognizer.view.width / 2.0;
} else if (x + recognizer.view.width / 2.0 > MAINSCREEN_WIDTH) {
x = MAINSCREEN_WIDTH - recognizer.view.width / 2.0;
}
if (y < recognizer.view.height / 2.0) {
y = recognizer.view.height / 2.0;
} else if (y + recognizer.view.height / 2.0> MAINSCREEN_HEIGHT) {
y = MAINSCREEN_HEIGHT - recognizer.view.height / 2.0;
}
recognizer.view.center = CGPointMake(x, y);
UIWindow *window = [UIApplication sharedApplication].keyWindow;
[recognizer setTranslation:CGPointMake(0, 0) inView:window];
break;
}
case UIGestureRecognizerStateCancelled:
case UIGestureRecognizerStateEnded:
default:
break;
}
}
- (void)zoomToSmall {
if (_controller == nil) {
return;
}
[(id<GMFloatWindowProtocol>)_controller hideOtherViews];
self.layer.cornerRadius = 18;
_isExpanded = NO;
[UIView animateWithDuration:0.25f animations:^{
self.transform = CGAffineTransformMakeScale(0.35, 0.35);
self.frame = CGRectMake(MAINSCREEN_WIDTH * 0.65, 85, MAINSCREEN_WIDTH * 0.35, MAINSCREEN_HEIGHT * 0.35);
} completion:^(BOOL finished) {
[self addGestureRecognizer:self.tapGesture];
[self addGestureRecognizer:self.panGesture];
}];
}
// 视频缩小,宽是屏幕1/4,宽高比3:5
- (void)videoZoomToSmall {
if (_controller == nil) {
return;
}
[(id<GMFloatWindowProtocol>)_controller hideOtherViews];
self.layer.cornerRadius = 28;
_isExpanded = NO;
[UIView animateWithDuration:0.25f animations:^{
self.transform = CGAffineTransformMakeScale(0.35, 0.35);
self.frame = CGRectMake(MAINSCREEN_WIDTH * 0.75, MAINSCREEN_HEIGHT * 0.16, MAINSCREEN_WIDTH * 0.25, MAINSCREEN_WIDTH * 0.417);
} completion:^(BOOL finished) {
[self addGestureRecognizer:self.tapGesture];
[self addGestureRecognizer:self.panGesture];
}];
}
#pragma mark- Gesture Delagate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
@end
//
// GMFloatWindowProtocol.h
// Gengmei
//
// Created by wangyang on 2018/5/2.
// Copyright © 2018年 更美互动信息科技有限公司. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol GMFloatWindowProtocol <NSObject>
/**
GMFloatWindow 由全屏模式到小窗口模式,会调用此方法
*/
- (void)hideOtherViews;
/**
GMFloatWindow 由小窗口模式到全屏模式,会调用此方法
*/
- (void)showOtherViews;
@end
//
// WMLocationManager.h
// Gengmei
//
// Created by wangyang on 5/6/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#define kLastLocation @"lastLocation"
typedef void(^LocationFinishBlock)(CLLocation *location);
/**
保证新用户在有网络的情况下弹出 授权框 不然调不起地理位置弹框
*/
//typedef void(^RequestLocationAuthorization)();
@interface GMLocationManager : NSObject <CLLocationManagerDelegate>
@property (nonatomic, readonly) CLLocation *location;
@property (nonatomic, assign, readonly) NSInteger statusWhenAppBackground;
+ (instancetype)shareInstance;
/**
* @author wangyang, 16-03-11 17:03:21
*
* @brief 定位成功的回调
* @since 5.9.2
*/
- (void)addBlock:(LocationFinishBlock)block;
/**
* @author wangyang, 16-03-11 17:03:31
*
* @brief 在dealloc时需要手动移除先前添加的block
* @since 5.9.2
*/
- (void)removeLast;
/**
* @author wangyang, 16-02-24 15:02:11
*
* @brief 尝试使用定位功能。如果没有权限会有提示,如果有权限直接重新定位
* @since 5.9.1
*/
- (void)tryLocationService;
//@property (nonatomic, copy) RequestLocationAuthorization *authorizationBlock;
/**
保证有网络的l时候调用 不然那会失败
*/
-(void)notDeterminedShowLocationAuthorize;
/**
尝试使用定位功能。如果没有权限会有提示,并只提示一次
@param key 如果key不为nil,那么该key下的无权限提示只会展示一次,直到app删除。
如果key为nil,相当于调用tryLocationService
*/
- (void)tryLocationServiceForKey:(NSString *)key;
/**
* @author wangyang, 16-03-10 14:03:57
*
* @brief 静默的尝试重新定位,而不会有任何提示
* @since 5.9.2
*/
- (void)updateLocation;
/**
* @author wangyang, 16-03-10 12:03:57
*
* @brief 会判断是否允许定位服务
* @return YES表示允许
* @since 5.9.2
*/
+ (BOOL)hasOpenLocationService;
/**
* @author wangyang, 16-03-10 18:03:03
*
* @brief 跳转到定位服务的系统设置页
* @since 5.9.2
*/
+ (void)jumpToSettings;
/**
* @author wangyang, 16-03-10 12:03:21
*
* @brief 会判断是否允许定位服务,如果不允许会弹出alert
* @since 5.9.2
*/
+ (void)showAlertIfNotAllowed;
@end
//
// WMLocationManager.m
// Gengmei
//
// Created by wangyang on 5/6/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMLocationManager.h"
#import "JZLocationConverter.h"
#import <GMPhobos/Phobos.h>
#import <GMPhobos/UIResponder+PhobosPV.h>
#import "GMBaseTool.h"
@import GMFoundation;
@import GMCache;
@import GMKit;
@interface GMLocationManager ()<CLLocationManagerDelegate>{
NSMutableArray<LocationFinishBlock> *_blocks;
// 因为定位回调会走多次,使用该变量可以设定为只使用第一次返回的数据
BOOL _firstTime;
}
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) CLLocation *location;
@property (nonatomic, assign) NSInteger statusWhenAppBackground;
@end
@implementation GMLocationManager
+ (instancetype)shareInstance
{
static dispatch_once_t onceToken;
static id instance = nil;
dispatch_once(&onceToken, ^{
instance = [[[self class] alloc] init];
});
return instance;
}
- (instancetype)init
{
self = [super init];
if (self) {
_blocks = [NSMutableArray array];
// 实例化一个位置管理器
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
// 设置定位精度
// kCLLocationAccuracyNearestTenMeters:精度10米
// kCLLocationAccuracyHundredMeters:精度100 米
// kCLLocationAccuracyKilometer:精度1000 米
// kCLLocationAccuracyThreeKilometers:精度3000米
// kCLLocationAccuracyBest:设备使用电池供电时候最高的精度
// kCLLocationAccuracyBestForNavigation:导航情况下最高精度,一般要有外接电源时才能使用
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// distanceFilter是距离过滤器,为了减少对定位装置的轮询次数,位置的改变不会每次都去通知委托,而是在移动了足够的距离时才通知委托程序
// 它的单位是米,这里设置为至少移动1000再通知委托处理更新;
self.locationManager.distanceFilter = 1000.0f;// 如果设为kCLDistanceFilterNone,则每秒更新一次;
// 初始化
// _location = [[CLLocation alloc] initWithLatitude:0 longitude:0];
self.locationManager.pausesLocationUpdatesAutomatically = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
_firstTime = YES;
if ([GMLocationManager hasOpenLocationService]) {
[self updateLocation];
}
}
return self;
}
- (void)applicationDidEnterBackground {
self.statusWhenAppBackground = [CLLocationManager authorizationStatus];
}
#pragma mark - Method
/**
* @author wangyang, 16-03-10 12:03:57
*
* @brief 会判断是否允许定位服务
* @return YES表示允许
* @since 5.9.2
*/
+ (BOOL)hasOpenLocationService {
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if(status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse){
return YES;
}else{
return NO;
}
}
/**
* @author wangyang, 16-02-24 15:02:11
*
* @brief 尝试使用定位功能。如果没有权限会有提示,如果有权限直接重新定位
* @since 5.9.1
*/
- (void)tryLocationService {
[GMLocationManager showAlertIfNotAllowed];
[self requestAuthorization];
}
- (void)tryLocationServiceForKey:(NSString *)key {
[GMLocationManager showAlertIfNotAllowedForKey:key];
[self requestAuthorization];
}
+ (void)showAlertIfNotAllowed {
[self showAlertIfNotAllowedForKey:nil];
}
/**
* @author wangyang, 16-03-10 12:03:21
*
* @brief 会判断是否允许定位服务,如果不允许会弹出alert
* @since 5.9.2
*/
+ (void)showAlertIfNotAllowedForKey:(NSString *)key {
if (key != nil) {
NSString *value = [GMCache fetchObjectAtDocumentPathWithkey:key];
if (value != nil) {
return;
}
}
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
NSString *title = nil;
NSString *detail = nil;
NSString *cancelButton = @"好的";
NSString *otherButton = nil;
if (status == kCLAuthorizationStatusRestricted) {
title = @"无法使用定位服务";
} else if(status == kCLAuthorizationStatusDenied) {
title = @"定位服务已经关闭";
detail = @"请在设置中确保定位服务开启,并且允许该程序访问地理位置";
otherButton = @"去设置";
cancelButton = @"暂不";
}
// 如果用户关闭了定位服务,或者某种未预料到的原因使title总不为空
if ([title isNonEmpty]) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:detail preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:cancelButton style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
if (key != nil) {
[GMCache storeObjectAtDocumentPathWithkey:key object:key];
}
}]];
if ([otherButton isNonEmpty]) {
[alert addAction:[UIAlertAction actionWithTitle:otherButton style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[GMLocationManager jumpToSettings];
if (key != nil) {
[GMCache storeObjectAtDocumentPathWithkey:key object:key];
}
}]];
}
// 虽然选择城市页是被present的,但是 visibleViewController 仍然能访问到该controller
[[GMBaseTool getCurrentViewController] presentViewController:alert animated:YES completion:NULL];
}
}
+ (void)jumpToSettings {
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusNotDetermined) {
[[GMLocationManager shareInstance] tryLocationService];
return;
}
// iOS8及以后可以跳转到该app的专有设置页
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:NULL];
} else {
[[UIApplication sharedApplication] openURL:url];
}
}
/**
* @author wangyang, 16-02-24 15:02:30
*
* @brief 以请求相应权限。如果定位服务异常不做任何处理,因为有相应的需求来处理这定位异常
* @since 5.9.1
*/
- (void)requestAuthorization{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if(status == kCLAuthorizationStatusNotDetermined){
// 弹出是否允许使用位置服务 要保证有网络的情况下弹出 请求 不然会报错
// [self.locationManager requestWhenInUseAuthorization];
[self _updatingLocation];
} else if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse){
[self _updatingLocation];
}
}
- (void)notDeterminedShowLocationAuthorize {
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestWhenInUseAuthorization];
[Phobos track:@"popup_view" attributes:@{@"page_name": SafeString([GMBaseTool getCurrentViewController].pageName), @"popup_name": @"location"} sendNow:YES];
[self _updatingLocation];
} else {
[self _updatingLocation];
}
}
- (void)updateLocation {
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
BOOL enable = [CLLocationManager locationServicesEnabled];
if (enable && (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse)) {
[self _updatingLocation];
}
}
- (void)_updatingLocation {
[self.locationManager startUpdatingLocation];
_firstTime = YES;
}
#pragma mark - CLLocationManagerDelegate
// 地理位置发生改变时触发
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
// 注意此处可能会被多次调用,这是CoreLocation中的正常现象
self.location = locations.lastObject;
[self finishUpdatingLocation];
}
// 定位失误时触发
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
// self.location = [[CLLocation alloc] initWithLatitude:0 longitude:0];
[self finishUpdatingLocation];
if (error.code == kCLErrorLocationUnknown ) {
NSLog(@"获取失败,会继续尝试获取位置信息");
}
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
// 如果不允许访问地理位置,直接完成
if (status == kCLAuthorizationStatusRestricted || status == kCLAuthorizationStatusDenied) {
[self finishUpdatingLocation];
[Phobos track:@"report_status" attributes:@{@"page_name": SafeString([GMBaseTool getCurrentViewController].pageName), @"report_name":@"close_location"} sendNow:YES];
}else if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse){
[self _updatingLocation];
[Phobos track:@"report_status" attributes:@{@"page_name": SafeString([GMBaseTool getCurrentViewController].pageName), @"report_name":@"open_location"} sendNow:YES];
}
}
- (void)finishUpdatingLocation {
for (int i = 0; i < _blocks.count; i ++) {
LocationFinishBlock block = _blocks[i];
block(self.location);
}
}
// iOS返回的是国际坐标,需要转换为百度坐标
- (void)setLocation:(CLLocation *)location {
if (location == nil) {
return;
}
CLLocationCoordinate2D coordinate = [JZLocationConverter wgs84ToBd09:location.coordinate];
// ZX 不开启定位时,不需要传经纬度 经过上边方法转换后有小误差,手动置为0
if (![GMLocationManager hasOpenLocationService]) {
coordinate.latitude = 0;
coordinate.longitude = 0;
}
_location = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
[GMCache storeObjectAtDiskWithkey:kLastLocation object:_location];
}
#pragma mark - Block Manage
- (void)addBlock:(LocationFinishBlock)block {
[_blocks addObject:block];
}
- (void)removeLast {
[_blocks removeLastObject];
}
@end
//
// JZLocationConverter.h
// Gengmei
//
// Created by wangyang on 2017/8/15.
// Copyright © 2017年 更美互动信息科技有限公司. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
@interface JZLocationConverter : NSObject
/**
* @brief 世界标准地理坐标(WGS-84) 转换成 中国国测局地理坐标(GCJ-02)<火星坐标>
*
* ####只在中国大陆的范围的坐标有效,以外直接返回世界标准坐标
*
* @param location 世界标准地理坐标(WGS-84)
*
* @return 中国国测局地理坐标(GCJ-02)<火星坐标>
*/
+ (CLLocationCoordinate2D)wgs84ToGcj02:(CLLocationCoordinate2D)location;
/**
* @brief 中国国测局地理坐标(GCJ-02) 转换成 世界标准地理坐标(WGS-84)
*
* ####此接口有1-2米左右的误差,需要精确定位情景慎用
*
* @param location 中国国测局地理坐标(GCJ-02)
*
* @return 世界标准地理坐标(WGS-84)
*/
+ (CLLocationCoordinate2D)gcj02ToWgs84:(CLLocationCoordinate2D)location;
/**
* @brief 世界标准地理坐标(WGS-84) 转换成 百度地理坐标(BD-09)
*
* @param location 世界标准地理坐标(WGS-84)
*
* @return 百度地理坐标(BD-09)
*/
+ (CLLocationCoordinate2D)wgs84ToBd09:(CLLocationCoordinate2D)location;
/**
* @brief 中国国测局地理坐标(GCJ-02)<火星坐标> 转换成 百度地理坐标(BD-09)
*
* @param location 中国国测局地理坐标(GCJ-02)<火星坐标>
*
* @return 百度地理坐标(BD-09)
*/
+ (CLLocationCoordinate2D)gcj02ToBd09:(CLLocationCoordinate2D)location;
/**
* @brief 百度地理坐标(BD-09) 转换成 中国国测局地理坐标(GCJ-02)<火星坐标>
*
* @param location 百度地理坐标(BD-09)
*
* @return 中国国测局地理坐标(GCJ-02)<火星坐标>
*/
+ (CLLocationCoordinate2D)bd09ToGcj02:(CLLocationCoordinate2D)location;
/**
* @brief 百度地理坐标(BD-09) 转换成 世界标准地理坐标(WGS-84)
*
* ####此接口有1-2米左右的误差,需要精确定位情景慎用
*
* @param location 百度地理坐标(BD-09)
*
* @return 世界标准地理坐标(WGS-84)
*/
+ (CLLocationCoordinate2D)bd09ToWgs84:(CLLocationCoordinate2D)location;
@end
//
// JZLocationConverter.m
// Gengmei
//
// Created by wangyang on 2017/8/15.
// Copyright © 2017年 更美互动信息科技有限公司. All rights reserved.
//
#import "JZLocationConverter.h"
@implementation JZLocationConverter
#define LAT_OFFSET_0(x,y) -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x))
#define LAT_OFFSET_1 (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0
#define LAT_OFFSET_2 (20.0 * sin(y * M_PI) + 40.0 * sin(y / 3.0 * M_PI)) * 2.0 / 3.0
#define LAT_OFFSET_3 (160.0 * sin(y / 12.0 * M_PI) + 320 * sin(y * M_PI / 30.0)) * 2.0 / 3.0
#define LON_OFFSET_0(x,y) 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x))
#define LON_OFFSET_1 (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0
#define LON_OFFSET_2 (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0
#define LON_OFFSET_3 (150.0 * sin(x / 12.0 * M_PI) + 300.0 * sin(x / 30.0 * M_PI)) * 2.0 / 3.0
#define X_PI ((M_PI * 3000.0) / 180.0)
#define RANGE_LON_MAX 137.8347
#define RANGE_LON_MIN 72.004
#define RANGE_LAT_MAX 55.8271
#define RANGE_LAT_MIN 0.8293
// jzA = 6378245.0, 1/f = 298.3
// b = a * (1 - f)
// ee = (a^2 - b^2) / a^2;
#define jzA 6378245.0
#define jzEE 0.00669342162296594323
+ (double)transformLat:(double)x bdLon:(double)y
{
double ret = LAT_OFFSET_0(x, y);
ret += LAT_OFFSET_1;
ret += LAT_OFFSET_2;
ret += LAT_OFFSET_3;
return ret;
}
+ (double)transformLon:(double)x bdLon:(double)y
{
double ret = LON_OFFSET_0(x, y);
ret += LON_OFFSET_1;
ret += LON_OFFSET_2;
ret += LON_OFFSET_3;
return ret;
}
+ (BOOL)outOfChina:(double)lat bdLon:(double)lon
{
if (lon < RANGE_LON_MIN || lon > RANGE_LON_MAX)
return true;
if (lat < RANGE_LAT_MIN || lat > RANGE_LAT_MAX)
return true;
return false;
}
+ (CLLocationCoordinate2D)gcj02Encrypt:(double)ggLat bdLon:(double)ggLon
{
CLLocationCoordinate2D resPoint;
double mgLat;
double mgLon;
if ([self outOfChina:ggLat bdLon:ggLon]) {
resPoint.latitude = ggLat;
resPoint.longitude = ggLon;
return resPoint;
}
double dLat = [self transformLat:(ggLon - 105.0)bdLon:(ggLat - 35.0)];
double dLon = [self transformLon:(ggLon - 105.0) bdLon:(ggLat - 35.0)];
double radLat = ggLat / 180.0 * M_PI;
double magic = sin(radLat);
magic = 1 - jzEE * magic * magic;
double sqrtMagic = sqrt(magic);
dLat = (dLat * 180.0) / ((jzA * (1 - jzEE)) / (magic * sqrtMagic) * M_PI);
dLon = (dLon * 180.0) / (jzA / sqrtMagic * cos(radLat) * M_PI);
mgLat = ggLat + dLat;
mgLon = ggLon + dLon;
resPoint.latitude = mgLat;
resPoint.longitude = mgLon;
return resPoint;
}
+ (CLLocationCoordinate2D)gcj02Decrypt:(double)gjLat gjLon:(double)gjLon {
CLLocationCoordinate2D gPt = [self gcj02Encrypt:gjLat bdLon:gjLon];
double dLon = gPt.longitude - gjLon;
double dLat = gPt.latitude - gjLat;
CLLocationCoordinate2D pt;
pt.latitude = gjLat - dLat;
pt.longitude = gjLon - dLon;
return pt;
}
+ (CLLocationCoordinate2D)bd09Decrypt:(double)bdLat bdLon:(double)bdLon
{
CLLocationCoordinate2D gcjPt;
double x = bdLon - 0.0065, y = bdLat - 0.006;
double z = sqrt(x * x + y * y) - 0.00002 * sin(y * X_PI);
double theta = atan2(y, x) - 0.000003 * cos(x * X_PI);
gcjPt.longitude = z * cos(theta);
gcjPt.latitude = z * sin(theta);
return gcjPt;
}
+(CLLocationCoordinate2D)bd09Encrypt:(double)ggLat bdLon:(double)ggLon
{
CLLocationCoordinate2D bdPt;
double x = ggLon, y = ggLat;
double z = sqrt(x * x + y * y) + 0.00002 * sin(y * X_PI);
double theta = atan2(y, x) + 0.000003 * cos(x * X_PI);
bdPt.longitude = z * cos(theta) + 0.0065;
bdPt.latitude = z * sin(theta) + 0.006;
return bdPt;
}
+ (CLLocationCoordinate2D)wgs84ToGcj02:(CLLocationCoordinate2D)location
{
return [self gcj02Encrypt:location.latitude bdLon:location.longitude];
}
+ (CLLocationCoordinate2D)gcj02ToWgs84:(CLLocationCoordinate2D)location
{
return [self gcj02Decrypt:location.latitude gjLon:location.longitude];
}
+ (CLLocationCoordinate2D)wgs84ToBd09:(CLLocationCoordinate2D)location
{
CLLocationCoordinate2D gcj02Pt = [self gcj02Encrypt:location.latitude
bdLon:location.longitude];
return [self bd09Encrypt:gcj02Pt.latitude bdLon:gcj02Pt.longitude] ;
}
+ (CLLocationCoordinate2D)gcj02ToBd09:(CLLocationCoordinate2D)location
{
return [self bd09Encrypt:location.latitude bdLon:location.longitude];
}
+ (CLLocationCoordinate2D)bd09ToGcj02:(CLLocationCoordinate2D)location
{
return [self bd09Decrypt:location.latitude bdLon:location.longitude];
}
+ (CLLocationCoordinate2D)bd09ToWgs84:(CLLocationCoordinate2D)location
{
CLLocationCoordinate2D gcj02 = [self bd09ToGcj02:location];
return [self gcj02Decrypt:gcj02.latitude gjLon:gcj02.longitude];
}
@end
//
// WMAlertParameterObject.h
// Gengmei
//
// Created by Sean Lee on 9/8/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <GMBase/GMObject.h>
/**
* @author licong, 15-11-27 15:11:44
*
* H5执行OC方法时候,传过来的参数
*
*/
@interface WMAlertParameterObject : GMObject
@property (nonatomic, strong) NSString * title;
@property (nonatomic, strong) NSString * content;
@property (nonatomic, strong) NSString * confirmText;
@property (nonatomic, strong) NSString * cancelText;
@property (nonatomic, strong) NSString * confirmCallback;
@property (nonatomic, strong) NSString * cancelCallback;
@end
@interface WMToastParameterObject : GMObject
@property (nonatomic, strong) NSString * text;
@property (nonatomic, assign) NSInteger duration;
@end
\ No newline at end of file
//
// WMAlertParameterObject.m
// Gengmei
//
// Created by Sean Lee on 9/8/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "WMAlertParameterObject.h"
@implementation WMAlertParameterObject
@end
@implementation WMToastParameterObject
@end
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment