增加换肤功能
This commit is contained in:
17
QXLive/Base/NSURLSession+QX.h
Normal file
17
QXLive/Base/NSURLSession+QX.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// NSURLSession+BJX.h
|
||||
// BJXGame
|
||||
//
|
||||
// Created by apple on 2022/11/7.
|
||||
// Copyright © 2022 鑫创. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NSURLSession (QX)
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
37
QXLive/Base/NSURLSession+QX.m
Normal file
37
QXLive/Base/NSURLSession+QX.m
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// NSURLSession+BJX.m
|
||||
// BJXGame
|
||||
//
|
||||
// Created by apple on 2022/11/7.
|
||||
// Copyright © 2022 鑫创. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSURLSession+QX.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation NSURLSession (QX)
|
||||
+ (void)load{
|
||||
Method method1 = class_getClassMethod([NSURLSession class],@selector(sessionWithConfiguration:));
|
||||
Method method2 = class_getClassMethod([NSURLSession class],@selector(px_sessionWithConfiguration:));
|
||||
method_exchangeImplementations(method1, method2);
|
||||
|
||||
Method method3 =class_getClassMethod([NSURLSession class],@selector(sessionWithConfiguration:delegate:delegateQueue:));
|
||||
Method method4 =class_getClassMethod([NSURLSession class],@selector(px_sessionWithConfiguration:delegate:delegateQueue:));
|
||||
method_exchangeImplementations(method3, method4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+ (NSURLSession*)px_sessionWithConfiguration:(NSURLSessionConfiguration*)configuration delegate:(nullable id)delegate delegateQueue:(nullable NSOperationQueue*)queue{
|
||||
if(configuration) configuration.connectionProxyDictionary=@{};
|
||||
return [self px_sessionWithConfiguration:configuration delegate:delegate delegateQueue:queue];
|
||||
}
|
||||
|
||||
|
||||
|
||||
+ (NSURLSession*)px_sessionWithConfiguration:(NSURLSessionConfiguration*)configuration{
|
||||
if(configuration) configuration.connectionProxyDictionary=@{};
|
||||
return [self px_sessionWithConfiguration:configuration];
|
||||
}
|
||||
|
||||
@end
|
||||
26
QXLive/Base/QXAlertViewController.h
Normal file
26
QXLive/Base/QXAlertViewController.h
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// QXAlertViewController.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/27.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
typedef NS_ENUM(NSInteger) {
|
||||
///从底部向上弹出view 弹出形式类似于actionsheet
|
||||
PopViewTypeBottomToUpActionSheet = 0,
|
||||
///从中间弹出
|
||||
PopViewTypePopFromCenter,
|
||||
///从顶部向中间弹窗
|
||||
PopViewTypeTopToCenter,
|
||||
}PopViewType;
|
||||
@interface QXAlertViewController : UIViewController
|
||||
@property (nonatomic,strong)UIView *alertView;
|
||||
@property (nonatomic,assign)PopViewType popType;
|
||||
@property (nonatomic,assign)BOOL tapDismiss;
|
||||
-(void)hideViewFinishBlock:(void(^)(void))closeBlock;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
152
QXLive/Base/QXAlertViewController.m
Normal file
152
QXLive/Base/QXAlertViewController.m
Normal file
@@ -0,0 +1,152 @@
|
||||
//
|
||||
// QXAlertViewController.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/27.
|
||||
//
|
||||
|
||||
#import "QXAlertViewController.h"
|
||||
|
||||
@interface QXAlertViewController ()<UIGestureRecognizerDelegate>
|
||||
|
||||
@property(nonatomic,copy)void (^closeBlock)(void);
|
||||
@end
|
||||
|
||||
@implementation QXAlertViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
self.view.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.3];
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
|
||||
tap.delegate = self;
|
||||
[self.view addGestureRecognizer:tap];
|
||||
|
||||
}
|
||||
-(void)viewDidAppear:(BOOL)animated{
|
||||
[super viewDidAppear:animated];
|
||||
[self beginShow];
|
||||
}
|
||||
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
|
||||
[self.view endEditing:YES];
|
||||
}
|
||||
-(void)beginShow{
|
||||
_alertView.centerX = self.view.centerX;
|
||||
switch (_popType) {
|
||||
case PopViewTypeBottomToUpActionSheet:{
|
||||
_alertView.y = SCREEN_HEIGHT;
|
||||
[self.view addSubview:_alertView];
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
self->_alertView.y = (SCREEN_HEIGHT-self->_alertView.height);
|
||||
} completion:^(BOOL finished) {
|
||||
|
||||
}];
|
||||
}
|
||||
break;
|
||||
case PopViewTypePopFromCenter:{
|
||||
_alertView.centerX = self.view.centerX;
|
||||
_alertView.centerY = self.view.centerY;
|
||||
[self.view addSubview:_alertView];
|
||||
_alertView.transform = CGAffineTransformMakeScale(0.1, 0.1);
|
||||
// 弹性动画
|
||||
[UIView animateWithDuration:0.3
|
||||
delay:0
|
||||
usingSpringWithDamping:0.9
|
||||
initialSpringVelocity:0.1
|
||||
options:UIViewAnimationOptionCurveEaseInOut
|
||||
animations:^{
|
||||
self->_alertView.transform = CGAffineTransformIdentity;
|
||||
} completion:nil];
|
||||
}
|
||||
|
||||
break;
|
||||
case PopViewTypeTopToCenter:{
|
||||
_alertView.y = -SCREEN_HEIGHT;
|
||||
[self.view addSubview:_alertView];
|
||||
[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.6 initialSpringVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
self->_alertView.y = (SCREEN_HEIGHT-self->_alertView.height)/2.0;
|
||||
} completion:^(BOOL finished) {
|
||||
|
||||
}];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
-(void)tapAction{
|
||||
if (!self.tapDismiss) {
|
||||
return;
|
||||
}
|
||||
[self hideViewFinishBlock:self.closeBlock];
|
||||
}
|
||||
|
||||
-(void)hideViewFinishBlock:(void (^)(void))closeBlock{
|
||||
MJWeakSelf
|
||||
switch (_popType) {
|
||||
case PopViewTypeBottomToUpActionSheet:{
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
self->_alertView.y = SCREEN_HEIGHT;
|
||||
} completion:^(BOOL finished) {
|
||||
[self->_alertView removeFromSuperview];
|
||||
[self dismissViewControllerAnimated:NO completion:^{
|
||||
if (closeBlock) {
|
||||
closeBlock();
|
||||
}
|
||||
}];
|
||||
}];
|
||||
}
|
||||
break;
|
||||
case PopViewTypePopFromCenter:{
|
||||
[UIView animateWithDuration:0.3
|
||||
delay:0
|
||||
usingSpringWithDamping:0.9
|
||||
initialSpringVelocity:1
|
||||
options:UIViewAnimationOptionCurveEaseInOut
|
||||
animations:^{
|
||||
self->_alertView.transform = CGAffineTransformMakeScale(0.001, 0.001);
|
||||
} completion:^(BOOL finished) {
|
||||
[self->_alertView removeFromSuperview];
|
||||
[self dismissViewControllerAnimated:NO completion:^{
|
||||
if (closeBlock) {
|
||||
closeBlock();
|
||||
}
|
||||
}];
|
||||
}];
|
||||
}
|
||||
break;
|
||||
case PopViewTypeTopToCenter:{
|
||||
[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.6 initialSpringVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
||||
self->_alertView.y = SCREEN_HEIGHT;
|
||||
} completion:^(BOOL finished) {
|
||||
[self->_alertView removeFromSuperview];
|
||||
[self dismissViewControllerAnimated:NO completion:^{
|
||||
if (closeBlock) {
|
||||
closeBlock();
|
||||
}
|
||||
}];
|
||||
}];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)setPopType:(PopViewType)popType{
|
||||
_popType = popType;
|
||||
}
|
||||
|
||||
-(void)setAlertView:(UIView *)alertView{
|
||||
if (_alertView) {
|
||||
[_alertView removeFromSuperview];
|
||||
_alertView = nil;
|
||||
}
|
||||
_alertView = alertView;
|
||||
}
|
||||
|
||||
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
|
||||
return touch.view == self.view;
|
||||
}
|
||||
|
||||
@end
|
||||
16
QXLive/Base/QXAppStartViewController.h
Normal file
16
QXLive/Base/QXAppStartViewController.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// QXAppStartViewController.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/8/12.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface QXAppStartViewController : UIViewController
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
107
QXLive/Base/QXAppStartViewController.m
Normal file
107
QXLive/Base/QXAppStartViewController.m
Normal file
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// QXAppStartViewController.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/8/12.
|
||||
//
|
||||
|
||||
#import "QXAppStartViewController.h"
|
||||
#import "AppDelegate.h"
|
||||
@interface QXAppStartViewController ()
|
||||
@property (nonatomic,strong)UIImageView *bgImaegView;
|
||||
@end
|
||||
|
||||
@implementation QXAppStartViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
self.bgImaegView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
self.bgImaegView.image = [UIImage imageNamed:@"启动页"];;
|
||||
self.bgImaegView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
[self.view addSubview:self.bgImaegView];
|
||||
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginSuccess) name:noticeUserLogin object:nil];
|
||||
[self getAppTheme];
|
||||
}
|
||||
-(void)viewDidDisappear:(BOOL)animated{
|
||||
[super viewDidDisappear:animated];
|
||||
// [[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
-(void)getAppTheme{
|
||||
NSString *themeUrl = [NSString stringWithFormat:@"%@%@",ServerUrl,QXAppTheme];
|
||||
[[QXRequset shareInstance] getWithUrl:themeUrl parameters:@{} needCache:NO success:^(id responseObject) {
|
||||
[QXConfig defaultConfig];
|
||||
QXThemeModel *model = [QXThemeModel yy_modelWithJSON:responseObject[@"data"]];
|
||||
if (model.theme_color && model.theme_color.length > 0) {
|
||||
QXConfig.shared.themeColor = [UIColor colorWithHexString:model.theme_color];
|
||||
}
|
||||
// QXConfig.shared.themeColor = [UIColor colorWithHexString:@"#ff0000"];
|
||||
if (model.btn_text_color && model.btn_text_color.length > 0) {
|
||||
QXConfig.shared.btnTextColor = [UIColor colorWithHexString:model.btn_text_color];
|
||||
}
|
||||
if (model.app_bg && model.app_bg.length > 0) {
|
||||
QXConfig.shared.backgroundImage = model.app_bg;
|
||||
}
|
||||
QXTabbarModel *tabbarIndex1 = QXConfig.shared.tabbarArray[0];
|
||||
QXTabbarModel *tabbarIndex2 = QXConfig.shared.tabbarArray[1];
|
||||
QXTabbarModel *tabbarIndex3 = QXConfig.shared.tabbarArray[2];
|
||||
QXTabbarModel *tabbarIndex4 = QXConfig.shared.tabbarArray[3];
|
||||
|
||||
if (model.home_nor && model.home_nor.length > 0) {
|
||||
tabbarIndex1.normalImage = model.home_nor;
|
||||
}
|
||||
if (model.home_sel && model.home_sel.length > 0) {
|
||||
tabbarIndex1.selectedImage = model.home_sel;
|
||||
}
|
||||
|
||||
if (model.find_nor && model.find_nor.length > 0) {
|
||||
tabbarIndex2.normalImage = model.find_nor;
|
||||
}
|
||||
if (model.find_sel && model.find_sel.length > 0) {
|
||||
tabbarIndex2.selectedImage = model.find_sel;
|
||||
}
|
||||
|
||||
if (model.msg_nor && model.msg_nor.length > 0) {
|
||||
tabbarIndex3.normalImage = model.msg_nor;
|
||||
}
|
||||
if (model.msg_sel && model.msg_sel.length > 0) {
|
||||
tabbarIndex3.selectedImage = model.msg_sel;
|
||||
}
|
||||
|
||||
if (model.mine_nor && model.mine_nor.length > 0) {
|
||||
tabbarIndex4.normalImage = model.mine_nor;
|
||||
}
|
||||
if (model.mine_sel && model.mine_sel.length > 0) {
|
||||
tabbarIndex4.selectedImage = model.mine_sel;
|
||||
}
|
||||
QXConfig.shared.tabbarArray = @[tabbarIndex1,tabbarIndex2,tabbarIndex3,tabbarIndex4];
|
||||
AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
[delegate changeRootViewControllerIsTabbar];
|
||||
NSLog(@"请求成功");
|
||||
} fail:^(NSError *error, NSString *msg, NSURLSessionDataTask *task) {
|
||||
NSLog(@"请求失败");
|
||||
[self alertNetworkError];
|
||||
}];
|
||||
}
|
||||
-(void)loginSuccess{
|
||||
[self getAppTheme];
|
||||
}
|
||||
-(void)alertNetworkError{
|
||||
MJWeakSelf
|
||||
UIAlertController *al = [UIAlertController alertControllerWithTitle:@"网络错误" message:@"" preferredStyle:(UIAlertControllerStyleAlert)];
|
||||
[al addAction:[UIAlertAction actionWithTitle:@"重试" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
|
||||
[weakSelf getAppTheme];
|
||||
}]];
|
||||
[self presentViewController:al animated:YES completion:nil];
|
||||
}
|
||||
/*
|
||||
#pragma mark - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
// Get the new view controller using [segue destinationViewController].
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
16
QXLive/Base/QXBadgeButton.h
Normal file
16
QXLive/Base/QXBadgeButton.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// QXBadgeButton.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/7/28.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TIMCommonModel.h"
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface QXBadgeButton : UIButton
|
||||
@property (nonatomic,strong)TUIUnReadView *unreadView;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
64
QXLive/Base/QXBadgeButton.m
Normal file
64
QXLive/Base/QXBadgeButton.m
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// QXBadgeButton.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/7/28.
|
||||
//
|
||||
|
||||
#import "QXBadgeButton.h"
|
||||
|
||||
@implementation QXBadgeButton
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self addSubview:self.unreadView];
|
||||
[self.unreadView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(self);
|
||||
make.right.equalTo(self);
|
||||
make.width.mas_equalTo(kScale375(17));
|
||||
make.height.mas_equalTo(kScale375(17));
|
||||
}];
|
||||
|
||||
|
||||
[self.unreadView.unReadLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.center.mas_equalTo(self.unreadView);
|
||||
make.size.mas_equalTo(self.unreadView.unReadLabel);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self addSubview:self.unreadView];
|
||||
[self.unreadView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(self);
|
||||
make.right.equalTo(self);
|
||||
make.width.mas_equalTo(kScale375(17));
|
||||
make.height.mas_equalTo(kScale375(17));
|
||||
}];
|
||||
|
||||
|
||||
[self.unreadView.unReadLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.center.mas_equalTo(self.unreadView);
|
||||
make.size.mas_equalTo(self.unreadView.unReadLabel);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
-(TUIUnReadView *)unreadView{
|
||||
if (!_unreadView) {
|
||||
_unreadView = [[TUIUnReadView alloc] init];
|
||||
_unreadView.userInteractionEnabled = NO;
|
||||
[_unreadView setNum:0];
|
||||
|
||||
[_unreadView.unReadLabel sizeToFit];
|
||||
|
||||
_unreadView.layer.cornerRadius = kScale375(10);
|
||||
[_unreadView.layer masksToBounds];
|
||||
}
|
||||
return _unreadView;
|
||||
}
|
||||
@end
|
||||
16
QXLive/Base/QXBaseModel.h
Normal file
16
QXLive/Base/QXBaseModel.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// QXBaseModel.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/5/13.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface QXBaseModel : NSObject
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
12
QXLive/Base/QXBaseModel.m
Normal file
12
QXLive/Base/QXBaseModel.m
Normal file
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// QXBaseModel.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/5/13.
|
||||
//
|
||||
|
||||
#import "QXBaseModel.h"
|
||||
|
||||
@implementation QXBaseModel
|
||||
|
||||
@end
|
||||
16
QXLive/Base/QXBaseNavigationController.h
Normal file
16
QXLive/Base/QXBaseNavigationController.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// QXBaseNavigationController.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/24.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface QXBaseNavigationController : UINavigationController
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
79
QXLive/Base/QXBaseNavigationController.m
Normal file
79
QXLive/Base/QXBaseNavigationController.m
Normal file
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// QXBaseNavigationController.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/24.
|
||||
//
|
||||
|
||||
#import "QXBaseNavigationController.h"
|
||||
|
||||
@interface QXBaseNavigationController ()<UINavigationControllerDelegate,UIGestureRecognizerDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation QXBaseNavigationController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
self.interactivePopGestureRecognizer.delegate = self;
|
||||
self.delegate = self;
|
||||
}
|
||||
-(void)viewWillAppear:(BOOL)animated{
|
||||
[super viewWillAppear:animated];
|
||||
}
|
||||
|
||||
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
|
||||
if (self.viewControllers.count == 1) {
|
||||
viewController.hidesBottomBarWhenPushed = YES;
|
||||
}
|
||||
// if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
|
||||
// self.interactivePopGestureRecognizer.enabled = YES;
|
||||
// }
|
||||
[super pushViewController:viewController animated:animated];
|
||||
}
|
||||
//-(UIViewController *)popViewControllerAnimated:(BOOL)animated{
|
||||
// if (self.childViewControllers.count == 2) {
|
||||
// if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
|
||||
// self.interactivePopGestureRecognizer.enabled = YES;
|
||||
// }
|
||||
// }
|
||||
// return [super popViewControllerAnimated:animated];
|
||||
//}
|
||||
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
|
||||
if (self.childViewControllers.count > 1) {
|
||||
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
|
||||
if ([self.visibleViewController isKindOfClass:NSClassFromString(@"QXRoomViewController")]) {
|
||||
self.interactivePopGestureRecognizer.enabled = NO;
|
||||
}else{
|
||||
self.interactivePopGestureRecognizer.enabled = YES;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
|
||||
self.interactivePopGestureRecognizer.enabled = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
|
||||
if (self.viewControllers.count == 1) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
/*
|
||||
#pragma mark - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
// Get the new view controller using [segue destinationViewController].
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
26
QXLive/Base/QXBaseViewController.h
Normal file
26
QXLive/Base/QXBaseViewController.h
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// QXBaseViewController.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/24.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface QXBaseViewController : UIViewController
|
||||
@property (nonatomic,strong)NSMutableArray *dataArray;
|
||||
@property (nonatomic,assign)NSInteger page;
|
||||
@property (nonatomic,assign)BOOL bgImageHidden;
|
||||
//交给子类来实现
|
||||
-(void)setNavgationItems;
|
||||
-(void)initSubViews;
|
||||
- (void)getData;
|
||||
/**
|
||||
imageurl :图片名称或链接
|
||||
*/
|
||||
-(void)updateBgImage:(NSString*)imageUrl;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
80
QXLive/Base/QXBaseViewController.m
Normal file
80
QXLive/Base/QXBaseViewController.m
Normal file
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// QXBaseViewController.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/24.
|
||||
//
|
||||
|
||||
#import "QXBaseViewController.h"
|
||||
|
||||
@interface QXBaseViewController ()
|
||||
@property (nonatomic,strong)UIImageView *bgImageView;
|
||||
@property (nonatomic,strong)NSString *imageUrl;
|
||||
@end
|
||||
|
||||
@implementation QXBaseViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
[self.view insertSubview:self.bgImageView atIndex:0];
|
||||
[self updateBgImage:QXConfig.backgroundImage];
|
||||
[self initSubViews];
|
||||
[self setNavgationItems];
|
||||
[self getData];
|
||||
self.page = 1;
|
||||
}
|
||||
- (void)initSubViews{
|
||||
|
||||
}
|
||||
- (void)getData{
|
||||
|
||||
}
|
||||
-(void)setNavgationItems{
|
||||
UIButton*backBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
|
||||
[backBtn setImage:[UIImage imageNamed:@"back"] forState:(UIControlStateNormal)];
|
||||
backBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeading;
|
||||
[backBtn addTarget:self action:@selector(backAction) forControlEvents:(UIControlEventTouchUpInside)];
|
||||
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn];
|
||||
}
|
||||
-(void)backAction{
|
||||
if (self.navigationController.viewControllers.count > 1) {
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
return;
|
||||
}else{
|
||||
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
}
|
||||
-(void)setBgImageHidden:(BOOL)bgImageHidden{
|
||||
_bgImageHidden = bgImageHidden;
|
||||
self.bgImageView.hidden = bgImageHidden;
|
||||
}
|
||||
-(void)updateBgImage:(NSString *)imageUrl{
|
||||
_imageUrl = imageUrl;
|
||||
if (![imageUrl isExist]) {
|
||||
return;
|
||||
}
|
||||
if ([imageUrl hasPrefix:@"http"] || [imageUrl hasPrefix:@"https"]) {
|
||||
[self.bgImageView sd_setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:nil];
|
||||
}else{
|
||||
self.bgImageView.image = [UIImage imageNamed:imageUrl];
|
||||
}
|
||||
}
|
||||
-(UIImageView *)bgImageView{
|
||||
if (!_bgImageView) {
|
||||
_bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
|
||||
_bgImageView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
_bgImageView.clipsToBounds = YES;
|
||||
}
|
||||
return _bgImageView;
|
||||
}
|
||||
-(NSMutableArray *)dataArray{
|
||||
if (!_dataArray) {
|
||||
_dataArray = [NSMutableArray array];
|
||||
}
|
||||
return _dataArray;
|
||||
}
|
||||
-(void)dealloc{
|
||||
QXLOG(@"%@已销毁",NSStringFromClass([self class]));
|
||||
}
|
||||
@end
|
||||
23
QXLive/Base/QXBaseWebViewController.h
Normal file
23
QXLive/Base/QXBaseWebViewController.h
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// TBaseWebViewController.h
|
||||
// YSDTrucksProject
|
||||
//
|
||||
// Created by 党凯 on 2020/7/3.
|
||||
// Copyright © 2020 党凯. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QXBaseViewController.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface QXBaseWebViewController : QXBaseViewController
|
||||
//网页链接
|
||||
@property(nonatomic,copy)NSString *urlStr;
|
||||
//html内容
|
||||
@property(nonatomic,copy)NSString *content;
|
||||
/** 进度条颜色 */
|
||||
@property (nonatomic, assign) UIColor *progressColor;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
243
QXLive/Base/QXBaseWebViewController.m
Normal file
243
QXLive/Base/QXBaseWebViewController.m
Normal file
@@ -0,0 +1,243 @@
|
||||
//
|
||||
// QXBaseWebViewController.m
|
||||
// YSDTrucksProject
|
||||
//
|
||||
// Created by 党凯 on 2020/7/3.
|
||||
// Copyright © 2020 党凯. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QXBaseWebViewController.h"
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
static void *WKWebBrowserContext = &WKWebBrowserContext;
|
||||
@interface QXBaseWebViewController ()<WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler>
|
||||
@property(nonatomic,strong)WKWebView *contentWebView;
|
||||
@property(nonatomic,strong)UIProgressView *progressView;
|
||||
//@property (nonatomic,strong)TitleView *titleView;
|
||||
@end
|
||||
|
||||
@implementation QXBaseWebViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
// if (@available(iOS 11.0, *)) {
|
||||
// self.contentWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
// } else {
|
||||
// self.automaticallyAdjustsScrollViewInsets = NO;
|
||||
// }
|
||||
|
||||
[self.view addSubview:self.contentWebView];
|
||||
[self.view addSubview:self.progressView];
|
||||
|
||||
[self layoutConstraints];
|
||||
[self loadData];
|
||||
}
|
||||
-(void)viewWillAppear:(BOOL)animated{
|
||||
[super viewWillAppear:animated];
|
||||
[self.navigationController setNavigationBarHidden:NO animated:YES];
|
||||
}
|
||||
-(void)setNavgationItems{
|
||||
[super setNavgationItems];
|
||||
}
|
||||
- (void)layoutConstraints {
|
||||
[self.contentWebView setFrame:CGRectMake(0, NavContentHeight, SCREEN_WIDTH, SCREEN_HEIGHT-(NavContentHeight))];
|
||||
[self.progressView setFrame:CGRectMake(0, NavContentHeight, SCREEN_WIDTH
|
||||
, 2)];
|
||||
}
|
||||
- (void)loadData {
|
||||
if (self.urlStr.length) {
|
||||
if ([self.urlStr hasPrefix:@"http"]) {
|
||||
NSURL* url=[NSURL URLWithString:self.urlStr];
|
||||
NSURLRequest *request =[NSURLRequest requestWithURL:url];
|
||||
[self.contentWebView loadRequest:request];
|
||||
}else{
|
||||
NSURL* url=[NSURL fileURLWithPath:self.urlStr];
|
||||
NSURLRequest *request =[NSURLRequest requestWithURL:url];
|
||||
[self.contentWebView loadRequest:request];
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (self.content.length) {
|
||||
[self.contentWebView loadHTMLString:self.content baseURL:nil];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - WKNavigationDelegate
|
||||
//开始加载
|
||||
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
|
||||
//开始加载的时候,让加载进度条显示
|
||||
self.progressView.hidden = NO;
|
||||
}
|
||||
|
||||
//网页加载完成
|
||||
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
|
||||
// 获取加载网页的标题
|
||||
if (self.title.length == 0) {
|
||||
self.title = self.contentWebView.title;
|
||||
}
|
||||
// if ([self.titleString containsString:@"转账"]) {
|
||||
// // 设置字体
|
||||
// NSString *fontFamilyStr = @"document.getElementsByTagName('body')[0].style.fontFamily='Arial';";
|
||||
// [webView evaluateJavaScript:fontFamilyStr completionHandler:nil];
|
||||
// //设置颜色
|
||||
// [ webView evaluateJavaScript:@"document.getElementsByTagName('body')[0].style.webkitTextFillColor= '#333333'" completionHandler:nil];
|
||||
// //修改字体大小
|
||||
// [ webView evaluateJavaScript:@"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '150%'"completionHandler:nil];
|
||||
// }
|
||||
}
|
||||
//内容返回时调用
|
||||
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
|
||||
|
||||
}
|
||||
|
||||
//服务器请求跳转的时候调用
|
||||
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
|
||||
|
||||
}
|
||||
|
||||
// 内容加载失败时候调用
|
||||
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{
|
||||
|
||||
}
|
||||
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
|
||||
NSLog(@"message.name====%@ body=%@",message.name,message.body);
|
||||
if([message.name isEqualToString:@"toRegister"]){
|
||||
// RegistVC *vc = [[RegistVC alloc] init];
|
||||
// vc.isRegist = YES;
|
||||
// [self.navigationController pushViewController:vc animated:YES];
|
||||
// NSMutableArray *vcArr = [[NSMutableArray alloc]initWithArray:self.navigationController.viewControllers];
|
||||
// for (UIViewController *vc in vcArr) {
|
||||
// if ([vc isKindOfClass:[self class]]) {
|
||||
// [vcArr removeObject:vc];
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// self.navigationController.viewControllers = vcArr;
|
||||
}
|
||||
}
|
||||
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
|
||||
//如果是跳转一个新页面
|
||||
if (navigationAction.targetFrame == nil) {
|
||||
[webView loadRequest:navigationAction.request];
|
||||
}
|
||||
NSURL *URL = navigationAction.request.URL;
|
||||
[self dealSomeThing:URL];
|
||||
decisionHandler(WKNavigationActionPolicyAllow);
|
||||
}
|
||||
|
||||
- (void)dealSomeThing:(NSURL *)url{
|
||||
NSString *scheme = [url scheme];
|
||||
NSString *resourceSpecifier = [url resourceSpecifier];
|
||||
if ([scheme isEqualToString:@"tel"]) {
|
||||
NSString *callPhone = [NSString stringWithFormat:@"tel://%@", resourceSpecifier];
|
||||
/// 防止iOS 10及其之后,拨打电话系统弹出框延迟出现
|
||||
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone]];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//进度条
|
||||
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
|
||||
}
|
||||
|
||||
//KVO监听进度条
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
||||
|
||||
if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == self.contentWebView) {
|
||||
[self.progressView setAlpha:1.0f];
|
||||
BOOL animated = self.contentWebView.estimatedProgress > self.progressView.progress;
|
||||
[self.progressView setProgress:self.contentWebView.estimatedProgress animated:animated];
|
||||
|
||||
// Once complete, fade out UIProgressView
|
||||
if(self.contentWebView.estimatedProgress >= 1.0f) {
|
||||
[UIView animateWithDuration:0.3f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
|
||||
[self.progressView setAlpha:0.0f];
|
||||
} completion:^(BOOL finished) {
|
||||
[self.progressView setProgress:0.0f animated:NO];
|
||||
}];
|
||||
}
|
||||
}
|
||||
else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - getters and setters
|
||||
- (WKWebView *)contentWebView {
|
||||
if (!_contentWebView) {
|
||||
//设置网页的配置文件
|
||||
WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
|
||||
// 允许可以与网页交互,选择视图
|
||||
configuration.selectionGranularity = YES;
|
||||
// web内容处理池pr
|
||||
configuration.processPool = [[WKProcessPool alloc] init];
|
||||
//自定义配置,一般用于 js调用oc方法(OC拦截URL中的数据做自定义操作)
|
||||
WKUserContentController * UserContentController = [[WKUserContentController alloc]init];
|
||||
// 是否支持记忆读取
|
||||
configuration.suppressesIncrementalRendering = YES;
|
||||
// 允许用户更改网页的设置
|
||||
[UserContentController addScriptMessageHandler:self name:@"toRegister"];
|
||||
configuration.preferences.javaScriptEnabled = YES;
|
||||
configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
|
||||
configuration.userContentController = UserContentController;
|
||||
// 此处一定要做判断,因为是iOS9之后才有的方法,否则在iOS8下会崩溃
|
||||
if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
|
||||
//允许视频播放
|
||||
configuration.allowsAirPlayForMediaPlayback = YES;
|
||||
// 允许在线播放
|
||||
configuration.allowsInlineMediaPlayback = YES;
|
||||
//开启手势触摸 默认设置就是NO。在ios8系统中会导致手势问题,程序崩溃
|
||||
_contentWebView.allowsBackForwardNavigationGestures = YES;
|
||||
}
|
||||
_contentWebView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
|
||||
_contentWebView.backgroundColor = [UIColor whiteColor];
|
||||
_contentWebView.opaque = YES;
|
||||
//适应你设定的尺寸
|
||||
[_contentWebView sizeToFit];
|
||||
_contentWebView.scrollView.showsVerticalScrollIndicator = NO;
|
||||
// 设置代理
|
||||
_contentWebView.navigationDelegate = self;
|
||||
//kvo 添加进度监控
|
||||
[_contentWebView addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:0 context:WKWebBrowserContext];
|
||||
}
|
||||
return _contentWebView;
|
||||
}
|
||||
|
||||
- (UIProgressView *)progressView {
|
||||
if (!_progressView) {
|
||||
_progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleDefault];
|
||||
[_progressView setTrackTintColor:[UIColor colorWithRed:240.0/255 green:240.0/255 blue:240.0/255 alpha:1.0]];
|
||||
_progressView.progressTintColor = QXConfig.themeColor;
|
||||
}
|
||||
return _progressView;
|
||||
}
|
||||
|
||||
-(void)setProgressColor:(UIColor *)progressColor{
|
||||
_progressView.progressTintColor = progressColor;
|
||||
}
|
||||
// 记得dealloc
|
||||
- (void)dealloc {
|
||||
if (self) {
|
||||
[self.contentWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
|
||||
}
|
||||
}
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
/*
|
||||
#pragma mark - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
// Get the new view controller using [segue destinationViewController].
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
116
QXLive/Base/QXGlobal.h
Normal file
116
QXLive/Base/QXGlobal.h
Normal file
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// QXGlobal.h
|
||||
// YSDTrucksProject
|
||||
//
|
||||
// Created by 党凯 on 2020/6/30.
|
||||
// Copyright © 2020 党凯. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "QXAlertViewController.h"
|
||||
#import "QXLoginModel.h"
|
||||
#import "QXMiniRoomView.h"
|
||||
#import "QXDayTaskModel.h"
|
||||
#import "QXRoomViewController.h"
|
||||
|
||||
typedef void (^closeBlock)(void);
|
||||
typedef void (^showFinishBlock)(void);
|
||||
typedef NS_ENUM(NSInteger) {
|
||||
/// 房主
|
||||
QXRoomRoleTypeOwner = 0,
|
||||
/// 主持
|
||||
QXRoomRoleTypeCompere,
|
||||
/// 管理员
|
||||
QXRoomRoleTypeManager,
|
||||
/// 观众
|
||||
QXRoomRoleTypeAudience,
|
||||
}QXRoomRoleType;
|
||||
|
||||
|
||||
@interface QXGlobal : NSObject
|
||||
+(instancetype)shareGlobal;
|
||||
// 是否登录
|
||||
@property (nonatomic,readonly,assign)BOOL isLogin;
|
||||
@property (nonatomic,assign)BOOL isShowLoginVC;
|
||||
/// 房间id
|
||||
@property (nonatomic,strong,readonly)NSString *roomId;
|
||||
// 是否实名
|
||||
@property (nonatomic,assign)BOOL isRealName;
|
||||
|
||||
/// 钻石兑币比例
|
||||
@property (nonatomic,strong)NSString *coin_exchange_rate;
|
||||
/// 提现手续费
|
||||
@property (nonatomic,strong)NSString *withdrawal_service_fee;
|
||||
/// 购买金币比例
|
||||
@property (nonatomic,strong)NSString *rmb_coin_ratio;
|
||||
|
||||
@property (nonatomic,strong)QXLoginModel *loginModel;
|
||||
// 初始化时是否支持一键登录
|
||||
@property (nonatomic,assign)BOOL canOneLogin;
|
||||
|
||||
@property (nonatomic,strong)QXAlertViewController *alertViewController;
|
||||
|
||||
@property (nonatomic,strong) QXMiniRoomView *miniView;
|
||||
|
||||
/// 每日任务id
|
||||
@property (nonatomic,strong) QXDayTaskListModel *taskModel;
|
||||
|
||||
@property (nonatomic,strong) QXRoomViewController *roomVC;
|
||||
|
||||
-(void)miniRoomWithRoomId:(NSString*)roomId roomCover:(NSString*)roomCover;
|
||||
|
||||
|
||||
-(BOOL)isOpenRecharge;
|
||||
|
||||
-(UIWindow*)getKeyWindow;
|
||||
|
||||
/// 退出登录
|
||||
-(void)logOut;
|
||||
|
||||
-(void)removeLocalData;
|
||||
|
||||
/// 保存个人信息
|
||||
-(void)saveLoginData:(NSString*)userInfoJson;
|
||||
/// 更新个人信息
|
||||
-(void)updateUserInfoWithMolde:(QXLoginModel *)loginModel;
|
||||
|
||||
-(void)removeMemory;
|
||||
|
||||
-(void)toLogin;
|
||||
-(void)showView:(UIView *)view popType:(PopViewType)popType tapDismiss:(BOOL)tapDismiss finishBlock:(showFinishBlock)finishBlock;
|
||||
-(void)showView:(UIView *)view controller:(UIViewController*)controller popType:(PopViewType)popType tapDismiss:(BOOL)tapDismiss finishBlock:(showFinishBlock)finishBlock;
|
||||
-(void)hideViewBlock:(closeBlock)closeBlock;
|
||||
|
||||
/**
|
||||
去聊天
|
||||
*/
|
||||
-(void)chatWithUserID:(NSString*)userId
|
||||
nickname:(NSString*)nickname
|
||||
avatar:(NSString*)avatar
|
||||
navagationController:(UINavigationController*)navagationController;
|
||||
/**
|
||||
去群聊
|
||||
*/
|
||||
-(void)chatWithGroupId:(NSString*)groupId
|
||||
cover:(NSString*)cover
|
||||
name:(NSString*)name
|
||||
navagationController:(UINavigationController*)navagationController;
|
||||
|
||||
/**
|
||||
加入房间
|
||||
*/
|
||||
-(void)joinRoomWithRoomId:(NSString*)roomId
|
||||
isRejoin:(BOOL)isRejoin
|
||||
navagationController:(UINavigationController*)navagationController;
|
||||
|
||||
/**
|
||||
退出房间
|
||||
*/
|
||||
-(void)quitRoomWithRoomId:(NSString*)roomId;
|
||||
/// 去完成任务
|
||||
-(void)finishTask;
|
||||
|
||||
-(void)vibrationFeedback;
|
||||
@end
|
||||
|
||||
|
||||
297
QXLive/Base/QXGlobal.m
Normal file
297
QXLive/Base/QXGlobal.m
Normal file
@@ -0,0 +1,297 @@
|
||||
//
|
||||
// QXGlobal.m
|
||||
// TrucksProject
|
||||
//
|
||||
// Created by 党凯 on 2020/6/30.
|
||||
// Copyright © 2020 党凯. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QXGlobal.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "QXLoginViewController.h"
|
||||
#import "QXBaseNavigationController.h"
|
||||
#import "TUILogin.h"
|
||||
#import "QXChatViewController.h"
|
||||
#import "QXRoomViewController.h"
|
||||
#import "QXMineNetwork.h"
|
||||
#import "QXGiftPlayerManager.h"
|
||||
#import "QXAgoraEngine.h"
|
||||
#import "QXRoomMessageManager.h"
|
||||
#import "QXTimer.h"
|
||||
#import <TIMPush/TIMPushManager.h>
|
||||
#import "QXManagerMqtt.h"
|
||||
|
||||
@interface QXGlobal()
|
||||
@property (nonatomic,assign)BOOL isLogin;
|
||||
@property (nonatomic,strong)NSString *roomId;
|
||||
|
||||
@property (nonatomic,strong)QXTimer *timer;
|
||||
@property (nonatomic,assign)NSInteger taskTime;
|
||||
@end
|
||||
@implementation QXGlobal
|
||||
+ (instancetype)shareGlobal {
|
||||
static QXGlobal *global = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
global = [[self alloc] init];
|
||||
global.isShowLoginVC = NO;
|
||||
});
|
||||
return global;
|
||||
}
|
||||
-(UIWindow *)getKeyWindow{
|
||||
AppDelegate*appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
UIWindow *window = appDelegate.window;
|
||||
return window;
|
||||
}
|
||||
-(void)logOut{
|
||||
[TUILogin logout:^{
|
||||
QXLOG(@"腾讯im退出登录成功");
|
||||
} fail:^(int code, NSString * _Nullable msg) {
|
||||
QXLOG(@"腾讯im退出登录失败");
|
||||
}];
|
||||
self.isLogin = NO;
|
||||
[self removeLocalData];
|
||||
[self removeMemory];
|
||||
AppDelegate *appdelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
|
||||
/// 移除推送监听
|
||||
[TIMPushManager removePushListener:appdelegate];
|
||||
/// 移除会话监听
|
||||
[[V2TIMManager sharedInstance] removeConversationListener:appdelegate];
|
||||
[TIMPushManager unRegisterPush:^{
|
||||
//success
|
||||
} fail:^(int code, NSString * _Nonnull desc) {
|
||||
//error
|
||||
}];
|
||||
|
||||
if (self.isShowLoginVC == YES) {
|
||||
return;
|
||||
}
|
||||
QXLoginViewController *vc = [[QXLoginViewController alloc] init];
|
||||
QXBaseNavigationController *na = [[QXBaseNavigationController alloc] initWithRootViewController:vc];
|
||||
na.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
[self.getKeyWindow.rootViewController presentViewController:na animated:YES completion:nil];
|
||||
self.isShowLoginVC = YES;
|
||||
/// 断开mqtt连接
|
||||
[[QXManagerMqtt sharedInstance] disconnect];
|
||||
|
||||
}
|
||||
-(void)saveLoginData:(NSString *)userInfoJson{
|
||||
[[NSUserDefaults standardUserDefaults] setObject:userInfoJson forKey:kUserLoginData];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
-(void)updateUserInfoWithMolde:(QXLoginModel *)loginModel{
|
||||
NSString *jsonStr = [loginModel yy_modelToJSONString];
|
||||
[self saveLoginData:jsonStr];
|
||||
}
|
||||
//-(void)setLoginModel:(QXLoginModel *)loginModel{
|
||||
// _loginModel = loginModel;
|
||||
// if (loginModel == nil) {
|
||||
// self.isLogin = NO;
|
||||
// }else{
|
||||
// self.isLogin = YES;
|
||||
// }
|
||||
//}
|
||||
-(BOOL)isRealName{
|
||||
return [QXGlobal shareGlobal].loginModel.auth == 1;
|
||||
}
|
||||
-(QXLoginModel *)loginModel{
|
||||
if (!_loginModel) {
|
||||
NSString *jsonStr = [[NSUserDefaults standardUserDefaults] objectForKey:kUserLoginData];
|
||||
if (jsonStr.length > 0) {
|
||||
_loginModel = [QXLoginModel yy_modelWithJSON:jsonStr];
|
||||
self.isLogin = YES;
|
||||
}else{
|
||||
_loginModel = nil;
|
||||
self.isLogin = NO;
|
||||
}
|
||||
}
|
||||
return _loginModel;
|
||||
}
|
||||
-(void)toLogin{
|
||||
|
||||
}
|
||||
-(BOOL)isLogin{
|
||||
NSString *jsonStr = [[NSUserDefaults standardUserDefaults] objectForKey:kUserLoginData];
|
||||
return jsonStr.length > 0;
|
||||
}
|
||||
-(void)removeLocalData{
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kUserLoginData];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
-(void)removeMemory{
|
||||
QXGlobal.shareGlobal.loginModel = nil;
|
||||
}
|
||||
-(void)showView:(UIView *)view popType:(PopViewType)popType tapDismiss:(BOOL)tapDismiss finishBlock:(showFinishBlock)finishBlock{
|
||||
self.alertViewController = [[QXAlertViewController alloc] init];
|
||||
self.alertViewController.popType = popType;
|
||||
self.alertViewController.alertView = view;
|
||||
self.alertViewController.tapDismiss = tapDismiss;
|
||||
self.alertViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
||||
[[QXGlobal shareGlobal].getKeyWindow.rootViewController presentViewController:self.alertViewController animated:NO completion:finishBlock];
|
||||
}
|
||||
|
||||
-(void)showView:(UIView *)view controller:(UIViewController*)controller popType:(PopViewType)popType tapDismiss:(BOOL)tapDismiss finishBlock:(showFinishBlock)finishBlock{
|
||||
self.alertViewController = [[QXAlertViewController alloc] init];
|
||||
self.alertViewController.popType = popType;
|
||||
self.alertViewController.alertView = view;
|
||||
self.alertViewController.tapDismiss = tapDismiss;
|
||||
self.alertViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
||||
[controller presentViewController:self.alertViewController animated:NO completion:finishBlock];
|
||||
}
|
||||
-(void)hideViewBlock:(closeBlock)closeBlock{
|
||||
[self.alertViewController hideViewFinishBlock:closeBlock];
|
||||
}
|
||||
-(BOOL)isOpenRecharge{
|
||||
BOOL isOpenRecharge = [[NSUserDefaults standardUserDefaults] boolForKey:kIsOpenRecharge];
|
||||
return isOpenRecharge;
|
||||
}
|
||||
|
||||
-(void)finishTask{
|
||||
if (QXGlobal.shareGlobal.taskModel != nil) {
|
||||
[QXMineNetwork dayTaskFinishedWithTaskId:QXGlobal.shareGlobal.taskModel.task_id successBlock:^(NSDictionary * _Nonnull dict) {
|
||||
NSString *is_completed = [NSString stringWithFormat:@"%@",dict[@"is_completed"]];
|
||||
if (is_completed.intValue == 1) {
|
||||
QXGlobal.shareGlobal.taskModel = nil;
|
||||
QXGlobal.shareGlobal.taskTime = 0;
|
||||
if (self->_timer) {
|
||||
[self->_timer invalidate];
|
||||
self->_timer = nil;
|
||||
}
|
||||
}
|
||||
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
|
||||
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)chatWithUserID:(NSString *)userId nickname:(NSString *)nickname avatar:(NSString *)avatar navagationController:(UINavigationController *)navagationController{
|
||||
QXChatViewController *vc = [[QXChatViewController alloc] init];
|
||||
TUIChatConversationModel *data = [[TUIChatConversationModel alloc] init];
|
||||
data.userID = [NSString stringWithFormat:@"u%@",userId];
|
||||
data.title = nickname;
|
||||
data.faceUrl = avatar;
|
||||
vc.data = data;
|
||||
[navagationController pushViewController:vc animated:YES];
|
||||
}
|
||||
|
||||
-(void)chatWithGroupId:(NSString *)groupId cover:(NSString *)cover name:(NSString *)name navagationController:(UINavigationController *)navagationController{
|
||||
QXChatViewController *vc = [[QXChatViewController alloc] init];
|
||||
TUIChatConversationModel *data = [[TUIChatConversationModel alloc] init];
|
||||
if ([groupId containsString:@"g"]) {
|
||||
data.groupID = groupId;
|
||||
}else{
|
||||
data.groupID = [NSString stringWithFormat:@"g%@",groupId];
|
||||
}
|
||||
data.faceUrl = cover;
|
||||
data.title = name;
|
||||
vc.data = data;
|
||||
[navagationController pushViewController:vc animated:YES];
|
||||
}
|
||||
|
||||
-(void)joinRoomWithRoomId:(NSString *)roomId isRejoin:(BOOL)isRejoin navagationController:(UINavigationController *)navagationController{
|
||||
if (!QXGlobal.shareGlobal.isLogin) {
|
||||
[[QXGlobal shareGlobal] logOut];
|
||||
return;
|
||||
}
|
||||
navagationController = (QXBaseNavigationController*)KEYWINDOW.rootViewController;
|
||||
// navagationController.interactivePopGestureRecognizer.enabled = NO;
|
||||
if (_miniView) {
|
||||
[_miniView removeFromSuperview];
|
||||
_miniView = nil;
|
||||
}
|
||||
if ([roomId isEqualToString:self.roomId]) {
|
||||
if ([navagationController.viewControllers containsObject:self.roomVC]) {
|
||||
return;
|
||||
}else{
|
||||
self.roomVC.hidesBottomBarWhenPushed = YES;
|
||||
[navagationController pushViewController:self.roomVC animated:YES];
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (self.roomId && ![self.roomId isEqualToString:roomId]) {
|
||||
[self quitRoomWithRoomId:self.roomId];
|
||||
}
|
||||
if (isRejoin) {
|
||||
if (self.roomVC!=nil) {
|
||||
self.roomVC.hidesBottomBarWhenPushed = YES;
|
||||
[navagationController pushViewController:self.roomVC animated:YES];
|
||||
}else{
|
||||
self.roomVC = [[QXRoomViewController alloc] init];
|
||||
self.roomVC.roomId = roomId;
|
||||
self.roomVC.isReJoin = isRejoin;
|
||||
self.roomId = roomId;
|
||||
self.roomVC.hidesBottomBarWhenPushed = YES;
|
||||
[navagationController pushViewController:self.roomVC animated:YES];
|
||||
}
|
||||
}else{
|
||||
if ([roomId isEqualToString:self.roomVC.roomId]) {
|
||||
[navagationController pushViewController:self.roomVC animated:YES];
|
||||
}else{
|
||||
self.roomVC = [[QXRoomViewController alloc] init];
|
||||
self.roomVC.roomId = roomId;
|
||||
self.roomVC.isReJoin = isRejoin;
|
||||
self.roomId = roomId;
|
||||
self.roomVC.hidesBottomBarWhenPushed = YES;
|
||||
[navagationController pushViewController:self.roomVC animated:YES];
|
||||
}
|
||||
}
|
||||
if (QXGlobal.shareGlobal.taskModel != nil) {
|
||||
/// 是否带有每日任务
|
||||
if (QXGlobal.shareGlobal.taskModel.task_id.intValue == 9) {
|
||||
/// 是计时任务
|
||||
if (_timer == nil) {
|
||||
_timer = [QXTimer scheduledTimerWithTimeInterval:1 repeats:YES queue:dispatch_get_main_queue() block:^{
|
||||
QXGlobal.shareGlobal.taskTime++;
|
||||
if (QXGlobal.shareGlobal.taskTime%60 == 0) {
|
||||
[[QXGlobal shareGlobal] finishTask];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)quitRoomWithRoomId:(NSString *)roomId{
|
||||
/// 移除特效
|
||||
[[QXGiftPlayerManager shareManager] destroyEffectSvga];
|
||||
/// 退出声网
|
||||
[[QXAgoraEngine sharedEngine] leaveChannel];
|
||||
|
||||
[[QXAgoraEngine sharedEngine] ktv_DestoryKtvPlayer];
|
||||
|
||||
[[QXAgoraEngine sharedEngine] destroyEngine];
|
||||
/// 退出直播群
|
||||
[[QXRoomMessageManager shared] quitGroupWithRoomId:roomId];
|
||||
self.roomId = nil;
|
||||
_roomVC = nil;
|
||||
/// 业务http退出
|
||||
[QXMineNetwork quitRoomWithRoomId:roomId user_id:[QXGlobal shareGlobal].loginModel.user_id successBlock:^(NSDictionary * _Nonnull dict) {
|
||||
|
||||
} failBlock:^(NSError * _Nonnull error, NSString * _Nonnull msg) {
|
||||
|
||||
}];
|
||||
|
||||
if (_timer) {
|
||||
[_timer invalidate];
|
||||
_timer = nil;
|
||||
}
|
||||
}
|
||||
-(void)miniRoomWithRoomId:(NSString*)roomId roomCover:(NSString*)roomCover{
|
||||
self.miniView.roomId = self.roomId;
|
||||
self.miniView.roomCoverImage = roomCover;
|
||||
[self.miniView show];
|
||||
}
|
||||
|
||||
-(QXMiniRoomView *)miniView{
|
||||
if (!_miniView) {
|
||||
_miniView = [[QXMiniRoomView alloc] init];
|
||||
}
|
||||
return _miniView;
|
||||
}
|
||||
|
||||
-(void)vibrationFeedback{
|
||||
UIImpactFeedbackGenerator *generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleHeavy];
|
||||
[generator impactOccurred];
|
||||
}
|
||||
@end
|
||||
38
QXLive/Base/QXLocationManager.h
Normal file
38
QXLive/Base/QXLocationManager.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// QXLocationManager.h
|
||||
// YSDTrucksProject
|
||||
//
|
||||
// Created by 党凯 on 2020/7/17.
|
||||
// Copyright © 2020 党凯. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol QXLocationManagerDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
-(void)locationSuccessWithCity:(NSString*_Nonnull)city province:(NSString*_Nonnull)province area:(NSString*_Nonnull)area address:(NSString*_Nonnull)address;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface QXLocationManager : NSObject
|
||||
@property (nonatomic,weak)id<QXLocationManagerDelegate>delegate;
|
||||
|
||||
+(instancetype)shareManager;
|
||||
|
||||
/**
|
||||
开始定位
|
||||
*/
|
||||
-(void)startLoction;
|
||||
|
||||
|
||||
/**
|
||||
结束定位
|
||||
*/
|
||||
-(void)stopLoction;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
155
QXLive/Base/QXLocationManager.m
Normal file
155
QXLive/Base/QXLocationManager.m
Normal file
@@ -0,0 +1,155 @@
|
||||
//
|
||||
// QXLocationManager.m
|
||||
// YSDTrucksProject
|
||||
//
|
||||
// Created by 党凯 on 2020/7/17.
|
||||
// Copyright © 2020 党凯. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QXLocationManager.h"
|
||||
|
||||
|
||||
@interface QXLocationManager()<CLLocationManagerDelegate>
|
||||
@property (nonatomic,strong)CLLocationManager *lcManager;
|
||||
@end
|
||||
@implementation QXLocationManager
|
||||
+(instancetype)shareManager{
|
||||
static QXLocationManager *manager = nil;
|
||||
static dispatch_once_t predicate;
|
||||
dispatch_once(&predicate, ^{
|
||||
manager = [[QXLocationManager alloc] init];
|
||||
});
|
||||
return manager;
|
||||
}
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
// [AMapServices sharedServices].apiKey = mapKey;
|
||||
// _locationManager = [[AMapLocationManager alloc] init];
|
||||
// // 带逆地理信息的一次定位(返回坐标和地址信息)
|
||||
// [_locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
|
||||
// // 定位超时时间,最低2s,此处设置为2s
|
||||
// _locationManager.locationTimeout =2;
|
||||
// // 逆地理请求超时时间,最低2s,此处设置为2s
|
||||
// _locationManager.reGeocodeTimeout = 2;
|
||||
// _locationManager.delegate = self;
|
||||
// if ([CLLocationManager authorizationStatus]) {
|
||||
|
||||
// 创建位置管理者对象
|
||||
|
||||
self.lcManager = [[CLLocationManager alloc] init];
|
||||
|
||||
self.lcManager.delegate = self; // 设置代理
|
||||
|
||||
// 设置定位距离过滤参数 (当本次定位和上次定位之间的距离大于或等于这个值时,调用代理方法)
|
||||
|
||||
self.lcManager.distanceFilter = 100;
|
||||
|
||||
self.lcManager.desiredAccuracy = kCLLocationAccuracyBest; // 设置定位精度(精度越高越耗电)
|
||||
|
||||
[self.lcManager requestWhenInUseAuthorization];//这句很关键!!!
|
||||
|
||||
// [self.lcManager startUpdatingLocation]; // 开始更新位置
|
||||
|
||||
// }else{
|
||||
//
|
||||
// //没开启,做其他提醒
|
||||
//
|
||||
// }
|
||||
}
|
||||
return self;
|
||||
}
|
||||
//-(void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager *)locationManager{
|
||||
// if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
|
||||
// [locationManager requestAlwaysAuthorization];
|
||||
// }
|
||||
//}
|
||||
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
|
||||
NSLog(@"定位到了");
|
||||
|
||||
__weak typeof(self)weakSelf = self;
|
||||
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
|
||||
[geocoder reverseGeocodeLocation:[locations firstObject] completionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks, NSError * _Nullable error) {
|
||||
|
||||
CLPlacemark *place = [placemarks firstObject];
|
||||
//place包含了地理信息
|
||||
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(locationSuccessWithCity:province:area:address:)]) {
|
||||
/// 省
|
||||
NSString *province = place.administrativeArea;
|
||||
/// 市
|
||||
NSString *city = place.locality;
|
||||
/// 县
|
||||
NSString *area = place.subLocality;
|
||||
[weakSelf.delegate locationSuccessWithCity:place.locality province:province area:area address:place.name];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
|
||||
NSLog(@"获取定位失败");
|
||||
}
|
||||
|
||||
-(void)startLoction{
|
||||
if (![self checkAuthorization]) {
|
||||
UIAlertController *al = [UIAlertController alertControllerWithTitle:@"您没有打开定位权限" message:nil preferredStyle:(UIAlertControllerStyleAlert)];
|
||||
[al addAction:[UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:^(UIAlertAction * _Nonnull action) {
|
||||
|
||||
}]];
|
||||
[al addAction:[UIAlertAction actionWithTitle:@"去设置" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
|
||||
//打开应用的设置界面
|
||||
NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
|
||||
if([[UIApplication sharedApplication] canOpenURL:url]) {
|
||||
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
|
||||
}
|
||||
}]];
|
||||
[KEYWINDOW.rootViewController presentViewController:al animated:YES completion:nil];
|
||||
// [self.locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
|
||||
// resultBlock(location,regeocode,error);
|
||||
// }];
|
||||
[self.lcManager startUpdatingLocation];
|
||||
}else{
|
||||
// [self.locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
|
||||
// resultBlock(location,regeocode,error);
|
||||
// }];
|
||||
[self.lcManager startUpdatingLocation];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void)stopLoction{
|
||||
[self.lcManager stopUpdatingLocation];
|
||||
}
|
||||
//检查定位权限
|
||||
-(BOOL)checkAuthorization{
|
||||
BOOL result = NO;
|
||||
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
|
||||
switch (status) {
|
||||
//用户在设置中关闭定位功能,或者用户明确的在弹框之后选择禁止定位
|
||||
case kCLAuthorizationStatusDenied:
|
||||
result = NO;
|
||||
break;
|
||||
//用户没有选择是否要使用定位服务(弹框没选择,或者根本没有弹框)注:高德会自动请求权限
|
||||
case kCLAuthorizationStatusNotDetermined:
|
||||
result = YES;
|
||||
break;
|
||||
//定位服务授权状态受限制,可能由于活动限制了定位服务,并且用户不能改变当前的权限,这个状态有可能不是用户拒绝的,但是也有可能是用户拒绝的。
|
||||
case kCLAuthorizationStatusRestricted:
|
||||
result = NO;
|
||||
break;
|
||||
//App始终允许使用定位功能
|
||||
case kCLAuthorizationStatusAuthorizedAlways:
|
||||
result = YES;
|
||||
break;
|
||||
//用户在使用期间允许使用定位功能
|
||||
case kCLAuthorizationStatusAuthorizedWhenInUse:
|
||||
result = YES;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
17
QXLive/Base/WKWebView+QX.h
Normal file
17
QXLive/Base/WKWebView+QX.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// WKWebView+QX.h
|
||||
// YBLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/16.
|
||||
// Copyright © 2025 cat. All rights reserved.
|
||||
//
|
||||
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface WKWebView (QX)
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
50
QXLive/Base/WKWebView+QX.m
Normal file
50
QXLive/Base/WKWebView+QX.m
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// WKWebView+QX.m
|
||||
// YBLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/16.
|
||||
// Copyright © 2025 cat. All rights reserved.
|
||||
//
|
||||
|
||||
#import "WKWebView+QX.h"
|
||||
|
||||
@implementation WKWebView (QX)
|
||||
+ (void)load{
|
||||
Method method1 = class_getInstanceMethod([self class],@selector(loadRequest:));
|
||||
Method method2 = class_getInstanceMethod([self class],@selector(qx_loadRequest:));
|
||||
method_exchangeImplementations(method1, method2);
|
||||
|
||||
}
|
||||
-(void)qx_loadRequest:(NSURLRequest*)request{
|
||||
if ([self isProxyEnabled]) {
|
||||
[self qx_loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https:www.baidu.com"]]];
|
||||
}else{
|
||||
[self qx_loadRequest:request];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-(BOOL)isProxyEnabled{
|
||||
NSArray *criticalDomains = @[
|
||||
H5ServerUrl,
|
||||
ServerUrl,
|
||||
];
|
||||
NSDictionary *proxySettings = (__bridge NSDictionary *)CFNetworkCopySystemProxySettings();
|
||||
for (NSString *domain in criticalDomains) {
|
||||
NSArray *proxies = (__bridge NSArray *)CFNetworkCopyProxiesForURL(
|
||||
(__bridge CFURLRef)[NSURL URLWithString:domain],
|
||||
(__bridge CFDictionaryRef)proxySettings
|
||||
);
|
||||
// 检查每个域名的代理情况...
|
||||
for (NSDictionary *proxy in proxies) {
|
||||
NSString *proxyType = proxy[(NSString *)kCFProxyTypeKey];
|
||||
if (![proxyType isEqualToString:(NSString *)kCFProxyTypeNone]) {
|
||||
return YES; // 存在代理或 VPN
|
||||
}
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
@end
|
||||
Reference in New Issue
Block a user