Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfce0d5885 | ||
|
|
5b719599ba | ||
|
|
ee47bba29a | ||
|
|
a6a0f0a4ce | ||
|
|
8a8a914a8c | ||
|
|
ee498064cc | ||
|
|
6337454956 | ||
|
|
2c2f307247 | ||
|
|
6f9f903ca1 | ||
|
|
1bfe617cab | ||
|
|
a47d1a56fa | ||
|
|
d0ff8c2c19 | ||
|
|
b69578aa4a | ||
|
|
c7925e3189 | ||
|
|
82a432f77a | ||
|
|
c5b5149bb1 | ||
|
|
823063653b | ||
|
|
aa34d4623e | ||
|
|
3c241b193b | ||
|
|
a7d78ef4d8 | ||
|
|
57643da94d | ||
|
|
4aba54ce74 | ||
|
|
2ec6c65bef | ||
|
|
8f7d08f1e1 | ||
|
|
2d2396bd53 | ||
|
|
b2d90a7c81 | ||
|
|
0ffc7ba2b2 | ||
|
|
4eec6512e7 | ||
|
|
cc4663206b |
@@ -0,0 +1,196 @@
|
||||
# Agent 行为准则 & XinjiangProject iOS 开发规范
|
||||
|
||||
---
|
||||
|
||||
## 一、Agent 行为准则
|
||||
|
||||
### 0. 语言强制
|
||||
- 强制使用简体中文进行所有交互(代码除外)。
|
||||
|
||||
### 1. 抽象设计确认
|
||||
- 涉及抽象设计、架构调整或新功能模块时,必须先用文字或 Mermaid 图对齐设计思路。
|
||||
- 必须等待用户确认方案后,才能开始编写代码。
|
||||
|
||||
### 2. 任务清单确认
|
||||
- 执行任何实质性任务前,必须先列出详细的任务清单。
|
||||
- 必须等待用户明确回复(如"好的"、"开始")后,才能进入执行阶段。
|
||||
|
||||
### 3. 分步执行与确认
|
||||
- 代码量较大或逻辑复杂的任务,禁止一次性完成。
|
||||
- 拆分为多个步骤,每步完成后汇报进度并询问"是否可以进行下一步?"。
|
||||
|
||||
### 4. 所有修改必须确认
|
||||
- 对代码库的任何修改(新建文件、修改文件、删除文件、执行 pod install 等)前,必须先描述变更内容。
|
||||
- 必须等待用户明确回复"确认"或"同意"后,才能执行。
|
||||
|
||||
### 9. 代码注释语言规范
|
||||
- 所有注释使用简体中文。
|
||||
- 标识符(变量名、函数名、类名)仍使用英文。
|
||||
|
||||
---
|
||||
|
||||
## 二、项目技术规范
|
||||
|
||||
### 技术栈
|
||||
- **主语言**: Objective-C
|
||||
- **混编**: 允许 OC/Swift 混编,OC 为主。引入 Swift 文件前**必须征得用户确认**。
|
||||
- **UI 框架**: UIKit
|
||||
- **架构模式**: MVC + Manager 层
|
||||
- **包管理**: CocoaPods,使用 `.xcworkspace` 打开项目
|
||||
- **最低系统版本**: iOS 12.0
|
||||
|
||||
---
|
||||
|
||||
### 项目目录结构
|
||||
|
||||
```
|
||||
XinjiangProject/
|
||||
├── Project/ # 业务模块(按功能划分)
|
||||
│ ├── Base/ # 基类 ViewController
|
||||
│ ├── AppDelegate/
|
||||
│ ├── Login_Register/
|
||||
│ ├── HomeV2/
|
||||
│ ├── Homepage/
|
||||
│ ├── Monitoring/
|
||||
│ ├── MainCenter/
|
||||
│ ├── BANK/
|
||||
│ ├── SOS/
|
||||
│ ├── Qusetion/
|
||||
│ ├── TUIChat/
|
||||
│ ├── CustomTUIChat/
|
||||
│ └── simulationUser(模拟用户)/
|
||||
├── Manager/ # 业务逻辑管理层
|
||||
│ ├── NetworkHelpManager/ # 网络层(XJPNetAPI、JKCQNetworkingWithCache)
|
||||
│ ├── UserManager/
|
||||
│ ├── AudioManager/
|
||||
│ ├── TUIManager/
|
||||
│ └── RuntimeManager/
|
||||
├── Categorys/ # UIKit 分类扩展
|
||||
├── Utils/ # 工具类
|
||||
├── Define/ # 宏定义(颜色、字体、接口地址、Key)
|
||||
└── ThirdParty/ # 本地化第三方库
|
||||
```
|
||||
|
||||
新增模块按以下结构组织:
|
||||
```
|
||||
Project/ModuleName/
|
||||
├── Controller/
|
||||
├── View/
|
||||
└── Model/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 命名规范
|
||||
|
||||
**类名(PascalCase):**
|
||||
- 新建类统一使用前缀 `XJ`,如 `XJOrderViewController`、`XJUserModel`
|
||||
- 历史遗留 `HQ` 前缀类(如 `HQUserInfo`)维护时保持原前缀,不得重命名
|
||||
- 分类命名:`ClassName+ExtensionName`,如 `UIView+Extension`
|
||||
|
||||
**方法名(camelCase):**
|
||||
```objc
|
||||
- (void)setupNavigationBar;
|
||||
- (void)loadUserDataWithType:(NSInteger)type;
|
||||
```
|
||||
|
||||
**属性修饰符规范:**
|
||||
```objc
|
||||
@property (nonatomic, strong) UIView *containerView; // 对象用 strong
|
||||
@property (nonatomic, copy) NSString *userName; // 字符串/Block 用 copy
|
||||
@property (nonatomic, assign) NSInteger pageIndex; // 基本类型用 assign
|
||||
@property (nonatomic, weak) id<Protocol> delegate; // 代理用 weak
|
||||
```
|
||||
|
||||
**宏常量:**
|
||||
```objc
|
||||
#define kNavBgColor [UIColor colorWithHexString:@"#00AE68"] // 颜色用 k 前缀
|
||||
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width // 系统级用大写
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 代码组织(#pragma mark)
|
||||
|
||||
```objc
|
||||
#pragma mark - ————— Life Cycle —————
|
||||
|
||||
#pragma mark - ————— Setter / Getter —————
|
||||
|
||||
#pragma mark - ————— Private Methods —————
|
||||
|
||||
#pragma mark - ————— Network —————
|
||||
|
||||
#pragma mark - ————— UITableViewDataSource —————
|
||||
|
||||
#pragma mark - ————— UITableViewDelegate —————
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 内存管理
|
||||
|
||||
Block 内防循环引用,使用项目全局 `kWeakSelf` 宏:
|
||||
|
||||
```objc
|
||||
kWeakSelf(self);
|
||||
[self.manager doSomethingWithCompletion:^{
|
||||
[weakself updateUI];
|
||||
}];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### UI 布局
|
||||
|
||||
frame 与 Masonry 均可使用,根据实际场景判断,不强制统一。
|
||||
|
||||
屏幕适配使用项目已定义宏(基于 375pt 基准):
|
||||
```objc
|
||||
kRealValue(x) // 尺寸等比缩放
|
||||
kFontSize(x) // 字体等比缩放
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 网络层规范
|
||||
|
||||
项目网络层使用 `XJPNetAPI` + `JKCQNetworkingWithCache`,
|
||||
回调通过 `performSelector` 动态分发,**遵循以下固定签名**:
|
||||
|
||||
**发起请求:**
|
||||
```objc
|
||||
// init:tag:NeedToken: 初始化,self 作为代理,tag 区分同一 VC 内的不同请求
|
||||
XJPNetAPI *api = [[XJPNetAPI alloc] init:self tag:@"USERINFO" NeedToken:token];
|
||||
[api getUserInfo:paramDic];
|
||||
```
|
||||
|
||||
**实现回调(固定方法签名,不得修改):**
|
||||
```objc
|
||||
// 请求成功
|
||||
- (void)Sucess:(id)response tag:(NSString *)tag {
|
||||
if ([tag isEqualToString:@"USERINFO"]) {
|
||||
// 处理用户信息数据
|
||||
}
|
||||
}
|
||||
|
||||
// 请求失败
|
||||
- (void)Failed:(NSString *)message tag:(NSString *)tag {
|
||||
[self showMBProgressHUDOnlyWithString:message];
|
||||
}
|
||||
```
|
||||
|
||||
**注意事项:**
|
||||
- `Sucess` 为项目约定拼写(非笔误),禁止修改方法名
|
||||
- 同一 VC 内多个请求通过 `tag` 字符串区分,在回调中用 `if/else` 分支处理
|
||||
- API 地址统一定义在 `StatusMacros.h`,禁止在业务代码中硬编码 URL
|
||||
|
||||
---
|
||||
|
||||
### 禁止事项
|
||||
|
||||
- 禁止将 API Key、SDKAPPID 等敏感信息硬编码在业务文件中(统一放 `ThirdMacros.h`)
|
||||
- 禁止在主线程执行网络请求、数据库读写、文件 IO 等耗时操作
|
||||
- 禁止在 Category 中声明存储属性(需用 `objc_setAssociatedObject`)
|
||||
- 禁止修改 `Sucess:tag:` / `Failed:tag:` 的方法签名
|
||||
- 禁止未经确认自行封装或绕过 `XJPNetAPI` 发起网络请求
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
platform :ios, '12.0'
|
||||
platform :ios, '15.0'
|
||||
# 忽略引入库的所有警告
|
||||
inhibit_all_warnings!
|
||||
|
||||
|
||||
@@ -511,6 +511,6 @@ SPEC CHECKSUMS:
|
||||
YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7
|
||||
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
|
||||
|
||||
PODFILE CHECKSUM: c63ef0a5edf68dd395621c435af5c0063b38442a
|
||||
PODFILE CHECKSUM: 9ebe0e8991fab6e5cf3d18a72b82760099c4bc48
|
||||
|
||||
COCOAPODS: 1.16.2
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
188C3FFF3005E07600461C07 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 188C3FFE3005E07600461C07 /* Security.framework */; };
|
||||
188C40013005E08000461C07 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 188C40003005E08000461C07 /* CoreTelephony.framework */; };
|
||||
2A9D6F4901C83B23A09A207B /* libPods-XinjiangProject.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5380821CF956D8001EF91CA7 /* libPods-XinjiangProject.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -31,6 +33,10 @@
|
||||
1809E4622E092C710034C8FC /* XinjiangProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XinjiangProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1809E47D2E092C740034C8FC /* XinjiangProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XinjiangProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1809E4872E092C740034C8FC /* XinjiangProjectUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XinjiangProjectUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
188C3FFE3005E07600461C07 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
188C40003005E08000461C07 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; };
|
||||
188C40023005E08B00461C07 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||
188C40033005E09100461C07 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
|
||||
5380821CF956D8001EF91CA7 /* libPods-XinjiangProject.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-XinjiangProject.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D5F062871D7E5499A760A0A9 /* Pods-XinjiangProject.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XinjiangProject.release.xcconfig"; path = "Target Support Files/Pods-XinjiangProject/Pods-XinjiangProject.release.xcconfig"; sourceTree = "<group>"; };
|
||||
F4F935FBD1765B37B37D212D /* Pods-XinjiangProject.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XinjiangProject.debug.xcconfig"; path = "Target Support Files/Pods-XinjiangProject/Pods-XinjiangProject.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
@@ -72,6 +78,8 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
188C40013005E08000461C07 /* CoreTelephony.framework in Frameworks */,
|
||||
188C3FFF3005E07600461C07 /* Security.framework in Frameworks */,
|
||||
2A9D6F4901C83B23A09A207B /* libPods-XinjiangProject.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -118,6 +126,10 @@
|
||||
5E0194FB12246C95B3FA5215 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
188C40033005E09100461C07 /* libc++.tbd */,
|
||||
188C40023005E08B00461C07 /* libz.tbd */,
|
||||
188C40003005E08000461C07 /* CoreTelephony.framework */,
|
||||
188C3FFE3005E07600461C07 /* Security.framework */,
|
||||
5380821CF956D8001EF91CA7 /* libPods-XinjiangProject.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
@@ -207,7 +219,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastUpgradeCheck = 1630;
|
||||
LastUpgradeCheck = 2630;
|
||||
TargetAttributes = {
|
||||
1809E4612E092C710034C8FC = {
|
||||
CreatedOnToolsVersion = 16.3;
|
||||
@@ -374,33 +386,35 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = XinjiangProject/XinjiangProject.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = A7CC5LW224;
|
||||
ENABLE_MODULE_VERIFIER = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GCC_PREFIX_HEADER = "$(SRCROOT)/XinjiangProject/Supporting Files/PrefixHeader.pch";
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/XinjiangProject/Supporting Files/Info.plist";
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "新疆亚克西";
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "健康油我";
|
||||
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "健康咨询员工端需要访问您的相机用来档案功能,是否同意?";
|
||||
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "APP需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSLocationAlwaysUsageDescription = "APP需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "APP需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "健康咨询员工端需要访问您的麦克风用来视频录制,是否同意?";
|
||||
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "新疆员工端需要访问您的相册上传图片,方便您的使用,是否同意?";
|
||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "健康咨询想使用您的相册功能 是否同意?";
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "健康油我需要访问您的相机用来档案功能,是否同意?";
|
||||
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "健康油我需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSLocationAlwaysUsageDescription = "健康油我需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "健康油我需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "健康油我需要访问您的麦克风用来视频录制,是否同意?";
|
||||
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "健康油我需要访问您的相册上传图片,方便您的使用,是否同意?";
|
||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "健康油我想使用您的相册功能 是否同意?";
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||
INFOPLIST_KEY_UIUserInterfaceStyle = Light;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
MARKETING_VERSION = 1.0.14;
|
||||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.questionTools.XinjiangProject;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
@@ -418,33 +432,35 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = XinjiangProject/XinjiangProject.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = A7CC5LW224;
|
||||
ENABLE_MODULE_VERIFIER = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GCC_PREFIX_HEADER = "$(SRCROOT)/XinjiangProject/Supporting Files/PrefixHeader.pch";
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/XinjiangProject/Supporting Files/Info.plist";
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "新疆亚克西";
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "健康油我";
|
||||
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "健康咨询员工端需要访问您的相机用来档案功能,是否同意?";
|
||||
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "APP需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSLocationAlwaysUsageDescription = "APP需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "APP需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "健康咨询员工端需要访问您的麦克风用来视频录制,是否同意?";
|
||||
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "新疆员工端需要访问您的相册上传图片,方便您的使用,是否同意?";
|
||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "健康咨询想使用您的相册功能 是否同意?";
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "健康油我需要访问您的相机用来档案功能,是否同意?";
|
||||
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "健康油我需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSLocationAlwaysUsageDescription = "健康油我需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "健康油我需要您的定位服务,否则可能无法使用。";
|
||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "健康油我需要访问您的麦克风用来视频录制,是否同意?";
|
||||
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "健康油我需要访问您的相册上传图片,方便您的使用,是否同意?";
|
||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "健康油我想使用您的相册功能 是否同意?";
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||
INFOPLIST_KEY_UIUserInterfaceStyle = Light;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
MARKETING_VERSION = 1.0.14;
|
||||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.questionTools.XinjiangProject;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
@@ -509,12 +525,13 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 18.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -565,11 +582,12 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 18.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "2630"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1809E4612E092C710034C8FC"
|
||||
BuildableName = "XinjiangProject.app"
|
||||
BlueprintName = "XinjiangProject"
|
||||
ReferencedContainer = "container:XinjiangProject.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1809E47C2E092C740034C8FC"
|
||||
BuildableName = "XinjiangProjectTests.xctest"
|
||||
BlueprintName = "XinjiangProjectTests"
|
||||
ReferencedContainer = "container:XinjiangProject.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1809E4862E092C740034C8FC"
|
||||
BuildableName = "XinjiangProjectUITests.xctest"
|
||||
BlueprintName = "XinjiangProjectUITests"
|
||||
ReferencedContainer = "container:XinjiangProject.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1809E4612E092C710034C8FC"
|
||||
BuildableName = "XinjiangProject.app"
|
||||
BlueprintName = "XinjiangProject"
|
||||
ReferencedContainer = "container:XinjiangProject.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "1809E4612E092C710034C8FC"
|
||||
BuildableName = "XinjiangProject.app"
|
||||
BlueprintName = "XinjiangProject"
|
||||
ReferencedContainer = "container:XinjiangProject.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// NSArray+Sudoku.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/3/4.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// NSArray+Sudoku.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/3/4.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// NSAttributedString+Extension.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by 仁康信息 on 2023/3/14.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// NSAttributedString+Extension.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by 仁康信息 on 2023/3/14.
|
||||
//
|
||||
|
||||
@@ -91,7 +91,7 @@ static char edgeKey;
|
||||
break;
|
||||
|
||||
case DIYStyleImgBottom:
|
||||
NSLog(@"%f",titleX);
|
||||
DLog(@"%f",titleX);
|
||||
self.titleEdgeInsets = UIEdgeInsetsMake(((selfH - totalH)/2.0 - titleY),
|
||||
-(titleX + titleW/2.0 - selfW/2.0),
|
||||
-((selfH - totalH)/2.0 - titleY),
|
||||
@@ -156,7 +156,7 @@ static char edgeKey;
|
||||
break;
|
||||
|
||||
case DIYStyleImgBottom:
|
||||
NSLog(@"%f",titleX);
|
||||
DLog(@"%f",titleX);
|
||||
self.titleEdgeInsets = UIEdgeInsetsMake(((selfH - totalH)/2.0 - titleY),
|
||||
-(titleX + titleW/2.0 - selfW/2.0),
|
||||
-((selfH - totalH)/2.0 - titleY),
|
||||
@@ -220,7 +220,7 @@ static char edgeKey;
|
||||
break;
|
||||
|
||||
case DIYStyleImgBottom:
|
||||
NSLog(@"%f",titleX);
|
||||
DLog(@"%f",titleX);
|
||||
self.titleEdgeInsets = UIEdgeInsetsMake(((selfH - totalH)/2.0 - titleY),
|
||||
-(titleX + titleW/2.0 - selfW/2.0),
|
||||
-((selfH - totalH)/2.0 - titleY),
|
||||
@@ -288,7 +288,7 @@ static char edgeKey;
|
||||
break;
|
||||
|
||||
case DIYStyleImgBottom:
|
||||
NSLog(@"%f",titleX);
|
||||
DLog(@"%f",titleX);
|
||||
self.titleEdgeInsets = UIEdgeInsetsMake(((selfH - totalH)/2.0 - titleY),
|
||||
-(titleX + titleW/2.0 - selfW/2.0),
|
||||
-((selfH - totalH)/2.0 - titleY),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// UIDevice+model.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/3/29.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// UIDevice+model.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/3/29.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// UIImage+RoundedCorner.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/4/24.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// UIImage+RoundedCorner.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/4/24.
|
||||
//
|
||||
|
||||
@@ -15,13 +15,11 @@
|
||||
#define KNotificationLoginIMResult @"loginIMResult"
|
||||
|
||||
//切换tabar
|
||||
#define KNotificSelectHomePageTabbar @"SlectHomePageTabBar"
|
||||
|
||||
#define KNotificSelectSoSTabbar @"SlectSoSTabBar"
|
||||
#define KNotificSelectQuestionTabbar @"SlectQuestionTabBar"
|
||||
#define KNotificSelectSOSCenterTabbar @"SlectSoSTabBar"
|
||||
#define KNotificSelectWatchTabbar @"SlectMonitoringTabBar"
|
||||
|
||||
#define KNotificSelectPhysicalTabbar @"SlectPhysicalTabBar"
|
||||
|
||||
#define KNotificSelectFileTabbar @"SlectFileTabBar"
|
||||
|
||||
//同意协议
|
||||
|
||||
@@ -63,31 +61,52 @@
|
||||
#pragma mark: 网络前缀
|
||||
#define ResourceAddress [NSString stringWithFormat:@"%@/file/show/",Http]
|
||||
|
||||
//生产环境
|
||||
//#define Http @"https://api.cqygjk.com"//
|
||||
//#define H5Http @"https://console.cqygjk.com/"///
|
||||
//#define H5DevHost @"cqyt.out.yg.icdat.cn"//
|
||||
//#define IntervenH5 @"https://console.cqygjk.com"
|
||||
|
||||
//#define Http UserDefaultObjectForKey(@"HTTPS")//
|
||||
//#define H5DevHost UserDefaultObjectForKey(@"H5DevHost")//
|
||||
//#define IntervenH5 UserDefaultObjectForKey(@"IntervenH5")
|
||||
//正式地址
|
||||
//#define Http @"https://api-jkglpt.iosp.ydpt.tech"//
|
||||
//#define H5DevHost @"api-jkglpt.iosp.ydpt.tech"//
|
||||
//#define IntervenH5 @"https://console-jkglpt.iosp.ydpt.tech"
|
||||
//#define SCHEME @"https" //
|
||||
//#define OtherHttp @"https://api-jkglpt.iosp.ydpt.tech/hb" //
|
||||
|
||||
//测试环境地址
|
||||
//四合一
|
||||
//正文斌 @"http://192.168.1.28"。青海项目:https://quarry-api.yg.icdat.cn 四合一://https://starry.test.icdat.cn
|
||||
|
||||
//#define Http @"https://starry.test.icdat.cn"
|
||||
//#define H5DevHost @"starry.test.icdat.cn"//
|
||||
//#define IntervenH5 @"https://starry.out.icdat.cn"
|
||||
|
||||
//开发环境地址
|
||||
#define Http @"http://cqyt.dev.yg.dt.io"//
|
||||
#define H5DevHost @"cqyt.dev.yg.dt.io"//
|
||||
#define IntervenH5 @"http://cms.dev.yg.dt.io"
|
||||
#define BASEURL @"https://yyjk.cqygjk.com" //北边接口前缀
|
||||
#define SCHEME @"http" //
|
||||
//最新新疆测试地址
|
||||
//#define Http @"http://192.168.1.223"//彭杰
|
||||
// 最新地址
|
||||
//#define Http @"http://192.168.1.47"//王昊
|
||||
#define Http @"https://xj-api.yixiong-tech.com:8081"//
|
||||
#define H5DevHost @"xjxc-api.mcrm.vip:8888"//
|
||||
#define IntervenH5 @"http://10.10.10.228:23006/"
|
||||
#define SCHEME @"https" //
|
||||
#define OtherHttp @"https://gstest.superwx.cn/xj_health" //
|
||||
|
||||
|
||||
#pragma mark - ——————— 健康知识/资讯 ————————
|
||||
|
||||
// H5 页面地址
|
||||
#define kHealthKnowMoreH5 @"/healthnewsweb/healthKnow.html"
|
||||
#define kHealthNewsMoreH5 @"/healthnewsweb/healthNews.html"
|
||||
#define kHealthDetailH5 @"/healthnewsweb/healthNewsDetail.html"
|
||||
#define kHealthSearchH5 @"/healthnewsweb/healthSecrch.html"
|
||||
|
||||
// HMAC-SHA256 签名密钥
|
||||
#define kHealthKnowledgeSecretKey @"XJp3EHpcnwReXc1A"
|
||||
|
||||
//测试 健康知识+资讯
|
||||
//#define kHealthKnowledgeBaseURL @"https://gstest.superwx.cn/healthcheck"
|
||||
//#define kHealthKnowledgeH5Host @"https://gstest.superwx.cn"
|
||||
//正式 健康知识+资讯
|
||||
#define kHealthKnowledgeBaseURL @"https://api-jkglpt.iosp.ydpt.tech/hb"
|
||||
#define kHealthKnowledgeH5Host @"https://console-jkglpt.iosp.ydpt.tech/hb"
|
||||
|
||||
// API 路径
|
||||
#define kHealthKnowledgeTokenPath @"/pe/frontend/init"
|
||||
#define kHealthKnowledgeCategoryPath @"/cms/frontend/category/list"
|
||||
#define kHealthKnowledgeArticleListPath @"/cms/frontend/articleList"
|
||||
|
||||
// 急救宣教资源
|
||||
#define kFirstAidResourceDetailPath @"/health-emergency/api/emergency/firstAid/resource/resource/queryById"
|
||||
|
||||
|
||||
#endif /* StatusMacros_h */
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
#define ThirdMacros_h
|
||||
|
||||
//微信
|
||||
#define kAppKey_Wechat @""
|
||||
#define kAppKey_Wechat @"wxb33cd60beda0a212"
|
||||
|
||||
#define kSecret_Wechat @""
|
||||
#define kSecret_Wechat @"9de1222d6c32af184538d2ae25d1f5a2"
|
||||
|
||||
#define kUniversalLink_Wechat @"https://www.rk-health.com"
|
||||
|
||||
#define UMShareAppKey @""
|
||||
|
||||
@@ -22,10 +24,11 @@
|
||||
|
||||
#define buglyAppid @""
|
||||
|
||||
#define SecretKey @"XJp3EHpcnwReXc1A"
|
||||
|
||||
|
||||
//高德key
|
||||
#define AMAPSDKKEY @"e5e5b1aa469fcf577c829165bae860dd"
|
||||
#define AMAPSDKKEY @"43f28dcc5782a0aa98169624f6e94b76"
|
||||
|
||||
#define KNotificAgreeProtoocl @"AGREEPMAP"
|
||||
|
||||
|
||||
@@ -184,10 +184,12 @@ alpha:1.0])
|
||||
|
||||
//数据验证
|
||||
#define StrValid(f) ([f isKindOfClass:[NSNull class]] || f == nil || [f length] < 1 || [f isEqualToString:@"(null)"] || [f isEqualToString:@"<null>"] || [f isEqualToString:@"null"]? YES : NO)
|
||||
#define SafeStr(f) (StrValid(f) ? f:@"")
|
||||
#define HasString(str,key) ([str rangeOfString:key].location!=NSNotFound)
|
||||
|
||||
#define ValidStr(f) StrValid(f)
|
||||
|
||||
#define SafeStr(f) (!StrValid(f) ? f:@"-")
|
||||
#define HasString(str,key) ([str rangeOfString:key].location!=NSNotFound)
|
||||
|
||||
#define ValidDict(f) (f!=nil && [f isKindOfClass:[NSDictionary class]])
|
||||
#define ValidArray(f) (f!=nil && [f isKindOfClass:[NSArray class]] && [f count]>0)
|
||||
#define ValidNum(f) (f!=nil && [f isKindOfClass:[NSNumber class]])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CQAudioPlayManager.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by 仁康信息 on 2023/12/5.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CQAudioPlayManager.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by 仁康信息 on 2023/12/5.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DownToolsManager.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by 仁康信息 on 2023/12/1.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DownToolsManager.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by 仁康信息 on 2023/12/1.
|
||||
//
|
||||
@@ -26,7 +26,7 @@
|
||||
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
|
||||
//下载进度
|
||||
progress ? progress(downloadProgress) : nil;
|
||||
NSLog(@"下载进度:%.2f%%",100.0*downloadProgress.completedUnitCount/downloadProgress.totalUnitCount);
|
||||
DLog(@"下载进度:%.2f%%",100.0*downloadProgress.completedUnitCount/downloadProgress.totalUnitCount);
|
||||
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
|
||||
|
||||
//拼接缓存目录
|
||||
@@ -35,11 +35,11 @@
|
||||
//拼接文件路径
|
||||
NSString *filePath = [downloadStr stringByAppendingPathComponent:fileDir];
|
||||
|
||||
NSLog(@"downloadStr = %@",downloadStr);
|
||||
DLog(@"downloadStr = %@",downloadStr);
|
||||
return [NSURL fileURLWithPath:filePath];
|
||||
|
||||
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
|
||||
NSLog(@"%@---%@", filePath, filePath.absoluteString);
|
||||
DLog(@"%@---%@", filePath, filePath.absoluteString);
|
||||
success ? success(filePath.absoluteString /** NSURL->NSString*/) : nil;
|
||||
failure && error ? failure(error) : nil;
|
||||
}];
|
||||
@@ -57,7 +57,7 @@
|
||||
//获取路径
|
||||
NSString *documentsPath = [ReaderDocument documentsPath];
|
||||
//可根据路径command + shift + G查看该路径下的所有的pdf文件
|
||||
NSLog(@"%@", documentsPath);
|
||||
DLog(@"%@", documentsPath);
|
||||
NSString *filePath = [documentsPath stringByAppendingPathComponent:fileName];
|
||||
ReaderDocument *document = [ReaderDocument withDocumentFilePath:filePath password:nil];
|
||||
if (document != nil)
|
||||
@@ -72,7 +72,7 @@
|
||||
[self downloadWithURL:url fileDir:fileName progress:^(NSProgress *progress) {
|
||||
|
||||
} success:^(NSString *filePath) {
|
||||
NSLog(@"%@", filePath);
|
||||
DLog(@"%@", filePath);
|
||||
//下载完成直接打开
|
||||
[self downLoadPdfFileByUrl:url fileName:fileName];
|
||||
} failure:^(NSError *error) {
|
||||
@@ -93,7 +93,7 @@
|
||||
NSString *filePath = [path stringByAppendingPathComponent:fileName];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
BOOL result = [fileManager fileExistsAtPath:filePath];
|
||||
NSLog(@"这个文件已经存在:%@",result?@"是的":@"不存在");
|
||||
DLog(@"这个文件已经存在:%@",result?@"是的":@"不存在");
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
@@ -53,4 +53,9 @@ typedef void (^FileDownloadFail)(int code, NSString * desc);
|
||||
#pragma mark - 下载文件方法
|
||||
- (void)downLoadFileWithUrl:(NSString *)urlStr Path:(NSString*)path downloadProgress:(void (^)(NSProgress *downloadProgress))progress SuccessBlock:(FileDownloadSucc)success FileDownloadFail:(FileDownloadFail)failure;
|
||||
|
||||
#pragma mark - 表单带参数
|
||||
- (void)httpPostFormDataRequest:(NSString *)api params:(NSMutableDictionary *)params;
|
||||
|
||||
//外部接口
|
||||
- (void)httpOtherPostRequest:(NSString *)api params:(NSMutableDictionary *)params;
|
||||
@end
|
||||
|
||||
+174
-3
@@ -8,7 +8,7 @@
|
||||
//
|
||||
|
||||
#import "JKCQNetworkingWithCache.h"
|
||||
|
||||
#import <CommonCrypto/CommonHMAC.h>
|
||||
#define DYLog(...) NSLog(__VA_ARGS__) //如果不需要打印数据, 注释掉NSLog
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ typedef NS_ENUM(NSInteger, RequestType) {
|
||||
RequestTypeMultiUpload,//多个上传
|
||||
RequestTypeDownload,
|
||||
RequestTypeUpLoadVideo,//上传视频
|
||||
RequestTypeParmFormData,//参数表单
|
||||
RequestTypeOterTypePost//外部接口
|
||||
};
|
||||
|
||||
@implementation JKCQNetworkingWithCache
|
||||
@@ -63,6 +65,11 @@ typedef NS_ENUM(NSInteger, RequestType) {
|
||||
[self httpRequestWithUrlStr:api params:params requestType:RequestTypePost isCache:YES cacheKey:api imageKey:nil withData:nil withDataArray:nil];
|
||||
}
|
||||
|
||||
- (void)httpOtherPostRequest:(NSString *)api params:(NSMutableDictionary *)params
|
||||
{
|
||||
[self httpRequestWithUrlStr:api params:params requestType:RequestTypeOterTypePost isCache:NO cacheKey:nil imageKey:nil withData:nil withDataArray:nil];
|
||||
}
|
||||
|
||||
#pragma mark - 上传文件方法
|
||||
//上传单张图片
|
||||
- (void)upLoadDataWithUrlStr:(NSString *)api params:(NSMutableDictionary *)params imageKey:(NSString *)name withData:(NSData *)data
|
||||
@@ -115,6 +122,13 @@ typedef NS_ENUM(NSInteger, RequestType) {
|
||||
//5.开始启动下载任务
|
||||
[task resume];
|
||||
}
|
||||
|
||||
#pragma mark:表单上传参数
|
||||
- (void)httpPostFormDataRequest:(NSString *)api params:(NSMutableDictionary *)params {
|
||||
|
||||
|
||||
[self httpRequestWithUrlStr:api params:params requestType:RequestTypeParmFormData isCache:YES cacheKey:api imageKey:nil withData:nil withDataArray:nil];
|
||||
}
|
||||
#pragma mark - 网络请求统一处理
|
||||
/**
|
||||
|
||||
@@ -142,6 +156,15 @@ typedef NS_ENUM(NSInteger, RequestType) {
|
||||
if (![self requestBeforeJudgeConnect]) {//断网
|
||||
[self showError:@"请检查网络设置"];
|
||||
DYLog(@"\n\n----%@------\n\n",@"没有网络");
|
||||
UIWindow *keyWindow = UIApplication.sharedApplication.windows.firstObject;
|
||||
for (UIWindow *window in UIApplication.sharedApplication.windows) {
|
||||
if (window.isKeyWindow) {
|
||||
keyWindow = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[MBProgressHUD hideHUDForView:keyWindow animated:YES];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -188,9 +211,19 @@ typedef NS_ENUM(NSInteger, RequestType) {
|
||||
}else
|
||||
{
|
||||
NSLog(@"%@",url);
|
||||
UIWindow *keyWindow = UIApplication.sharedApplication.windows.firstObject;
|
||||
for (UIWindow *window in UIApplication.sharedApplication.windows) {
|
||||
if (window.isKeyWindow) {
|
||||
keyWindow = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[MBProgressHUD hideHUDForView:keyWindow animated:YES];
|
||||
[self showError:@"网络服务出错"];
|
||||
}
|
||||
|
||||
|
||||
// }
|
||||
|
||||
|
||||
@@ -218,7 +251,19 @@ typedef NS_ENUM(NSInteger, RequestType) {
|
||||
}
|
||||
else
|
||||
{
|
||||
[self showError:@"网络服务出错"];
|
||||
|
||||
NSLog(@"%@",url);
|
||||
[MBProgressHUD hideHUDForView:[HQCommonUtils getCurrentVC].view animated:YES];
|
||||
UIWindow *keyWindow = UIApplication.sharedApplication.windows.firstObject;
|
||||
for (UIWindow *window in UIApplication.sharedApplication.windows) {
|
||||
if (window.isKeyWindow) {
|
||||
keyWindow = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[MBProgressHUD hideHUDForView:keyWindow animated:YES];
|
||||
[EasyTextView showErrorText:@"请求超时"];
|
||||
}
|
||||
|
||||
}];
|
||||
@@ -296,6 +341,99 @@ typedef NS_ENUM(NSInteger, RequestType) {
|
||||
}];
|
||||
|
||||
|
||||
}else if(requestType == RequestTypeParmFormData) {//参数表单上传
|
||||
|
||||
[session.requestSerializer setValue:@"application/x-www-form-urlencoded;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
|
||||
[session POST:url parameters:nil headers:@{@"X-Access-Token":self.needToken} constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
|
||||
|
||||
// 这里我们通过将每一个键值对转换成 multipart 数据块来实现
|
||||
[formData appendPartWithFormData:[params[@"userId"] dataUsingEncoding:NSUTF8StringEncoding] name:@"userId"];
|
||||
|
||||
} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
||||
// 请求成功处理
|
||||
[weakSelf dealWithResponseObject:responseObject cacheUrl:url];
|
||||
|
||||
|
||||
|
||||
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
||||
// 请求失败处理
|
||||
NSString * statusCode = [error.userInfo objectForKey:@"NSLocalizedDescription"];
|
||||
if ([statusCode containsString:@"(401)"]) {
|
||||
DLog(@"%@",error.userInfo);
|
||||
[EasyTextView showErrorText:@"身份验证过期"];
|
||||
[HQCommonUtils keyedArchiverWithData:nil key:LoginUserInfo];
|
||||
KPostNotification(KNotificationLoginStateChange, @NO);
|
||||
}
|
||||
else {
|
||||
[MBProgressHUD hideHUDForView:[HQCommonUtils getCurrentVC].view animated:YES];
|
||||
UIWindow *keyWindow = UIApplication.sharedApplication.windows.firstObject;
|
||||
for (UIWindow *window in UIApplication.sharedApplication.windows) {
|
||||
if (window.isKeyWindow) {
|
||||
keyWindow = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[MBProgressHUD hideHUDForView:keyWindow animated:YES];
|
||||
[EasyTextView showErrorText:@"请求超时"];
|
||||
}
|
||||
|
||||
}];
|
||||
|
||||
}else if(requestType == RequestTypeOterTypePost) {//参数表单上传
|
||||
//获取当前时间戳
|
||||
|
||||
NSDate *date = [NSDate date];
|
||||
|
||||
NSTimeInterval time = [date timeIntervalSince1970];
|
||||
|
||||
NSString *timeString = [NSString stringWithFormat:@"%.0f", time];
|
||||
|
||||
[session.requestSerializer setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
|
||||
//加密
|
||||
NSString * needSign = [NSString stringWithFormat:@"%@%@",timeString,params];
|
||||
|
||||
NSString * sign = [self signWithTimestamp:timeString body:params secretKey:SecretKey];
|
||||
|
||||
DLog(@"%@",sign);
|
||||
|
||||
[session POST:url parameters:params headers:@{@"X-Timestamp":timeString,@"X-Sign":sign} progress:^(NSProgress * _Nonnull downloadProgress) {
|
||||
|
||||
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
||||
|
||||
[weakSelf dealWithResponseObject:responseObject cacheUrl:allUrl];
|
||||
|
||||
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
||||
NSString * statusCode = [error.userInfo objectForKey:@"NSLocalizedDescription"];
|
||||
if ([statusCode containsString:@"401"]) {
|
||||
DLog(@"%@",error.userInfo);
|
||||
[HQCommonUtils keyedArchiverWithData:nil key:LoginUserInfo];
|
||||
KPostNotification(KNotificationLoginStateChange, @NO);
|
||||
if (![HQCommonUtils isLogin]) {
|
||||
[EasyTextView showErrorText:@"请您登录"];
|
||||
}
|
||||
else{
|
||||
[EasyTextView showErrorText:@"身份信息已过期"];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
NSLog(@"%@",url);
|
||||
[MBProgressHUD hideHUDForView:[HQCommonUtils getCurrentVC].view animated:YES];
|
||||
UIWindow *keyWindow = UIApplication.sharedApplication.windows.firstObject;
|
||||
for (UIWindow *window in UIApplication.sharedApplication.windows) {
|
||||
if (window.isKeyWindow) {
|
||||
keyWindow = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[MBProgressHUD hideHUDForView:keyWindow animated:YES];
|
||||
[EasyTextView showErrorText:@"请求超时"];
|
||||
}
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -345,7 +483,7 @@ typedef NS_ENUM(NSInteger, RequestType) {
|
||||
}
|
||||
if ([response.allKeys containsObject:@"code"]) {
|
||||
|
||||
if ([[response objectForKey:@"code"] integerValue] == 200)
|
||||
if ([[response objectForKey:@"code"] integerValue] == 200 ||( [[response objectForKey:@"code"] integerValue] == 0 && [url containsString:@"listAll"]))
|
||||
{
|
||||
flag = true;
|
||||
}else
|
||||
@@ -504,5 +642,38 @@ typedef NS_ENUM(NSInteger, RequestType) {
|
||||
self.requestDelegate=nil;
|
||||
}
|
||||
|
||||
#pragma mark:外部加密sign
|
||||
- (NSString *)signWithTimestamp:(NSString *)timestamp
|
||||
body:(NSDictionary *)bodyDict
|
||||
secretKey:(NSString *)secretKey {
|
||||
|
||||
// 1 字典转 JSON
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:bodyDict options:0 error:nil];
|
||||
NSString *body = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
// 2 拼接字符串
|
||||
NSString *signString = [NSString stringWithFormat:@"%@%@", timestamp, body];
|
||||
|
||||
// 3 HMAC-SHA256
|
||||
const char *key = [secretKey UTF8String];
|
||||
const char *data = [signString UTF8String];
|
||||
|
||||
unsigned char result[CC_SHA256_DIGEST_LENGTH];
|
||||
|
||||
CCHmac(kCCHmacAlgSHA256,
|
||||
key,
|
||||
strlen(key),
|
||||
data,
|
||||
strlen(data),
|
||||
result);
|
||||
|
||||
// 4 转16进制
|
||||
NSMutableString *hash = [NSMutableString string];
|
||||
|
||||
for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
|
||||
[hash appendFormat:@"%02x", result[i]];
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
//
|
||||
// SDGETHealthTokenManager.h
|
||||
// EscortProject
|
||||
//
|
||||
// Created by 仁康信息 on 2024/1/4.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^successBlock)(NSDictionary *responseObject);
|
||||
typedef void (^failedBlock)(NSError *error);
|
||||
|
||||
@interface SDGETHealthTokenManager : NSObject
|
||||
|
||||
+(SDGETHealthTokenManager *)getHealthTokenManager;
|
||||
|
||||
- (void)getTokenSuccess:(successBlock)success
|
||||
failed:(failedBlock)failed;
|
||||
|
||||
|
||||
-(void)getUserJoinStatusSuccess:(successBlock)success
|
||||
failed:(failedBlock)failed;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,195 +0,0 @@
|
||||
//
|
||||
// SDGETHealthTokenManager.m
|
||||
// EscortProject
|
||||
//
|
||||
// Created by 仁康信息 on 2024/1/4.
|
||||
//
|
||||
|
||||
#import "SDGETHealthTokenManager.h"
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#import "RSAObjC.h"
|
||||
|
||||
@interface SDGETHealthTokenManager ()
|
||||
@property (nonatomic,strong)AFHTTPSessionManager *session;
|
||||
@end
|
||||
|
||||
@implementation SDGETHealthTokenManager
|
||||
|
||||
|
||||
#pragma mark - 初始化单例
|
||||
+(SDGETHealthTokenManager *)getHealthTokenManager
|
||||
{
|
||||
static SDGETHealthTokenManager *manager = nil;
|
||||
static dispatch_once_t pred;
|
||||
dispatch_once(&pred, ^{
|
||||
manager = [[self alloc] init];
|
||||
});
|
||||
return manager;
|
||||
}
|
||||
-(id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_session = [AFHTTPSessionManager manager];
|
||||
|
||||
/***********请求的序列化**********/
|
||||
//传Json 对象
|
||||
_session.requestSerializer = [AFJSONRequestSerializer serializer];
|
||||
//设置超时时间
|
||||
[_session.requestSerializer willChangeValueForKey:@"timeoutInterval"];
|
||||
_session.requestSerializer.timeoutInterval = 10.f;
|
||||
[_session.requestSerializer didChangeValueForKey:@"timeoutInterval"];
|
||||
|
||||
/**********响应的序列化**************/
|
||||
_session.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
_session.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/plain" ,@"text/javascript",@"text/html",nil];
|
||||
}
|
||||
return self;
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(void)httpRequestWithURL:(NSString *)url
|
||||
parameters:(NSDictionary*)paraDic
|
||||
hearders:(NSDictionary *)hearder
|
||||
success:(successBlock)success
|
||||
failed:(failedBlock)failed
|
||||
{
|
||||
|
||||
NSString *fullURL = [NSString stringWithFormat:@"%@/%@",BASEURL,url];
|
||||
[_session POST:fullURL parameters:paraDic headers:hearder progress:^(NSProgress * _Nonnull uploadProgress) {
|
||||
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
||||
success(responseObject);
|
||||
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
||||
failed(error);
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void)httpRequestGetWithURL:(NSString *)url
|
||||
parameters:(NSDictionary*)paraDic
|
||||
hearders:(NSDictionary *)hearder
|
||||
success:(successBlock)success
|
||||
failed:(failedBlock)failed
|
||||
{
|
||||
|
||||
NSString *fullURL = [NSString stringWithFormat:@"%@/%@",BASEURL,url];
|
||||
|
||||
[_session GET:fullURL parameters:paraDic headers:hearder progress:nil success:^(NSURLSessionTask *task, NSDictionary * responseObject) {
|
||||
|
||||
success(responseObject);
|
||||
} failure:^(NSURLSessionTask *operation, NSError *error) {
|
||||
failed(error);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)getTokenSuccess:(successBlock)success failed:(failedBlock)failed {
|
||||
|
||||
NSMutableDictionary * dic = [[NSMutableDictionary alloc] init];
|
||||
|
||||
NSMutableDictionary * headerDic = [[NSMutableDictionary alloc] init];
|
||||
NSDate * date = [NSDate date];
|
||||
NSDateFormatter *matter = [[NSDateFormatter alloc] init];
|
||||
matter.dateFormat = @"yyyyMMddHHmmss";
|
||||
NSString * dateString = [matter stringFromDate:date];
|
||||
|
||||
[dic setObject:dateString forKey:@"timeSign"];
|
||||
NSMutableDictionary * sigDic = [[NSMutableDictionary alloc] init];
|
||||
[sigDic setObject:dateString forKey:@"timeSign"];
|
||||
NSString * needSersy = [sigDic modelToJSONString];
|
||||
// 时间戳
|
||||
NSError *parseError;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:sigDic options:0 error:&parseError];
|
||||
if (parseError) {
|
||||
//解析出错
|
||||
}
|
||||
NSString * str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
// 时间戳
|
||||
NSMutableString * str3 = [[NSMutableString alloc]initWithString:str];
|
||||
|
||||
[str3 replaceOccurrencesOfString:@"\\" withString:@"" options:1 range:NSMakeRange(0, str3.length)];
|
||||
|
||||
[str3 appendString:@"dd05f1c54d63749eda95f9fa6d49v442a"];
|
||||
|
||||
NSString * md5str = [self getMd5_32Bit_String:str3];
|
||||
|
||||
[headerDic setObject:dateString forKey:@"X-TIMESTAMP"];
|
||||
[headerDic setObject:md5str forKey:@"X-Sign"];
|
||||
|
||||
[self httpRequestGetWithURL:@"gateway/sys/getPublicKey" parameters:dic hearders:@{@"X-TIMESTAMP":dateString,@"X-Sign":md5str} success:^(NSDictionary * _Nonnull responseObject) {
|
||||
|
||||
if ([responseObject.allKeys containsObject:@"code"]) {
|
||||
|
||||
if ([[responseObject objectForKey:@"code"] integerValue] == 200)
|
||||
{
|
||||
NSString *pubkey ;
|
||||
if ([responseObject.allKeys containsObject:@"result"]) {
|
||||
pubkey = [NSString stringWithFormat:@"-----BEGIN PUBLIC KEY-----\n%@\n-----END PUBLIC KEY-----",responseObject[@"result"]];
|
||||
// 时间戳
|
||||
}
|
||||
HQUserInfo * user = [HQCommonUtils keyedUnarchiverWithKey:LoginUserInfo];
|
||||
|
||||
NSString *ret = [RSAObjC encrypt:user.idCard PublicKey:pubkey];
|
||||
DLog(@"encrypted: %@", ret);
|
||||
|
||||
if (ValidStr(ret)) {
|
||||
// KPostNotification(KNotificationLoginStateChange, @NO);
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary * parmDic = [[NSMutableDictionary alloc] init];
|
||||
[parmDic setObject:[NSString stringWithFormat:@"RSA_%@",ret] forKey: @"idcard"];
|
||||
|
||||
NSDate * date = [NSDate date];
|
||||
NSDateFormatter *matter = [[NSDateFormatter alloc] init];
|
||||
matter.dateFormat = @"yyyyMMddHHmmss";
|
||||
NSString * dateString = [matter stringFromDate:date];
|
||||
|
||||
NSError *parseError;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parmDic options:0 error:&parseError];
|
||||
if (parseError) {
|
||||
//解析出错
|
||||
}
|
||||
NSString * str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
// 时间戳
|
||||
NSMutableString * str3 = [[NSMutableString alloc]initWithString:str];
|
||||
|
||||
[str3 replaceOccurrencesOfString:@"\\" withString:@"" options:1 range:NSMakeRange(0, str3.length)];
|
||||
|
||||
[str3 appendString:@"dd05f1c54d63749eda95f9fa6d49v442a"];
|
||||
|
||||
NSString * md5str = [self getMd5_32Bit_String:str3];
|
||||
|
||||
|
||||
[self httpRequestWithURL:@"gateway/sys/thirdAppGetTokenByIdCard" parameters:parmDic hearders:@{@"X-TIMESTAMP":dateString,@"X-Sign":md5str} success:success failed:failed];
|
||||
}
|
||||
else
|
||||
{
|
||||
success(responseObject);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} failed:^(NSError * _Nonnull error) {
|
||||
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (NSString *)getMd5_32Bit_String:(NSString *)srcString {
|
||||
// 参数 srcString 传进来的字符串
|
||||
// 参数 isUppercase 是否需要大小写
|
||||
const char *cStr = [srcString UTF8String];
|
||||
unsigned char digest[CC_MD5_DIGEST_LENGTH];
|
||||
CC_MD5( cStr, (CC_LONG)srcString.length, digest );
|
||||
NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
|
||||
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
|
||||
[result appendFormat:@"%02X", digest[i]];
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,33 +0,0 @@
|
||||
//
|
||||
// SDHttpRequest.h
|
||||
// colorPrintingMaster
|
||||
//
|
||||
// Created by 青山小明 on 17/5/3.
|
||||
// Copyright © 2017年 zhangming. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
typedef void (^successBlock)(NSDictionary *responseObject);
|
||||
typedef void (^failedBlock)(NSError *error);
|
||||
|
||||
@interface SDHttpRequest : NSObject
|
||||
+(SDHttpRequest *)httpRequest;
|
||||
|
||||
#pragma mark - 首页
|
||||
- (void)getInterWatchDataUrlWithParm:(NSMutableDictionary *)parmDic
|
||||
Success:(successBlock)success
|
||||
failed:(failedBlock)failed;
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
-(void)postWithParameter:(NSDictionary *)para
|
||||
images:(NSArray *)images
|
||||
success:(successBlock)success
|
||||
failed:(failedBlock)failed;
|
||||
|
||||
//获取服务地址
|
||||
- (void)getChangeUrlSuccess:(successBlock)success
|
||||
failed:(failedBlock)failed;
|
||||
|
||||
@end
|
||||
@@ -1,133 +0,0 @@
|
||||
//
|
||||
// SDHttpRequest.m
|
||||
// colorPrintingMaster
|
||||
//
|
||||
// Created by 青山小明 on 17/5/3.
|
||||
// Copyright © 2017年 zhangming. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SDHttpRequest.h"
|
||||
#import "AFNetworking.h"
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#import "RSAObjC.h"
|
||||
//static SDHttpRequest *singleton = nil;
|
||||
|
||||
@interface SDHttpRequest ()
|
||||
@property (nonatomic,strong)AFHTTPSessionManager *session;
|
||||
@end
|
||||
|
||||
@implementation SDHttpRequest
|
||||
#pragma mark - 初始化单例
|
||||
+(SDHttpRequest *)httpRequest
|
||||
{
|
||||
static SDHttpRequest *manager = nil;
|
||||
static dispatch_once_t pred;
|
||||
dispatch_once(&pred, ^{
|
||||
manager = [[self alloc] init];
|
||||
});
|
||||
return manager;
|
||||
}
|
||||
-(id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_session = [AFHTTPSessionManager manager];
|
||||
|
||||
/***********请求的序列化**********/
|
||||
//传Json 对象
|
||||
_session.requestSerializer = [AFJSONRequestSerializer serializer];
|
||||
//设置超时时间
|
||||
[_session.requestSerializer willChangeValueForKey:@"timeoutInterval"];
|
||||
_session.requestSerializer.timeoutInterval = 30.f;
|
||||
[_session.requestSerializer didChangeValueForKey:@"timeoutInterval"];
|
||||
|
||||
/**********响应的序列化**************/
|
||||
_session.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
_session.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/plain" ,@"text/javascript",@"text/html",nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
#pragma mark---请求调用的方法
|
||||
-(void)httpRequestWithURL:(NSString *)url
|
||||
parameters:(NSDictionary*)paraDic
|
||||
success:(successBlock)success
|
||||
failed:(failedBlock)failed
|
||||
{
|
||||
NSUserDefaults * tokenDefaul = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
NSString * token = [tokenDefaul objectForKey:KHEALTHTOKEN];
|
||||
|
||||
|
||||
|
||||
NSString *fullURL = [NSString stringWithFormat:@"%@/%@",BASEURL,url];
|
||||
[_session POST:fullURL parameters:paraDic headers: @{@"X-Access-Token":token} progress:^(NSProgress * _Nonnull uploadProgress) {
|
||||
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
||||
success(responseObject);
|
||||
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
||||
failed(error);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)uploadImagesWithURL:(NSString *)url
|
||||
parameters:(NSDictionary *)paraDic
|
||||
hearders:(NSDictionary *)hearder
|
||||
imagesKey:(NSString *)imagesKey
|
||||
images:(NSArray *)images
|
||||
success:(successBlock)success
|
||||
failed:(failedBlock)failed
|
||||
{
|
||||
NSString *fullURL = [NSString stringWithFormat:@"%@/%@",BASEURL,url];
|
||||
|
||||
[_session POST:fullURL parameters:paraDic headers:hearder constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
|
||||
for (UIImage *image in images)
|
||||
{
|
||||
[formData appendPartWithFileData:UIImageJPEGRepresentation(image, 0.5)
|
||||
name:imagesKey
|
||||
fileName:@"1.jpeg"
|
||||
mimeType:@"image/jpeg"];
|
||||
}
|
||||
|
||||
} progress:^(NSProgress * _Nonnull uploadProgress) {
|
||||
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
||||
success(responseObject);
|
||||
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
||||
failed(error);
|
||||
}];
|
||||
}
|
||||
|
||||
-(void)httpRequestGetWithURL:(NSString *)url
|
||||
parameters:(NSDictionary*)paraDic
|
||||
success:(successBlock)success
|
||||
failed:(failedBlock)failed
|
||||
{
|
||||
NSUserDefaults * tokenDefaul = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
NSString * token = [tokenDefaul objectForKey:KHEALTHTOKEN];
|
||||
|
||||
NSString *fullURL = [NSString stringWithFormat:@"%@/%@",BASEURL,url];
|
||||
|
||||
[_session GET:fullURL parameters:paraDic headers:@{@"X-Access-Token":token} progress:nil success:^(NSURLSessionTask *task, NSDictionary * responseObject) {
|
||||
|
||||
success(responseObject);
|
||||
} failure:^(NSURLSessionTask *operation, NSError *error) {
|
||||
failed(error);
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - 首页
|
||||
- (void)getInterWatchDataUrlWithParm:(NSMutableDictionary *)parmDic
|
||||
Success:(successBlock)success
|
||||
failed:(failedBlock)failed {
|
||||
|
||||
//参数
|
||||
[self httpRequestGetWithURL:@"health-watch/watchH5Api/indexDataNew"
|
||||
parameters:parmDic success:success failed:failed];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
+88
-2
@@ -9,7 +9,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "JKCQNetworkingWithCache.h"
|
||||
|
||||
@interface JKCQAPI : NSObject
|
||||
@interface XJPNetAPI : NSObject
|
||||
|
||||
@property (nonatomic,strong) JKCQNetworkingWithCache * httpRequest;
|
||||
|
||||
@@ -27,7 +27,28 @@
|
||||
- (void)GetSoSHomePageResources:(NSMutableDictionary *)pamraDic;
|
||||
- (void)PostEndSoSIMQuestion:(NSMutableDictionary *)pamraDic;
|
||||
- (void)getSoSCarInfoLocationHome:(NSMutableDictionary *)parmDic;
|
||||
|
||||
// 急救员 - 搜索专家
|
||||
- (void)getSearchExpert:(NSMutableDictionary *)parmDic;
|
||||
// 急救员 - 搜索员工
|
||||
- (void)getSearchEmployee:(NSMutableDictionary *)parmDic;
|
||||
// 急救员 - 我参与的应急工单
|
||||
- (void)getMyParticipatedOrders:(NSMutableDictionary *)parmDic;
|
||||
// 急救员 - 创建群聊(不发起音视频通话)
|
||||
- (void)getCreateGroupMagFirstAider:(NSMutableDictionary *)parmDic;
|
||||
// 急救员 - 邀请进群
|
||||
- (void)postAddGroupUser:(NSMutableDictionary *)parmDic;
|
||||
// 急救员 - 移除群成员
|
||||
- (void)postRemoveGroupUser:(NSMutableDictionary *)parmDic;
|
||||
// 急救员 - 判断是否联络员
|
||||
- (void)getIsLiaisonUser:(NSMutableDictionary *)parmDic;
|
||||
// 急救员 - 群成员列表
|
||||
- (void)getGroupMemberList:(NSMutableDictionary *)parmDic;
|
||||
// 急救员 - 实际群成员列表(经腾讯IM验证,含isSelf字段)
|
||||
- (void)getActualGroupMemberList:(NSMutableDictionary *)parmDic;
|
||||
// 急救员 - 宣教资源详情
|
||||
- (void)getFirstAidResourceDetail:(NSMutableDictionary *)parmDic;
|
||||
// 一人一案 - 健康档案详情
|
||||
- (void)getOnePersonCase:(NSMutableDictionary *)parmDic;
|
||||
|
||||
//首页接口
|
||||
- (void)GetQuetsionRecordsList:(NSMutableDictionary *)parmDic;
|
||||
@@ -73,6 +94,7 @@
|
||||
- (void)getOneKeyQuestionByID:(NSMutableDictionary *)parmDic;
|
||||
- (void)postSearchOneKeyQuestionData:(NSMutableDictionary *)parmDic;
|
||||
- (void)getHistoryReportById:(NSMutableDictionary *)parmDic;
|
||||
- (void)recordDoctorCardInfoClick:(NSMutableDictionary *)parmDic;
|
||||
|
||||
#pragma mark:咨询人管理
|
||||
|
||||
@@ -123,4 +145,68 @@
|
||||
|
||||
- (void)getMinitringWatchData:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getInterMonitoringMaxMinData:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getWarningWatchListV2Data:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getWranHistoryList:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getSOSDoctorRecordList:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getSOSDoctorDetailInfo:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getSOSSmallSumData:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)healthAccountLogin:(NSMutableDictionary *)parmDic;
|
||||
|
||||
//版本更新
|
||||
- (void)GetAppVesionUpdata:(NSMutableDictionary *)parmDic;
|
||||
|
||||
#pragma mark:模拟数据
|
||||
//获取模拟用户信息(判断是否为模拟)
|
||||
- (void)postSimulationUser:(NSMutableDictionary *)parmDic;
|
||||
//获取系统用户数据(查询全部用户,不做租户隔离)
|
||||
- (void)getSimulationUserList:(NSMutableDictionary *)parmDic;
|
||||
//开启模拟
|
||||
- (void)postStartedSimulationUser:(NSMutableDictionary *)parmDic;
|
||||
//恢复用户状态
|
||||
- (void)postRecoverySimulationUser:(NSMutableDictionary *)parmDic;
|
||||
|
||||
//消息
|
||||
- (void)getUserMessageList:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getUserMessageDetailConnet:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getHomepageBannerList:(NSMutableDictionary *)parmDic;
|
||||
|
||||
//我的积分
|
||||
- (void)getPointsBankHeard:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)postPointsBankRankData:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)postPointsBankSourceDetail:(NSMutableDictionary *)parmDic;
|
||||
- (void)postPointsCheckInCard:(NSMutableDictionary *)parmDic;
|
||||
|
||||
//积分任务
|
||||
- (void)postPointsTaskList:(NSMutableDictionary *)parmDic;
|
||||
|
||||
//图片地址
|
||||
- (void)getDetailImageAddress:(NSMutableDictionary *)parmDic;
|
||||
//轮播图一次性全请求
|
||||
- (void)getHomeBannerAllData:(NSMutableDictionary *)parmDic;
|
||||
|
||||
//手表接口
|
||||
- (void)getHomeWatchWearBool:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getHomeWatchData:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)getWebNeedEncryptionKey:(NSMutableDictionary *)parmDic;
|
||||
|
||||
//绑定手表
|
||||
- (void)getBindWatchDevice:(NSMutableDictionary *)parmDic;
|
||||
//解绑手表
|
||||
- (void)getUnBindWatchDevice:(NSMutableDictionary *)parmDic;
|
||||
|
||||
- (void)postPointsUnmberData:(NSMutableDictionary *)parmDic;
|
||||
|
||||
@end
|
||||
+246
-10
@@ -1,18 +1,12 @@
|
||||
//
|
||||
// API.m
|
||||
// XZYNetworking
|
||||
//
|
||||
// Created by 徐自由 on 2017/12/25.
|
||||
// Copyright © 2017年 徐自由. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JKCQAPI.h"
|
||||
|
||||
#import "XJPNetAPI.h"
|
||||
|
||||
#define needToken httpRequest.needToken
|
||||
#define isLoginFlag httpRequest.isLoginFlag
|
||||
|
||||
|
||||
@implementation JKCQAPI
|
||||
@implementation XJPNetAPI
|
||||
|
||||
#pragma mark - init方法
|
||||
@synthesize httpRequest;
|
||||
@@ -75,6 +69,61 @@
|
||||
|
||||
}
|
||||
|
||||
// 急救员 - 搜索专家
|
||||
- (void)getSearchExpert:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/order/searchExpert",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 急救员 - 判断是否联络员
|
||||
- (void)getIsLiaisonUser:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/emergency/LargeScreenNew/isLiaisonUser",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 急救员 - 创建群聊(不发起音视频通话)
|
||||
- (void)getCreateGroupMagFirstAider:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/createGroupMagFirstAider",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 急救员 - 我参与的应急工单
|
||||
- (void)getMyParticipatedOrders:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/order/myParticipatedOrders",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 急救员 - 搜索员工
|
||||
- (void)getSearchEmployee:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/order/searchEmployee",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 急救员 - 邀请进群
|
||||
- (void)postAddGroupUser:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/addGroupUser",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 急救员 - 移除群成员
|
||||
- (void)postRemoveGroupUser:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/removeGroupUser",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 急救员 - 群成员列表
|
||||
- (void)getGroupMemberList:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/order/getGroupMemberList",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 急救员 - 实际群成员列表(经腾讯IM验证,含isSelf字段)
|
||||
- (void)getActualGroupMemberList:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/order/getActualGroupMemberList",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 急救员 - 宣教资源详情
|
||||
- (void)getFirstAidResourceDetail:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/firstAid/resource/resource/queryById",Http] params:parmDic];
|
||||
}
|
||||
|
||||
// 一人一案 - 健康档案详情
|
||||
- (void)getOnePersonCase:(NSMutableDictionary *)parmDic {
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/emergency/LargeScreenNew/onePersonCase",Http] params:parmDic];
|
||||
}
|
||||
|
||||
- (void)getNearbyHomePageHospitalPoint:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/medical-center/api/resource/nearbyResource",Http] params:parmDic];
|
||||
@@ -106,6 +155,13 @@
|
||||
|
||||
}
|
||||
|
||||
//记录医生信息
|
||||
- (void)recordDoctorCardInfoClick:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/health-consultation/con-message/saveReadLog",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
- (void)GetAllHistoryChatRecord:(NSMutableDictionary *)parmDic {
|
||||
//http://192.168.1.28/health-consultation/?groupId=1801087415104962560&pageNo=1&pageSize=10
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-consultation/api/consult/conSession/selectImMessagePageListSession",Http] params:parmDic];
|
||||
@@ -550,7 +606,7 @@
|
||||
- (void)getUserAgreementPrivacy:(NSMutableDictionary *)parmDic {
|
||||
|
||||
//GET https://cqyt.test.yg.icdat.cn/health-consultation/api/consult/conDoctor/selectDictList?dictKey=jump_url HTTP/1.1
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-consultation/api/consult/conDoctor/selectDictList?dictKey=qh_ios_jump_url",Http] params:parmDic];
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-consultation/api/consult/conDoctor/selectDictList?dictKey=jump_url",Http] params:parmDic];
|
||||
|
||||
|
||||
}
|
||||
@@ -747,5 +803,185 @@
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-watch/watchH5Api/indexDataNew",Http] params:parmDic];
|
||||
}
|
||||
|
||||
//更新接口
|
||||
- (void)getWarningWatchListV2Data:(NSMutableDictionary *)parmDic {
|
||||
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-watch/watchH5Api/indexDataNew/v2",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
- (void)getInterMonitoringMaxMinData:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-watch/watchH5Api/thresholdSetting",Http] params:parmDic];
|
||||
}
|
||||
|
||||
- (void)getWranHistoryList:(NSMutableDictionary *)parmDic {
|
||||
// https://health-api.tzgl.shuziweidao.com/health-watch/watchH5Api/historicalWarn?eventType=spo2&queryDate=2025-07-01&userId=1898914204455915521&pageNo=1&pageSize=100
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-watch/watchH5Api/historicalWarn",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
//应急就医
|
||||
- (void)getSOSDoctorRecordList:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/order/initUserOrderPage",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
- (void)getSOSDoctorDetailInfo:(NSMutableDictionary *)parmDic {
|
||||
|
||||
//GET https://cqyt.test.yg.icdat.cn/health-emergency/api/emergency/order/orderThrough?id=1744265549623332865 HTTP/1.1
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/order/getOrderById",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
//应急小结
|
||||
- (void)getSOSSmallSumData:(NSMutableDictionary *)parmDic {
|
||||
//
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-emergency/api/emergency/order/orderThrough",Http] params:parmDic];
|
||||
|
||||
}
|
||||
//登录
|
||||
- (void)healthAccountLogin:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/sys/mLoginAnYan",Http] params:parmDic];
|
||||
|
||||
}
|
||||
//版本更新
|
||||
|
||||
- (void)GetAppVesionUpdata:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-system/version/getSysVersionDetailByPackageName",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
#pragma mark:模拟用户
|
||||
|
||||
- (void)postSimulationUser:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/health-system/test/fakeUser",Http] params:parmDic];
|
||||
|
||||
}
|
||||
//获取系统用户数据(查询全部用户,不做租户隔离)
|
||||
- (void)getSimulationUserList:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-system/sys/user/listAll",Http] params:parmDic];
|
||||
|
||||
|
||||
}
|
||||
//开启模拟
|
||||
- (void)postStartedSimulationUser:(NSMutableDictionary *)parmDic{
|
||||
|
||||
[httpRequest httpPostFormDataRequest:[NSString stringWithFormat:@"%@/health-system/test/fake",Http] params:parmDic];
|
||||
|
||||
}
|
||||
//恢复用户状态
|
||||
- (void)postRecoverySimulationUser:(NSMutableDictionary *)parmDic{
|
||||
|
||||
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/health-system/test/restore",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
- (void)getUserMessageList:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-system/app/sys/message/notice/list",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
- (void)getUserMessageDetailConnet:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-system/app/sys/message/notice/queryById",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
//轮播图
|
||||
- (void)getHomepageBannerList:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/sys/api/banner/selectBannerList",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
- (void)getWebNeedEncryptionKey:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-system/api/sys/encryptInfo",Http] params:parmDic];
|
||||
|
||||
}
|
||||
//积分银行
|
||||
- (void)getPointsBankHeard:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-system/bank/userPoints/app/myPoints",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
//积分榜单
|
||||
- (void)postPointsBankRankData:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/health-system/bank/userPoints/app/pointRanking",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
//积分明细
|
||||
- (void)postPointsBankSourceDetail:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/health-system/bank/userPoints/app/pointRecord",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
//积分任务
|
||||
- (void)postPointsCheckInCard:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/health-system/bank/userPoints/app/pointCheckIn",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
|
||||
//积分任务
|
||||
- (void)postPointsTaskList:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpPostRequest:[NSString stringWithFormat:@"%@/health-system/bank/userPoints/app/pointsTaskList",Http] params:parmDic];
|
||||
|
||||
}
|
||||
|
||||
//图片地址
|
||||
- (void)getDetailImageAddress:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-consultation/consultation/conSession/getPicUrl",Http] params:parmDic];
|
||||
}
|
||||
|
||||
- (void)getHomeBannerAllData:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-system/sys/api/banner/selectAllBannerList",Http] params:parmDic];
|
||||
}
|
||||
|
||||
#pragma mark:手表相关
|
||||
//是否佩戴手表
|
||||
- (void)getHomeWatchWearBool:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-watch/api/watchData/findWatchInfo",Http] params:parmDic];
|
||||
}
|
||||
|
||||
//手表数据
|
||||
- (void)getHomeWatchData:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-watch/api/watchData/userWatchDataAll",Http] params:parmDic];
|
||||
}
|
||||
|
||||
|
||||
- (void)getBindWatchDevice:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-watch/watch/watchDevice/app/bindDevice",Http] params:parmDic];
|
||||
}
|
||||
//解绑手表
|
||||
- (void)getUnBindWatchDevice:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpGetRequest:[NSString stringWithFormat:@"%@/health-watch/watch/watchDevice/app/unbundleDevice",Http] params:parmDic];
|
||||
}
|
||||
|
||||
//外部接口
|
||||
- (void)postPointsUnmberData:(NSMutableDictionary *)parmDic {
|
||||
|
||||
[httpRequest httpOtherPostRequest:[NSString stringWithFormat:@"%@/api/v1/users/point-details",OtherHttp] params:parmDic];
|
||||
}
|
||||
@end
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ESCTUIManager.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by 仁康信息 on 2023/2/16.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ESCTUIManager.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by 仁康信息 on 2023/2/16.
|
||||
//
|
||||
@@ -30,6 +30,9 @@
|
||||
[TUILogin login:sdkAppid userID:userID userSig:userSig succ:^{
|
||||
|
||||
// KPostNotification(KNotificationLoginIMResult, @YES);
|
||||
HQUserInfo *user = [HQCommonUtils keyedUnarchiverWithKey:LoginUserInfo];
|
||||
[[TUICallKit createInstance] setSelfInfo:user.realname avatar:user.avatar succ:nil fail:nil];
|
||||
DLog(@"IM登录成功");
|
||||
|
||||
} fail:^(int code, NSString *msg) {
|
||||
|
||||
@@ -76,10 +79,10 @@
|
||||
[TUIChatConfig defaultConfig].enableAudioCall = isAudio; // YES:开启,NO:关闭
|
||||
// 把 TUIC2CChatViewController 添加到自己的 ViewController
|
||||
|
||||
HQBaseViewController * currentVc =(HQBaseViewController *)[HQCommonUtils getCurrentVC];
|
||||
XJBaseViewController * currentVc =(XJBaseViewController *)[HQCommonUtils getCurrentVC];
|
||||
if (!currentVc) {
|
||||
|
||||
currentVc = [[HQBaseViewController alloc] init];
|
||||
currentVc = [[XJBaseViewController alloc] init];
|
||||
}
|
||||
[currentVc addChildViewController:vc];
|
||||
[currentVc.view addSubview:vc.view];
|
||||
@@ -103,7 +106,6 @@
|
||||
}
|
||||
|
||||
+ (void)sendGroupVideo:(NSString *)groupID withUserIdList:(NSArray *)userList {
|
||||
|
||||
[[TUICallKit createInstance] groupCall:groupID userIdList:userList callMediaType:TUICallMediaTypeVideo];
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
[aCoder encodeObject:self.depart_id forKey:@"depart_id"];
|
||||
[aCoder encodeObject:self.parentId forKey:@"parentId"];
|
||||
[aCoder encodeObject:self.departName forKey:@"departName"];
|
||||
[aCoder encodeObject:self.workNo forKey:@"workNo"];
|
||||
[aCoder encodeObject:self.token forKey:@"token"];
|
||||
[aCoder encodeObject:self.sex_dictText forKey:@"sex_dictText"];
|
||||
|
||||
@@ -43,6 +44,8 @@
|
||||
self.parentId = [aDecoder decodeObjectForKey:@"parentId"];
|
||||
self.departName = [aDecoder decodeObjectForKey:@"departName"];
|
||||
self.token = [aDecoder decodeObjectForKey:@"token"];
|
||||
self.workNo = [aDecoder decodeObjectForKey:@"workNo"];
|
||||
|
||||
self.sex_dictText = [aDecoder decodeObjectForKey:@"sex_dictText"];
|
||||
|
||||
}
|
||||
@@ -51,21 +54,41 @@
|
||||
|
||||
|
||||
- (void)setUserInfo:(NSDictionary *)userInfo {
|
||||
if (![userInfo isKindOfClass:[NSDictionary class]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
_userInfo = userInfo;
|
||||
self.user_id = [_userInfo objectForKey:@"id"];
|
||||
self.avatar = [NSString stringWithFormat:@"%@%@",ResourceAddress,[_userInfo objectForKey:@"avatar"]];
|
||||
self.phone = [_userInfo objectForKey:@"phone"];
|
||||
self.realname = [_userInfo objectForKey:@"realname"];
|
||||
self.username = [_userInfo objectForKey:@"username"];
|
||||
self.sex = [_userInfo objectForKey:@"sex"];
|
||||
self.idCard = [_userInfo objectForKey:@"idCard"];
|
||||
self.personType = [_userInfo objectForKey:@"personType"];
|
||||
self.secondDepart = [_userInfo objectForKey:@"secondDepart"];
|
||||
self.sex_dictText = [_userInfo objectForKey:@"sex_dictText"];
|
||||
self.depart_id = [self.secondDepart objectForKey:@"id"];
|
||||
self.parentId = [self.secondDepart objectForKey:@"parentId"];
|
||||
self.departName = [self.secondDepart objectForKey:@"departName"];
|
||||
|
||||
// 一个小工具块,用于安全取值(避免 NSNull)
|
||||
id (^safeValue)(id obj) = ^id(id obj) {
|
||||
return (obj && ![obj isKindOfClass:[NSNull class]]) ? obj : nil;
|
||||
};
|
||||
|
||||
self.user_id = safeValue(userInfo[@"id"]);
|
||||
|
||||
NSString *avatarPath = safeValue(userInfo[@"avatar"]);
|
||||
self.avatar = avatarPath ? [NSString stringWithFormat:@"%@%@", ResourceAddress, avatarPath] : nil;
|
||||
|
||||
self.phone = safeValue(userInfo[@"phone"]);
|
||||
self.realname = safeValue(userInfo[@"realname"]);
|
||||
self.username = safeValue(userInfo[@"username"]);
|
||||
self.sex = safeValue(userInfo[@"sex"]);
|
||||
self.idCard = safeValue(userInfo[@"idCard"]);
|
||||
self.personType = safeValue(userInfo[@"personType"]);
|
||||
self.sex_dictText = safeValue(userInfo[@"sex_dictText"]);
|
||||
self.workNo = safeValue(userInfo[@"workNo"]);
|
||||
|
||||
NSDictionary *secondDepart = safeValue(userInfo[@"secondDepart"]);
|
||||
if ([secondDepart isKindOfClass:[NSDictionary class]]) {
|
||||
self.secondDepart = secondDepart;
|
||||
self.depart_id = safeValue(secondDepart[@"id"]);
|
||||
self.parentId = safeValue(secondDepart[@"parentId"]);
|
||||
self.departName = safeValue(secondDepart[@"departName"]);
|
||||
} else {
|
||||
self.secondDepart = nil;
|
||||
self.depart_id = self.parentId = self.departName = nil;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>WechatOpenSDK.framework/WechatOpenSDK</string>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>WechatOpenSDK.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>WechatOpenSDK.framework/WechatOpenSDK</string>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64_x86_64-simulator</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>WechatOpenSDK.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>x86_64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
<key>XCFrameworkFormatVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
重要!
|
||||
SDK2.0.5
|
||||
1. 支持模块化集成:XCFramework 头文件引用改为标准化格式 #import <WechatOpenSDK/WXApi.h>,解决路径冲突并支持 Swift/ObjC 混合开发
|
||||
2. 修复openWXApp偶现失败的问题
|
||||
|
||||
SDK2.0.4
|
||||
1.增加privacy manifest文件
|
||||
2.修复跳微信时可能卡顿的问题
|
||||
|
||||
SDK2.0.2
|
||||
1. 优化XCFramework打包方式
|
||||
|
||||
SDK2.0.1
|
||||
1. SDK支持XCFramework
|
||||
|
||||
SDK2.0.0
|
||||
1. 分享能力支持内容防篡改校验
|
||||
|
||||
SDK1.9.9
|
||||
1. 授权登录支持关闭自动授权
|
||||
2. 分享支持添加签名,防止篡改
|
||||
|
||||
SDK1.9.7
|
||||
1. 适配CocoaPods
|
||||
|
||||
SDK1.9.6
|
||||
1. 适配iOS 16,减少读写剪切板
|
||||
|
||||
SDK1.9.4
|
||||
1. 修复授权登录取消/拒绝时state字段没有带回
|
||||
|
||||
SDK1.9.3
|
||||
1. 新增发起二维码支付能力
|
||||
|
||||
SDK1.9.2
|
||||
1. 新增发起企微客服会话能力
|
||||
|
||||
SDK1.9.1
|
||||
1. 音乐视频分享类型增加运营H5字段
|
||||
|
||||
SDK1.8.9
|
||||
1. 增加音乐视频分享类型
|
||||
|
||||
SDK1.8.8
|
||||
1. 增加游戏直播消息类型
|
||||
|
||||
SDK1.8.7.1
|
||||
1. 修复Xcode11以下编译不通过
|
||||
|
||||
SDK1.8.7
|
||||
1. 修复iPadOS,未安装微信的情况下,因为UA问题无法授权登录
|
||||
2. 修复未安装微信的情况下, 适配了UIScene的App因为UIAlertView Crash
|
||||
3. 增加Universal Link检测函数
|
||||
|
||||
SDK1.8.6.2
|
||||
1. 修改包含"UIWebView"字符的类名
|
||||
|
||||
SDK1.8.6.1
|
||||
1.短信授权登录使用的UIWebview切换成WKWebview
|
||||
|
||||
SDK1.8.6
|
||||
1. 支持Universal Link拉起微信以及返回App
|
||||
2. SDK移除MTA库
|
||||
|
||||
SDK1.8.5
|
||||
1. 更换MTA库:取消对剪切板的访问, 防止和其他SDK竞争导致crash
|
||||
2. NSMutableArray的MTA分类方法改名,减少命名冲突
|
||||
3. 不含支付功能版本移除非税支付和医保支付接口
|
||||
4. 分享音乐支持填写歌词和高清封面图
|
||||
|
||||
SDK1.8.4
|
||||
1. 调整分享图片大小限制
|
||||
2. 新增openBusinessView接口
|
||||
|
||||
SDK1.8.3
|
||||
1. SDK增加调起微信刷卡支付接口
|
||||
2. SDK增加小程序订阅消息接口
|
||||
3. 修复小程序订阅消息接口没有resp的问题
|
||||
|
||||
SDK1.8.2
|
||||
1. SDK增加开发票授权 WXInvoiceAuthInsert
|
||||
2. SDK增加非税接口 WXNontaxPay
|
||||
3. SDK增加医保接口 WXPayInsurance
|
||||
4. 更换MTA库
|
||||
|
||||
SDK1.8.1
|
||||
1. SDK打开小程序支持指定版本(体验,开发,正式版)
|
||||
2. SDK分享小程序支持指定版本(体验,开发,正式版)
|
||||
3. SDK支持输出log日志
|
||||
|
||||
SDK1.8.0
|
||||
1. SDK支持打开小程序
|
||||
2. SDK分享小程序支持shareTicket
|
||||
|
||||
SDK1.7.9
|
||||
1. SDK订阅一次性消息
|
||||
|
||||
SDK1.7.8
|
||||
1 SDK分享小程序支持大图
|
||||
|
||||
SDK1.7.7
|
||||
1 增加SDK分享小程序
|
||||
2 增加选择发票接口
|
||||
|
||||
SDK1.7.6
|
||||
1. 提高稳定性
|
||||
1 修复mta崩溃
|
||||
2 新增接口支持开发者关闭mta数据统计上报
|
||||
|
||||
SDK1.7.5
|
||||
1. 提高稳定性
|
||||
2. 加快registerApp接口启动速度
|
||||
|
||||
SDK1.7.4
|
||||
1. 更新支持iOS启用 ATS(App Transport Security)
|
||||
2. 需要在工程中链接CFNetwork.framework
|
||||
3. 在工程配置中的”Other Linker Flags”中加入”-Objc -all_load”
|
||||
|
||||
SDK1.7.3
|
||||
1. 增强稳定性,适配iOS10
|
||||
2. 修复小于32K的jpg格式缩略图设置失败的问题
|
||||
|
||||
SDK1.7.2
|
||||
1. 修复因CTTeleponyNetworkInfo引起的崩溃问题
|
||||
|
||||
SDK1.7.1
|
||||
1. 支持兼容ipv6(提升稳定性)
|
||||
2. xCode Version 7.3.1 (7D1014) 编译
|
||||
|
||||
SDK1.7
|
||||
1. 支持兼容ipv6
|
||||
2. 修复若干问题增强稳定性
|
||||
|
||||
SDK1.6.3
|
||||
1. xCode7.2 构建的sdk包。
|
||||
2. 请使用xCode7.2进行编译。
|
||||
3. 需要在Build Phases中Link Security.framework
|
||||
4. 修复若干小问题。
|
||||
|
||||
SDK1.6.2
|
||||
1、xCode7.1 构建的sdk包
|
||||
2、请使用xCode7.1进行编译
|
||||
|
||||
SDK1.6.1
|
||||
1、修复armv7s下,bitcode可能编译不过
|
||||
2、解决warning
|
||||
|
||||
SDK1.6
|
||||
1、iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装。
|
||||
受此影响,当你的应用在iOS 9中需要使用微信SDK的相关能力(分享、收藏、支付、登录等)时,需要在“Info.plist”里增加如下代码:
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>weixin</string>
|
||||
</array>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
2、开发者需要在工程中链接上 CoreTelephony.framework
|
||||
3、解决bitcode编译不过问题
|
||||
|
||||
SDK1.5
|
||||
1、废弃safeSendReq:接口,使用sendReq:即可。
|
||||
2、新增+(BOOL) sendAuthReq:(SendAuthReq*) req viewController : (UIViewController*) viewController delegate:(id<WXApiDelegate>) delegate;
|
||||
支持未安装微信情况下Auth,具体见WXApi.h接口描述
|
||||
3、微信开放平台新增了微信模块用户统计功能,便于开发者统计微信功能模块的用户使用和活跃情况。开发者需要在工程中链接上:SystemConfiguration.framework,libz.dylib,libsqlite3.0.dylib。
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
//
|
||||
// WXApi.h
|
||||
// 所有Api接口
|
||||
//
|
||||
// Created by Wechat on 12-2-28.
|
||||
// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "WXApiObject.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
typedef BOOL(^WXGrantReadPasteBoardPermissionCompletion)(void);
|
||||
|
||||
|
||||
#pragma mark - WXApiDelegate
|
||||
/*! @brief 接收并处理来自微信终端程序的事件消息
|
||||
*
|
||||
* 接收并处理来自微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。
|
||||
* WXApiDelegate 会在handleOpenURL:delegate:中使用并触发。
|
||||
*/
|
||||
@protocol WXApiDelegate <NSObject>
|
||||
@optional
|
||||
|
||||
/*! @brief 收到一个来自微信的请求,第三方应用程序处理完后调用sendResp向微信发送结果
|
||||
*
|
||||
* 收到一个来自微信的请求,异步处理完成后必须调用sendResp发送处理结果给微信。
|
||||
* 可能收到的请求有GetMessageFromWXReq、ShowMessageFromWXReq等。
|
||||
* @param req 具体请求内容,是自动释放的
|
||||
*/
|
||||
- (void)onReq:(BaseReq*)req;
|
||||
|
||||
|
||||
|
||||
/*! @brief 发送一个sendReq后,收到微信的回应
|
||||
*
|
||||
* 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。
|
||||
* 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。
|
||||
* @param resp具体的回应内容,是自动释放的
|
||||
*/
|
||||
- (void)onResp:(BaseResp*)resp;
|
||||
|
||||
/* ! @brief 用于在iOS16以及以上系统上,控制OpenSDK是否读取剪切板中微信传递的数据以及读取的时机
|
||||
* 在iOS16以及以上系统,在SDK需要读取剪切板中微信写入的数据时,会回调该方法。没有实现默认会直接读取微信通过剪切板传递过来的数据
|
||||
* 注意:
|
||||
* 1. 只在iOS16以及以上的系统版本上回调;
|
||||
* 2. 不实现时,OpenSDK会直接调用读取剪切板接口,读取微信传递过来的数据;
|
||||
* 3. 若实现该方法:开发者需要通过调用completion(), 支持异步,通知SDK允许读取剪切板中微信传递的数据,
|
||||
* 不调用completion()则代表不授权OpenSDK读取剪切板,会导致收不到onReq:, onResp:回调,无法后续业务流程。请谨慎使用
|
||||
* 4. 不要长时间持有completion不释放,可能会导致内存泄漏。
|
||||
*/
|
||||
- (void)onNeedGrantReadPasteBoardPermissionWithURL:(nonnull NSURL *)openURL completion:(nonnull WXGrantReadPasteBoardPermissionCompletion)completion;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - WXApiLogDelegate
|
||||
|
||||
@protocol WXApiLogDelegate <NSObject>
|
||||
|
||||
- (void)onLog:(NSString*)log logLevel:(WXLogLevel)level;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - WXApi
|
||||
|
||||
/*! @brief 微信Api接口函数类
|
||||
*
|
||||
* 该类封装了微信终端SDK的所有接口
|
||||
*/
|
||||
@interface WXApi : NSObject
|
||||
|
||||
/*! @brief WXApi的成员函数,向微信终端程序注册第三方应用。
|
||||
*
|
||||
* 需要在每次启动第三方应用程序时调用。
|
||||
* @attention 请保证在主线程中调用此函数
|
||||
* @param appid 微信开发者ID
|
||||
* @param universalLink 微信开发者Universal Link
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
+ (BOOL)registerApp:(NSString *)appid universalLink:(NSString *)universalLink;
|
||||
|
||||
|
||||
/*! @brief 处理旧版微信通过URL启动App时传递的数据
|
||||
*
|
||||
* 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。
|
||||
* @param url 微信启动第三方应用时传递过来的URL
|
||||
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
+ (BOOL)handleOpenURL:(NSURL *)url delegate:(nullable id<WXApiDelegate>)delegate;
|
||||
|
||||
|
||||
/*! @brief 处理微信通过Universal Link启动App时传递的数据
|
||||
*
|
||||
* 需要在 application:continueUserActivity:restorationHandler:中调用。
|
||||
* @param userActivity 微信启动第三方应用时系统API传递过来的userActivity
|
||||
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
+ (BOOL)handleOpenUniversalLink:(NSUserActivity *)userActivity delegate:(nullable id<WXApiDelegate>)delegate;
|
||||
|
||||
|
||||
/*! @brief 检查微信是否已被用户安装
|
||||
*
|
||||
* @return 微信已安装返回YES,未安装返回NO。
|
||||
*/
|
||||
+ (BOOL)isWXAppInstalled;
|
||||
|
||||
|
||||
|
||||
/*! @brief 判断当前微信的版本是否支持OpenApi
|
||||
*
|
||||
* @return 支持返回YES,不支持返回NO。
|
||||
*/
|
||||
+ (BOOL)isWXAppSupportApi;
|
||||
|
||||
|
||||
/*! @brief 判断当前微信的版本是否支持分享微信状态功能
|
||||
*
|
||||
* @attention 需在工程LSApplicationQueriesSchemes配置中添加weixinStateAPI
|
||||
* @return 支持返回YES,不支持返回NO。
|
||||
*/
|
||||
+ (BOOL)isWXAppSupportStateAPI;
|
||||
|
||||
|
||||
#ifndef BUILD_WITHOUT_PAY
|
||||
/*! @brief 判断当前微信的版本是否支持二维码拉起微信支付
|
||||
*
|
||||
* @attention 需在工程LSApplicationQueriesSchemes配置中添加weixinQRCodePayAPI
|
||||
* @return 支持返回YES,不支持返回NO。
|
||||
*/
|
||||
+ (BOOL)isWXAppSupportQRCodePayAPI;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*! @brief 获取微信的itunes安装地址
|
||||
*
|
||||
* @return 微信的安装地址字符串。
|
||||
*/
|
||||
+ (NSString *)getWXAppInstallUrl;
|
||||
|
||||
|
||||
|
||||
/*! @brief 获取当前微信SDK的版本号
|
||||
*
|
||||
* @return 返回当前微信SDK的版本号
|
||||
*/
|
||||
+ (NSString *)getApiVersion;
|
||||
|
||||
|
||||
|
||||
/*! @brief 打开微信
|
||||
*
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
+ (BOOL)openWXApp;
|
||||
|
||||
|
||||
|
||||
/*! @brief 发送请求到微信,等待微信返回onResp
|
||||
*
|
||||
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型
|
||||
* SendAuthReq、SendMessageToWXReq、PayReq等。
|
||||
* @param req 具体的发送请求。
|
||||
* @param completion 调用结果回调block
|
||||
*/
|
||||
+ (void)sendReq:(BaseReq *)req completion:(void (^ __nullable)(BOOL success))completion;
|
||||
|
||||
/*! @brief 收到微信onReq的请求,发送对应的应答给微信,并切换到微信界面
|
||||
*
|
||||
* 函数调用后,会切换到微信的界面。第三方应用程序收到微信onReq的请求,异步处理该请求,完成后必须调用该函数。可能发送的相应有
|
||||
* GetMessageFromWXResp、ShowMessageFromWXResp等。
|
||||
* @param resp 具体的应答内容
|
||||
* @param completion 调用结果回调block
|
||||
*/
|
||||
+ (void)sendResp:(BaseResp*)resp completion:(void (^ __nullable)(BOOL success))completion;
|
||||
|
||||
|
||||
/*! @brief 发送Auth请求到微信,支持用户没安装微信,等待微信返回onResp
|
||||
*
|
||||
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持SendAuthReq类型。
|
||||
* @param req 具体的发送请求。
|
||||
* @param viewController 当前界面对象。
|
||||
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||
* @param completion 调用结果回调block
|
||||
*/
|
||||
+ (void)sendAuthReq:(SendAuthReq *)req viewController:(UIViewController*)viewController delegate:(nullable id<WXApiDelegate>)delegate completion:(void (^ __nullable)(BOOL success))completion;
|
||||
|
||||
|
||||
/*! @brief 测试函数,用于排查当前App通过Universal Link方式分享到微信的流程
|
||||
注意1: 调用自检函数之前必须要先调用registerApp:universalLink接口, 并确认调用成功
|
||||
注意2: 自检过程中会有Log产生,可以先调用startLogByLevel函数,根据Log排查问题
|
||||
注意3: 会多次回调block
|
||||
注意4: 仅用于新接入SDK时调试使用,请勿在正式环境的调用
|
||||
*
|
||||
* 当completion回调的step为WXULCheckStepFinal时,表示检测通过,Universal Link接入成功
|
||||
* @param completion 回调Block
|
||||
*/
|
||||
+ (void)checkUniversalLinkReady:(nonnull WXCheckULCompletion)completion;
|
||||
|
||||
|
||||
/*! @brief WXApi的成员函数,接受微信的log信息。byBlock
|
||||
注意1:SDK会强引用这个block,注意不要导致内存泄漏,注意不要导致内存泄漏
|
||||
注意2:调用过一次startLog by block之后,如果再调用一次任意方式的startLoad,会释放上一次logBlock,不再回调上一个logBlock
|
||||
*
|
||||
* @param level 打印log的级别
|
||||
* @param logBlock 打印log的回调block
|
||||
*/
|
||||
|
||||
+ (void)startLogByLevel:(WXLogLevel)level logBlock:(WXLogBolock)logBlock;
|
||||
|
||||
/*! @brief WXApi的成员函数,接受微信的log信息。byDelegate
|
||||
注意1:sdk会弱引用这个delegate,这里可加任意对象为代理,不需要与WXApiDelegate同一个对象
|
||||
注意2:调用过一次startLog by delegate之后,再调用一次任意方式的startLoad,不会再回调上一个logDelegate对象
|
||||
* @param level 打印log的级别
|
||||
* @param logDelegate 打印log的回调代理,
|
||||
*/
|
||||
+ (void)startLogByLevel:(WXLogLevel)level logDelegate:(id<WXApiLogDelegate>)logDelegate;
|
||||
|
||||
/*! @brief 停止打印log,会清理block或者delegate为空,释放block
|
||||
* @param
|
||||
*/
|
||||
+ (void)stopLog;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+1410
File diff suppressed because it is too large
Load Diff
+68
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// WechatAuthSDK.h
|
||||
// WechatAuthSDK
|
||||
//
|
||||
// Created by 李凯 on 13-11-29.
|
||||
// Copyright (c) 2013年 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
enum AuthErrCode {
|
||||
WechatAuth_Err_Ok = 0, //Auth成功
|
||||
WechatAuth_Err_NormalErr = -1, //普通错误
|
||||
WechatAuth_Err_NetworkErr = -2, //网络错误
|
||||
WechatAuth_Err_GetQrcodeFailed = -3, //获取二维码失败
|
||||
WechatAuth_Err_Cancel = -4, //用户取消授权
|
||||
WechatAuth_Err_Timeout = -5, //超时
|
||||
};
|
||||
|
||||
@protocol WechatAuthAPIDelegate<NSObject>
|
||||
@optional
|
||||
|
||||
- (void)onAuthGotQrcode:(UIImage *)image; //得到二维码
|
||||
- (void)onQrcodeScanned; //二维码被扫描
|
||||
- (void)onAuthFinish:(int)errCode AuthCode:(nullable NSString *)authCode; //成功登录
|
||||
|
||||
@end
|
||||
|
||||
@interface WechatAuthSDK : NSObject{
|
||||
NSString *_sdkVersion;
|
||||
__weak id<WechatAuthAPIDelegate> _delegate;
|
||||
}
|
||||
|
||||
@property(nonatomic, weak, nullable) id<WechatAuthAPIDelegate> delegate;
|
||||
@property(nonatomic, readonly) NSString *sdkVersion; //authSDK版本号
|
||||
|
||||
/*! @brief 发送登录请求,等待WechatAuthAPIDelegate回调
|
||||
*
|
||||
* @param appId 微信开发者ID
|
||||
* @param nonceStr 一个随机的尽量不重复的字符串,用来使得每次的signature不同
|
||||
* @param timeStamp 时间戳
|
||||
* @param scope 应用授权作用域,拥有多个作用域用逗号(,)分隔
|
||||
* @param signature 签名
|
||||
* @param schemeData 会在扫码后拼在scheme后
|
||||
* @return 成功返回YES,失败返回NO
|
||||
注:该实现只保证同时只有一个Auth在运行,Auth未完成或未Stop再次调用Auth接口时会返回NO。
|
||||
*/
|
||||
|
||||
- (BOOL)Auth:(NSString *)appId
|
||||
nonceStr:(NSString *)nonceStr
|
||||
timeStamp:(NSString *)timeStamp
|
||||
scope:(NSString *)scope
|
||||
signature:(NSString *)signature
|
||||
schemeData:(nullable NSString *)schemeData;
|
||||
|
||||
|
||||
/*! @brief 暂停登录请求
|
||||
*
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
- (BOOL)StopAuth;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// WechatOpenSDK.h
|
||||
//
|
||||
// Created by Wechat.
|
||||
// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||
//
|
||||
#import <WechatOpenSDK/WXApi.h>
|
||||
#import <WechatOpenSDK/WXApiObject.h>
|
||||
#import <WechatOpenSDK/WechatAuthSDK.h>
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.tencent.WechatOpenSDK</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>12.0</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>WechatOpenSDK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
framework module WechatOpenSDK {
|
||||
umbrella header "WechatOpenSDK.h"
|
||||
export *
|
||||
link "WechatOpenSDK"
|
||||
}
|
||||
BIN
Binary file not shown.
+231
@@ -0,0 +1,231 @@
|
||||
//
|
||||
// WXApi.h
|
||||
// 所有Api接口
|
||||
//
|
||||
// Created by Wechat on 12-2-28.
|
||||
// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "WXApiObject.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
typedef BOOL(^WXGrantReadPasteBoardPermissionCompletion)(void);
|
||||
|
||||
|
||||
#pragma mark - WXApiDelegate
|
||||
/*! @brief 接收并处理来自微信终端程序的事件消息
|
||||
*
|
||||
* 接收并处理来自微信终端程序的事件消息,期间微信界面会切换到第三方应用程序。
|
||||
* WXApiDelegate 会在handleOpenURL:delegate:中使用并触发。
|
||||
*/
|
||||
@protocol WXApiDelegate <NSObject>
|
||||
@optional
|
||||
|
||||
/*! @brief 收到一个来自微信的请求,第三方应用程序处理完后调用sendResp向微信发送结果
|
||||
*
|
||||
* 收到一个来自微信的请求,异步处理完成后必须调用sendResp发送处理结果给微信。
|
||||
* 可能收到的请求有GetMessageFromWXReq、ShowMessageFromWXReq等。
|
||||
* @param req 具体请求内容,是自动释放的
|
||||
*/
|
||||
- (void)onReq:(BaseReq*)req;
|
||||
|
||||
|
||||
|
||||
/*! @brief 发送一个sendReq后,收到微信的回应
|
||||
*
|
||||
* 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。
|
||||
* 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。
|
||||
* @param resp具体的回应内容,是自动释放的
|
||||
*/
|
||||
- (void)onResp:(BaseResp*)resp;
|
||||
|
||||
/* ! @brief 用于在iOS16以及以上系统上,控制OpenSDK是否读取剪切板中微信传递的数据以及读取的时机
|
||||
* 在iOS16以及以上系统,在SDK需要读取剪切板中微信写入的数据时,会回调该方法。没有实现默认会直接读取微信通过剪切板传递过来的数据
|
||||
* 注意:
|
||||
* 1. 只在iOS16以及以上的系统版本上回调;
|
||||
* 2. 不实现时,OpenSDK会直接调用读取剪切板接口,读取微信传递过来的数据;
|
||||
* 3. 若实现该方法:开发者需要通过调用completion(), 支持异步,通知SDK允许读取剪切板中微信传递的数据,
|
||||
* 不调用completion()则代表不授权OpenSDK读取剪切板,会导致收不到onReq:, onResp:回调,无法后续业务流程。请谨慎使用
|
||||
* 4. 不要长时间持有completion不释放,可能会导致内存泄漏。
|
||||
*/
|
||||
- (void)onNeedGrantReadPasteBoardPermissionWithURL:(nonnull NSURL *)openURL completion:(nonnull WXGrantReadPasteBoardPermissionCompletion)completion;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - WXApiLogDelegate
|
||||
|
||||
@protocol WXApiLogDelegate <NSObject>
|
||||
|
||||
- (void)onLog:(NSString*)log logLevel:(WXLogLevel)level;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - WXApi
|
||||
|
||||
/*! @brief 微信Api接口函数类
|
||||
*
|
||||
* 该类封装了微信终端SDK的所有接口
|
||||
*/
|
||||
@interface WXApi : NSObject
|
||||
|
||||
/*! @brief WXApi的成员函数,向微信终端程序注册第三方应用。
|
||||
*
|
||||
* 需要在每次启动第三方应用程序时调用。
|
||||
* @attention 请保证在主线程中调用此函数
|
||||
* @param appid 微信开发者ID
|
||||
* @param universalLink 微信开发者Universal Link
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
+ (BOOL)registerApp:(NSString *)appid universalLink:(NSString *)universalLink;
|
||||
|
||||
|
||||
/*! @brief 处理旧版微信通过URL启动App时传递的数据
|
||||
*
|
||||
* 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。
|
||||
* @param url 微信启动第三方应用时传递过来的URL
|
||||
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
+ (BOOL)handleOpenURL:(NSURL *)url delegate:(nullable id<WXApiDelegate>)delegate;
|
||||
|
||||
|
||||
/*! @brief 处理微信通过Universal Link启动App时传递的数据
|
||||
*
|
||||
* 需要在 application:continueUserActivity:restorationHandler:中调用。
|
||||
* @param userActivity 微信启动第三方应用时系统API传递过来的userActivity
|
||||
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
+ (BOOL)handleOpenUniversalLink:(NSUserActivity *)userActivity delegate:(nullable id<WXApiDelegate>)delegate;
|
||||
|
||||
|
||||
/*! @brief 检查微信是否已被用户安装
|
||||
*
|
||||
* @return 微信已安装返回YES,未安装返回NO。
|
||||
*/
|
||||
+ (BOOL)isWXAppInstalled;
|
||||
|
||||
|
||||
|
||||
/*! @brief 判断当前微信的版本是否支持OpenApi
|
||||
*
|
||||
* @return 支持返回YES,不支持返回NO。
|
||||
*/
|
||||
+ (BOOL)isWXAppSupportApi;
|
||||
|
||||
|
||||
/*! @brief 判断当前微信的版本是否支持分享微信状态功能
|
||||
*
|
||||
* @attention 需在工程LSApplicationQueriesSchemes配置中添加weixinStateAPI
|
||||
* @return 支持返回YES,不支持返回NO。
|
||||
*/
|
||||
+ (BOOL)isWXAppSupportStateAPI;
|
||||
|
||||
|
||||
#ifndef BUILD_WITHOUT_PAY
|
||||
/*! @brief 判断当前微信的版本是否支持二维码拉起微信支付
|
||||
*
|
||||
* @attention 需在工程LSApplicationQueriesSchemes配置中添加weixinQRCodePayAPI
|
||||
* @return 支持返回YES,不支持返回NO。
|
||||
*/
|
||||
+ (BOOL)isWXAppSupportQRCodePayAPI;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*! @brief 获取微信的itunes安装地址
|
||||
*
|
||||
* @return 微信的安装地址字符串。
|
||||
*/
|
||||
+ (NSString *)getWXAppInstallUrl;
|
||||
|
||||
|
||||
|
||||
/*! @brief 获取当前微信SDK的版本号
|
||||
*
|
||||
* @return 返回当前微信SDK的版本号
|
||||
*/
|
||||
+ (NSString *)getApiVersion;
|
||||
|
||||
|
||||
|
||||
/*! @brief 打开微信
|
||||
*
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
+ (BOOL)openWXApp;
|
||||
|
||||
|
||||
|
||||
/*! @brief 发送请求到微信,等待微信返回onResp
|
||||
*
|
||||
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型
|
||||
* SendAuthReq、SendMessageToWXReq、PayReq等。
|
||||
* @param req 具体的发送请求。
|
||||
* @param completion 调用结果回调block
|
||||
*/
|
||||
+ (void)sendReq:(BaseReq *)req completion:(void (^ __nullable)(BOOL success))completion;
|
||||
|
||||
/*! @brief 收到微信onReq的请求,发送对应的应答给微信,并切换到微信界面
|
||||
*
|
||||
* 函数调用后,会切换到微信的界面。第三方应用程序收到微信onReq的请求,异步处理该请求,完成后必须调用该函数。可能发送的相应有
|
||||
* GetMessageFromWXResp、ShowMessageFromWXResp等。
|
||||
* @param resp 具体的应答内容
|
||||
* @param completion 调用结果回调block
|
||||
*/
|
||||
+ (void)sendResp:(BaseResp*)resp completion:(void (^ __nullable)(BOOL success))completion;
|
||||
|
||||
|
||||
/*! @brief 发送Auth请求到微信,支持用户没安装微信,等待微信返回onResp
|
||||
*
|
||||
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持SendAuthReq类型。
|
||||
* @param req 具体的发送请求。
|
||||
* @param viewController 当前界面对象。
|
||||
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
|
||||
* @param completion 调用结果回调block
|
||||
*/
|
||||
+ (void)sendAuthReq:(SendAuthReq *)req viewController:(UIViewController*)viewController delegate:(nullable id<WXApiDelegate>)delegate completion:(void (^ __nullable)(BOOL success))completion;
|
||||
|
||||
|
||||
/*! @brief 测试函数,用于排查当前App通过Universal Link方式分享到微信的流程
|
||||
注意1: 调用自检函数之前必须要先调用registerApp:universalLink接口, 并确认调用成功
|
||||
注意2: 自检过程中会有Log产生,可以先调用startLogByLevel函数,根据Log排查问题
|
||||
注意3: 会多次回调block
|
||||
注意4: 仅用于新接入SDK时调试使用,请勿在正式环境的调用
|
||||
*
|
||||
* 当completion回调的step为WXULCheckStepFinal时,表示检测通过,Universal Link接入成功
|
||||
* @param completion 回调Block
|
||||
*/
|
||||
+ (void)checkUniversalLinkReady:(nonnull WXCheckULCompletion)completion;
|
||||
|
||||
|
||||
/*! @brief WXApi的成员函数,接受微信的log信息。byBlock
|
||||
注意1:SDK会强引用这个block,注意不要导致内存泄漏,注意不要导致内存泄漏
|
||||
注意2:调用过一次startLog by block之后,如果再调用一次任意方式的startLoad,会释放上一次logBlock,不再回调上一个logBlock
|
||||
*
|
||||
* @param level 打印log的级别
|
||||
* @param logBlock 打印log的回调block
|
||||
*/
|
||||
|
||||
+ (void)startLogByLevel:(WXLogLevel)level logBlock:(WXLogBolock)logBlock;
|
||||
|
||||
/*! @brief WXApi的成员函数,接受微信的log信息。byDelegate
|
||||
注意1:sdk会弱引用这个delegate,这里可加任意对象为代理,不需要与WXApiDelegate同一个对象
|
||||
注意2:调用过一次startLog by delegate之后,再调用一次任意方式的startLoad,不会再回调上一个logDelegate对象
|
||||
* @param level 打印log的级别
|
||||
* @param logDelegate 打印log的回调代理,
|
||||
*/
|
||||
+ (void)startLogByLevel:(WXLogLevel)level logDelegate:(id<WXApiLogDelegate>)logDelegate;
|
||||
|
||||
/*! @brief 停止打印log,会清理block或者delegate为空,释放block
|
||||
* @param
|
||||
*/
|
||||
+ (void)stopLog;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+1410
File diff suppressed because it is too large
Load Diff
+68
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// WechatAuthSDK.h
|
||||
// WechatAuthSDK
|
||||
//
|
||||
// Created by 李凯 on 13-11-29.
|
||||
// Copyright (c) 2013年 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
enum AuthErrCode {
|
||||
WechatAuth_Err_Ok = 0, //Auth成功
|
||||
WechatAuth_Err_NormalErr = -1, //普通错误
|
||||
WechatAuth_Err_NetworkErr = -2, //网络错误
|
||||
WechatAuth_Err_GetQrcodeFailed = -3, //获取二维码失败
|
||||
WechatAuth_Err_Cancel = -4, //用户取消授权
|
||||
WechatAuth_Err_Timeout = -5, //超时
|
||||
};
|
||||
|
||||
@protocol WechatAuthAPIDelegate<NSObject>
|
||||
@optional
|
||||
|
||||
- (void)onAuthGotQrcode:(UIImage *)image; //得到二维码
|
||||
- (void)onQrcodeScanned; //二维码被扫描
|
||||
- (void)onAuthFinish:(int)errCode AuthCode:(nullable NSString *)authCode; //成功登录
|
||||
|
||||
@end
|
||||
|
||||
@interface WechatAuthSDK : NSObject{
|
||||
NSString *_sdkVersion;
|
||||
__weak id<WechatAuthAPIDelegate> _delegate;
|
||||
}
|
||||
|
||||
@property(nonatomic, weak, nullable) id<WechatAuthAPIDelegate> delegate;
|
||||
@property(nonatomic, readonly) NSString *sdkVersion; //authSDK版本号
|
||||
|
||||
/*! @brief 发送登录请求,等待WechatAuthAPIDelegate回调
|
||||
*
|
||||
* @param appId 微信开发者ID
|
||||
* @param nonceStr 一个随机的尽量不重复的字符串,用来使得每次的signature不同
|
||||
* @param timeStamp 时间戳
|
||||
* @param scope 应用授权作用域,拥有多个作用域用逗号(,)分隔
|
||||
* @param signature 签名
|
||||
* @param schemeData 会在扫码后拼在scheme后
|
||||
* @return 成功返回YES,失败返回NO
|
||||
注:该实现只保证同时只有一个Auth在运行,Auth未完成或未Stop再次调用Auth接口时会返回NO。
|
||||
*/
|
||||
|
||||
- (BOOL)Auth:(NSString *)appId
|
||||
nonceStr:(NSString *)nonceStr
|
||||
timeStamp:(NSString *)timeStamp
|
||||
scope:(NSString *)scope
|
||||
signature:(NSString *)signature
|
||||
schemeData:(nullable NSString *)schemeData;
|
||||
|
||||
|
||||
/*! @brief 暂停登录请求
|
||||
*
|
||||
* @return 成功返回YES,失败返回NO。
|
||||
*/
|
||||
- (BOOL)StopAuth;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// WechatOpenSDK.h
|
||||
//
|
||||
// Created by Wechat.
|
||||
// Copyright (c) 2012年 Tencent. All rights reserved.
|
||||
//
|
||||
#import <WechatOpenSDK/WXApi.h>
|
||||
#import <WechatOpenSDK/WXApiObject.h>
|
||||
#import <WechatOpenSDK/WechatAuthSDK.h>
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.tencent.WechatOpenSDK</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>12.0</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>WechatOpenSDK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
framework module WechatOpenSDK {
|
||||
umbrella header "WechatOpenSDK.h"
|
||||
export *
|
||||
link "WechatOpenSDK"
|
||||
}
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// XJWeChatManager.h
|
||||
// XinjiangProject
|
||||
//
|
||||
// 微信分享管理类(手动集成 WechatOpenSDK-NoPay)
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// 微信分享结果回调
|
||||
typedef void(^XJWeChatShareCompletion)(BOOL success, NSString *_Nullable errorMsg);
|
||||
|
||||
@interface XJWeChatManager : NSObject
|
||||
|
||||
+ (instancetype)sharedManager;
|
||||
|
||||
#pragma mark - 注册
|
||||
/// 注册微信 SDK(需在 AppDelegate didFinishLaunching 中调用)
|
||||
/// @param appID 微信开放平台 AppID
|
||||
/// @param universalLink 通用链接
|
||||
- (BOOL)registerWithAppID:(NSString *)appID universalLink:(NSString *)universalLink;
|
||||
|
||||
/// 处理微信 URL 回调(AppDelegate handleOpenURL 中调用)
|
||||
- (BOOL)handleOpenURL:(NSURL *)url;
|
||||
|
||||
/// 处理微信 Universal Link 回调(AppDelegate continueUserActivity 中调用)
|
||||
- (BOOL)handleOpenUniversalLink:(NSUserActivity *)userActivity;
|
||||
|
||||
#pragma mark - 分享
|
||||
/// 分享文字
|
||||
- (void)shareText:(NSString *)text
|
||||
toScene:(int)scene
|
||||
completion:(XJWeChatShareCompletion _Nullable)completion;
|
||||
|
||||
/// 分享图片(NSData)
|
||||
- (void)shareImageData:(NSData *)imageData
|
||||
toScene:(int)scene
|
||||
completion:(XJWeChatShareCompletion _Nullable)completion;
|
||||
|
||||
/// 分享网页
|
||||
/// @param title 标题
|
||||
/// @param desc 描述
|
||||
/// @param webpageUrl 网页链接
|
||||
/// @param thumbImage 缩略图(不超过 32KB)
|
||||
/// @param scene 分享目标:WXSceneSession=好友, WXSceneTimeline=朋友圈
|
||||
- (void)shareWebpageWithTitle:(NSString *)title
|
||||
desc:(NSString *)desc
|
||||
webpageUrl:(NSString *)webpageUrl
|
||||
thumbImage:(UIImage *_Nullable)thumbImage
|
||||
toScene:(int)scene
|
||||
completion:(XJWeChatShareCompletion _Nullable)completion;
|
||||
|
||||
/// 分享小程序卡片
|
||||
/// @param title 标题
|
||||
/// @param desc 描述
|
||||
/// @param webpageUrl 兼容低版本网页链接
|
||||
/// @param userName 小程序原始ID(gh_ 开头)
|
||||
/// @param path 小程序页面路径
|
||||
/// @param miniProgramType 小程序类型:0=正式版, 1=开发版, 2=体验版
|
||||
- (void)shareMiniProgramWithTitle:(NSString *)title
|
||||
desc:(NSString *)desc
|
||||
webpageUrl:(NSString *)webpageUrl
|
||||
userName:(NSString *)userName
|
||||
path:(NSString *)path
|
||||
miniProgramType:(NSUInteger)miniProgramType
|
||||
thumbImage:(UIImage *_Nullable)thumbImage
|
||||
completion:(XJWeChatShareCompletion _Nullable)completion;
|
||||
|
||||
#pragma mark - 工具
|
||||
/// 是否安装微信
|
||||
- (BOOL)isWeChatInstalled;
|
||||
|
||||
/// 微信是否支持 OpenAPI
|
||||
- (BOOL)isWeChatSupportApi;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// XJWeChatManager.m
|
||||
// XinjiangProject
|
||||
//
|
||||
// 微信分享管理类
|
||||
//
|
||||
|
||||
#import "XJWeChatManager.h"
|
||||
#import <WechatOpenSDK/WXApi.h>
|
||||
|
||||
@interface XJWeChatManager () <WXApiDelegate>
|
||||
@property (nonatomic, copy) XJWeChatShareCompletion shareCompletion;
|
||||
@end
|
||||
|
||||
@implementation XJWeChatManager
|
||||
|
||||
#pragma mark - ————— 单例 —————
|
||||
+ (instancetype)sharedManager {
|
||||
static XJWeChatManager *instance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[XJWeChatManager alloc] init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
#pragma mark - ————— 注册 —————
|
||||
- (BOOL)registerWithAppID:(NSString *)appID universalLink:(NSString *)universalLink {
|
||||
return [WXApi registerApp:appID universalLink:universalLink];
|
||||
}
|
||||
|
||||
- (BOOL)handleOpenURL:(NSURL *)url {
|
||||
return [WXApi handleOpenURL:url delegate:self];
|
||||
}
|
||||
|
||||
- (BOOL)handleOpenUniversalLink:(NSUserActivity *)userActivity {
|
||||
return [WXApi handleOpenUniversalLink:userActivity delegate:self];
|
||||
}
|
||||
|
||||
#pragma mark - ————— 分享 —————
|
||||
- (void)shareText:(NSString *)text
|
||||
toScene:(int)scene
|
||||
completion:(XJWeChatShareCompletion)completion {
|
||||
self.shareCompletion = completion;
|
||||
|
||||
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
|
||||
req.bText = YES;
|
||||
req.text = text;
|
||||
req.scene = scene;
|
||||
|
||||
[WXApi sendReq:req completion:nil];
|
||||
}
|
||||
|
||||
- (void)shareImageData:(NSData *)imageData
|
||||
toScene:(int)scene
|
||||
completion:(XJWeChatShareCompletion)completion {
|
||||
self.shareCompletion = completion;
|
||||
|
||||
WXMediaMessage *message = [WXMediaMessage message];
|
||||
message.thumbData = nil;
|
||||
|
||||
WXImageObject *imageObject = [WXImageObject object];
|
||||
imageObject.imageData = imageData;
|
||||
message.mediaObject = imageObject;
|
||||
|
||||
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
|
||||
req.bText = NO;
|
||||
req.message = message;
|
||||
req.scene = scene;
|
||||
|
||||
[WXApi sendReq:req completion:nil];
|
||||
}
|
||||
|
||||
- (void)shareWebpageWithTitle:(NSString *)title
|
||||
desc:(NSString *)desc
|
||||
webpageUrl:(NSString *)webpageUrl
|
||||
thumbImage:(UIImage *)thumbImage
|
||||
toScene:(int)scene
|
||||
completion:(XJWeChatShareCompletion)completion {
|
||||
self.shareCompletion = completion;
|
||||
|
||||
WXMediaMessage *message = [WXMediaMessage message];
|
||||
message.title = title;
|
||||
message.description = desc;
|
||||
|
||||
if (thumbImage) {
|
||||
message.thumbData = UIImageJPEGRepresentation(thumbImage, 0.5);
|
||||
}
|
||||
|
||||
WXWebpageObject *webpageObject = [WXWebpageObject object];
|
||||
webpageObject.webpageUrl = webpageUrl;
|
||||
message.mediaObject = webpageObject;
|
||||
|
||||
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
|
||||
req.bText = NO;
|
||||
req.message = message;
|
||||
req.scene = scene;
|
||||
|
||||
[WXApi sendReq:req completion:nil];
|
||||
}
|
||||
|
||||
- (void)shareMiniProgramWithTitle:(NSString *)title
|
||||
desc:(NSString *)desc
|
||||
webpageUrl:(NSString *)webpageUrl
|
||||
userName:(NSString *)userName
|
||||
path:(NSString *)path
|
||||
miniProgramType:(NSUInteger)miniProgramType
|
||||
thumbImage:(UIImage *)thumbImage
|
||||
completion:(XJWeChatShareCompletion)completion {
|
||||
self.shareCompletion = completion;
|
||||
|
||||
WXMediaMessage *message = [WXMediaMessage message];
|
||||
message.title = title;
|
||||
message.description = desc;
|
||||
|
||||
if (thumbImage) {
|
||||
message.thumbData = UIImageJPEGRepresentation(thumbImage, 0.5);
|
||||
}
|
||||
|
||||
WXMiniProgramObject *miniProgramObject = [WXMiniProgramObject object];
|
||||
miniProgramObject.webpageUrl = webpageUrl;
|
||||
miniProgramObject.userName = userName;
|
||||
miniProgramObject.path = path;
|
||||
miniProgramObject.miniProgramType = miniProgramType;
|
||||
message.mediaObject = miniProgramObject;
|
||||
|
||||
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
|
||||
req.bText = NO;
|
||||
req.message = message;
|
||||
req.scene = WXSceneSession;
|
||||
|
||||
[WXApi sendReq:req completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - ————— 工具 —————
|
||||
- (BOOL)isWeChatInstalled {
|
||||
return [WXApi isWXAppInstalled];
|
||||
}
|
||||
|
||||
- (BOOL)isWeChatSupportApi {
|
||||
return [WXApi isWXAppSupportApi];
|
||||
}
|
||||
|
||||
#pragma mark - ————— WXApiDelegate —————
|
||||
- (void)onResp:(BaseResp *)resp {
|
||||
if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
|
||||
if (self.shareCompletion) {
|
||||
if (resp.errCode == WXSuccess) {
|
||||
self.shareCompletion(YES, nil);
|
||||
} else if (resp.errCode == WXErrCodeUserCancel) {
|
||||
self.shareCompletion(NO, @"用户取消分享");
|
||||
} else {
|
||||
self.shareCompletion(NO, resp.errStr ?: @"分享失败");
|
||||
}
|
||||
self.shareCompletion = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// XJHealthKnowledgeManager.h
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/6/29.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "XJHealthCategoryModel.h"
|
||||
#import "XJHealthArticleModel.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// 健康知识网络管理器
|
||||
@interface XJHealthKnowledgeManager : NSObject
|
||||
|
||||
+ (instancetype)sharedManager;
|
||||
|
||||
/// 当前 token(获取后缓存)
|
||||
@property (nonatomic, copy, readonly, nullable) NSString * cachedToken;
|
||||
|
||||
/// 清除缓存的 token(退出登录时调用)
|
||||
- (void)clearToken;
|
||||
|
||||
/// 获取 token
|
||||
- (void)getTokenWithUserId:(NSString *)userId
|
||||
workNo:(NSString *)workNo
|
||||
success:(void (^)(NSString * token))success
|
||||
failure:(void (^)(NSString * errorMsg))failure;
|
||||
|
||||
/// 获取栏目列表
|
||||
- (void)getCategoryListWithToken:(NSString *)token
|
||||
success:(void (^)(NSArray<XJHealthCategoryModel *> * categories))success
|
||||
failure:(void (^)(NSString * errorMsg))failure;
|
||||
|
||||
/// 分页查询文章(showAppHomepage 固定 Y)
|
||||
- (void)getArticleListWithToken:(NSString *)token
|
||||
categoryId:(NSInteger)categoryId
|
||||
articleType:(nullable NSString *)articleType
|
||||
pageNum:(NSInteger)pageNum
|
||||
pageSize:(NSInteger)pageSize
|
||||
success:(void (^)(NSArray<XJHealthArticleModel *> * articles, NSInteger total))success
|
||||
failure:(void (^)(NSString * errorMsg))failure;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,222 @@
|
||||
//
|
||||
// XJHealthKnowledgeManager.m
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/6/29.
|
||||
//
|
||||
|
||||
#import "XJHealthKnowledgeManager.h"
|
||||
#import <CommonCrypto/CommonHMAC.h>
|
||||
|
||||
#pragma mark - ————— Manager —————
|
||||
|
||||
@interface XJHealthKnowledgeManager ()
|
||||
|
||||
@property (nonatomic, copy) NSString * cachedToken;
|
||||
|
||||
@end
|
||||
|
||||
@implementation XJHealthKnowledgeManager
|
||||
|
||||
+ (instancetype)sharedManager {
|
||||
static XJHealthKnowledgeManager * instance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[XJHealthKnowledgeManager alloc] init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
#pragma mark - ————— HMAC-SHA256 —————
|
||||
|
||||
- (void)clearToken {
|
||||
self.cachedToken = nil;
|
||||
DLog(@"[健康知识] Token 已清除");
|
||||
}
|
||||
|
||||
+ (NSString *)hmacSHA256:(NSString *)data key:(NSString *)key {
|
||||
const char * cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
const char * cData = [data cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
unsigned char result[CC_SHA256_DIGEST_LENGTH];
|
||||
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), result);
|
||||
|
||||
NSMutableString * hash = [[NSMutableString alloc] initWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
|
||||
for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
|
||||
[hash appendFormat:@"%02x", result[i]];
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
#pragma mark - ————— 获取 Token —————
|
||||
|
||||
- (void)getTokenWithUserId:(NSString *)userId
|
||||
workNo:(NSString *)workNo
|
||||
success:(void (^)(NSString *))success
|
||||
failure:(void (^)(NSString *))failure {
|
||||
|
||||
NSString * urlString = [NSString stringWithFormat:@"%@%@", kHealthKnowledgeBaseURL, kHealthKnowledgeTokenPath];
|
||||
|
||||
// 构建请求体
|
||||
NSDictionary * bodyDict = @{ @"userId": userId ?: @"",
|
||||
@"workNo": workNo ?: @"" };
|
||||
NSData * bodyData = [NSJSONSerialization dataWithJSONObject:bodyDict options:0 error:nil];
|
||||
NSString * bodyString = [[NSString alloc] initWithData:bodyData encoding:NSUTF8StringEncoding];
|
||||
|
||||
// 签名
|
||||
NSString * timestamp = [NSString stringWithFormat:@"%.0f", [[NSDate date] timeIntervalSince1970]];
|
||||
NSString * stringToSign = [NSString stringWithFormat:@"%@%@", timestamp, bodyString];
|
||||
NSString * sign = [[self class] hmacSHA256:stringToSign key:kHealthKnowledgeSecretKey];
|
||||
|
||||
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
|
||||
request.HTTPMethod = @"POST";
|
||||
[request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
|
||||
[request setValue:timestamp forHTTPHeaderField:@"X-Timestamp"];
|
||||
[request setValue:sign forHTTPHeaderField:@"X-Sign"];
|
||||
request.HTTPBody = bodyData;
|
||||
|
||||
DLog(@"[健康知识] 请求 Token URL: %@", urlString);
|
||||
DLog(@"[健康知识] 签名串: %@", stringToSign);
|
||||
DLog(@"[健康知识] X-Sign: %@", sign);
|
||||
|
||||
[self sendRequest:request completion:^(NSDictionary * json) {
|
||||
DLog(@"[健康知识] Token 响应: %@", json);
|
||||
if ([json[@"code"] integerValue] == 200) {
|
||||
NSString * token = json[@"data"][@"token"];
|
||||
if (!ValidStr(token)) {
|
||||
self.cachedToken = token;
|
||||
DLog(@"[健康知识] Token 获取成功: %@", token);
|
||||
if (success) success(token);
|
||||
} else {
|
||||
DLog(@"[健康知识] Token 为空");
|
||||
if (failure) failure(@"token 为空");
|
||||
}
|
||||
} else {
|
||||
DLog(@"[健康知识] Token 失败: %@", json[@"msg"]);
|
||||
if (failure) failure(json[@"msg"] ?: @"获取 token 失败");
|
||||
}
|
||||
} failure:^(NSString * errorMsg) {
|
||||
DLog(@"[健康知识] Token 请求异常: %@", errorMsg);
|
||||
if (failure) failure(errorMsg);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - ————— 栏目列表 —————
|
||||
|
||||
- (void)getCategoryListWithToken:(NSString *)token
|
||||
success:(void (^)(NSArray<XJHealthCategoryModel *> *))success
|
||||
failure:(void (^)(NSString *))failure {
|
||||
|
||||
NSString * urlString = [NSString stringWithFormat:@"%@%@", kHealthKnowledgeBaseURL, kHealthKnowledgeCategoryPath];
|
||||
|
||||
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
|
||||
request.HTTPMethod = @"GET";
|
||||
[request setValue:token forHTTPHeaderField:@"token"];
|
||||
|
||||
[self sendRequest:request completion:^(NSDictionary * json) {
|
||||
if ([json[@"code"] integerValue] == 200) {
|
||||
NSArray * dataArray = json[@"data"];
|
||||
NSMutableArray * categories = [[NSMutableArray alloc] init];
|
||||
if ([dataArray isKindOfClass:[NSArray class]]) {
|
||||
for (NSDictionary * dict in dataArray) {
|
||||
XJHealthCategoryModel * m = [XJHealthCategoryModel modelWithDictionary:dict];
|
||||
[categories addObject:m];
|
||||
}
|
||||
}
|
||||
if (success) success(categories);
|
||||
} else {
|
||||
if (failure) failure(json[@"msg"] ?: @"获取栏目列表失败");
|
||||
}
|
||||
} failure:^(NSString * errorMsg) {
|
||||
if (failure) failure(errorMsg);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - ————— 分页查询文章 —————
|
||||
|
||||
- (void)getArticleListWithToken:(NSString *)token
|
||||
categoryId:(NSInteger)categoryId
|
||||
articleType:(NSString *)articleType
|
||||
pageNum:(NSInteger)pageNum
|
||||
pageSize:(NSInteger)pageSize
|
||||
success:(void (^)(NSArray<XJHealthArticleModel *> *, NSInteger))success
|
||||
failure:(void (^)(NSString *))failure {
|
||||
|
||||
NSMutableString * urlString = [NSMutableString stringWithFormat:@"%@%@", kHealthKnowledgeBaseURL, kHealthKnowledgeArticleListPath];
|
||||
[urlString appendFormat:@"?categoryId=%ld&pageNum=%ld&pageSize=%ld&showAppHomepage=Y",
|
||||
(long)categoryId, (long)pageNum, (long)pageSize];
|
||||
|
||||
if (!ValidStr(articleType)) {
|
||||
[urlString appendFormat:@"&articleType=%@", articleType];
|
||||
}
|
||||
|
||||
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
|
||||
request.HTTPMethod = @"GET";
|
||||
[request setValue:token forHTTPHeaderField:@"token"];
|
||||
|
||||
[self sendRequest:request completion:^(NSDictionary * json) {
|
||||
if ([json[@"code"] integerValue] == 200) {
|
||||
NSArray * rows = json[@"rows"];
|
||||
NSInteger total = [json[@"total"] integerValue];
|
||||
NSMutableArray * articles = [[NSMutableArray alloc] init];
|
||||
if ([rows isKindOfClass:[NSArray class]]) {
|
||||
for (NSDictionary * dict in rows) {
|
||||
XJHealthArticleModel * m = [XJHealthArticleModel modelWithDictionary:dict];
|
||||
[articles addObject:m];
|
||||
}
|
||||
}
|
||||
if (success) success(articles, total);
|
||||
} else {
|
||||
if (failure) failure(json[@"msg"] ?: @"获取文章列表失败");
|
||||
}
|
||||
} failure:^(NSString * errorMsg) {
|
||||
if (failure) failure(errorMsg);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - ————— 通用请求 —————
|
||||
|
||||
- (void)sendRequest:(NSURLRequest *)request
|
||||
completion:(void (^)(NSDictionary * json))completion
|
||||
failure:(void (^)(NSString * errorMsg))failure {
|
||||
|
||||
DLog(@"[健康知识] >>> 请求: %@ %@", request.HTTPMethod, request.URL.absoluteString);
|
||||
|
||||
NSURLSession * session = [NSURLSession sharedSession];
|
||||
NSURLSessionDataTask * task = [session dataTaskWithRequest:request
|
||||
completionHandler:^(NSData * _Nullable data,
|
||||
NSURLResponse * _Nullable response,
|
||||
NSError * _Nullable error) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (error) {
|
||||
DLog(@"[健康知识] <<< 网络错误: %@", error.localizedDescription);
|
||||
if (failure) failure(error.localizedDescription);
|
||||
return;
|
||||
}
|
||||
|
||||
NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response;
|
||||
NSInteger statusCode = httpResp.statusCode;
|
||||
DLog(@"[健康知识] <<< HTTP %ld", (long)statusCode);
|
||||
|
||||
if (statusCode != 200) {
|
||||
NSString * msg = [NSString stringWithFormat:@"HTTP %ld", (long)statusCode];
|
||||
DLog(@"[健康知识] <<< 请求失败: %@", msg);
|
||||
if (failure) failure(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
NSError * jsonError = nil;
|
||||
NSDictionary * json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
|
||||
if (jsonError || ![json isKindOfClass:[NSDictionary class]]) {
|
||||
DLog(@"[健康知识] <<< JSON 解析失败");
|
||||
if (failure) failure(@"数据解析失败");
|
||||
return;
|
||||
}
|
||||
|
||||
DLog(@"[健康知识] <<< 响应: %@", json);
|
||||
if (completion) completion(json);
|
||||
});
|
||||
}];
|
||||
[task resume];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
//初始化服务
|
||||
-(void)initService;
|
||||
- (void)chageUrlService;
|
||||
//初始化 window
|
||||
|
||||
-(void)initWindow;
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
//
|
||||
|
||||
#import "AppDelegate+AppService.h"
|
||||
#import "HQBaseTabBarController.h"
|
||||
#import "HQLoginViewController.h"
|
||||
#import "XJBaseTabBarController.h"
|
||||
//#import "XJLoginViewController.h"
|
||||
#import "XJLoginTopChangeViewController.h"
|
||||
#import <IQKeyboardManager/IQKeyboardManager.h>
|
||||
#import <AMapFoundationKit/AMapFoundationKit.h>
|
||||
|
||||
@@ -33,31 +34,41 @@
|
||||
object:nil];
|
||||
|
||||
|
||||
//切换SOStabbar
|
||||
//切换咨询tabbar
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(tabBarSoSChange:)
|
||||
name:KNotificSelectSoSTabbar
|
||||
selector:@selector(tabBarQuestionChange:)
|
||||
name:KNotificSelectQuestionTabbar
|
||||
object:nil];
|
||||
//切换应急tabbar
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(tabBarSOSChange:)
|
||||
name:KNotificSelectSOSCenterTabbar
|
||||
object:nil];
|
||||
|
||||
//切换体检tabbar
|
||||
//切换监测tabbar
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(tabBarPhyChange:)
|
||||
name:KNotificSelectPhysicalTabbar
|
||||
selector:@selector(tabBarMonitoringChange:)
|
||||
name:KNotificSelectWatchTabbar
|
||||
object:nil];
|
||||
|
||||
//切换档案tabbar
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(tabBarFileChange:)
|
||||
name:KNotificSelectFileTabbar
|
||||
object:nil];
|
||||
|
||||
if ([HQCommonUtils isLogin]) {
|
||||
//腾讯im
|
||||
JKCQAPI * proctocolApi = [[JKCQAPI alloc] init:self tag:@"IMAPI" NeedToken:nil];
|
||||
[proctocolApi GetIMLoginAccount:nil];
|
||||
#if DEBUG
|
||||
[self loginImAccount];
|
||||
|
||||
#else
|
||||
[self loginImAccount];
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)loginImAccount {
|
||||
XJPNetAPI * proctocolApi = [[XJPNetAPI alloc] init:self tag:@"IMAPI" NeedToken:nil];
|
||||
[proctocolApi GetIMLoginAccount:nil];
|
||||
}
|
||||
#pragma mark ————— 初始化window —————
|
||||
-(void)initWindow{
|
||||
|
||||
@@ -65,13 +76,13 @@
|
||||
self.window.backgroundColor = KWhiteColor;
|
||||
//直接进入显示登录页面
|
||||
// if ([HQCommonUtils isLogin]) {
|
||||
self.mainTabBar = [HQBaseTabBarController new];
|
||||
self.mainTabBar = [XJBaseTabBarController new];
|
||||
self.mainTabBar.delegate =self;
|
||||
self.window.rootViewController = self.mainTabBar;
|
||||
[self.window makeKeyAndVisible];
|
||||
// }else {
|
||||
// HQLoginViewController * loginvc = [[HQLoginViewController alloc] init];
|
||||
// HQBaseNavigationController * nav = [[HQBaseNavigationController alloc] initWithRootViewController:loginvc];
|
||||
// XJBaseNavigationController * nav = [[XJBaseNavigationController alloc] initWithRootViewController:loginvc];
|
||||
// self.window.rootViewController = nav;
|
||||
// }
|
||||
// [self.window makeKeyAndVisible];
|
||||
@@ -86,102 +97,6 @@
|
||||
[[TUICallEngine createInstance] addObserver:self];
|
||||
}
|
||||
|
||||
#pragma mark:请求前缀
|
||||
- (void)chageUrlService {
|
||||
|
||||
AFHTTPSessionManager *session=[AFHTTPSessionManager manager];
|
||||
// AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
|
||||
|
||||
session.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html",@"text/plain", nil];
|
||||
//超时时间
|
||||
|
||||
session.requestSerializer.timeoutInterval= 30.f;
|
||||
session.responseSerializer = [AFHTTPResponseSerializer serializer];
|
||||
|
||||
session.requestSerializer = [AFJSONRequestSerializer serializer];
|
||||
|
||||
session.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
|
||||
|
||||
NSMutableDictionary * parmDic = [[NSMutableDictionary alloc] init];
|
||||
|
||||
|
||||
// 获取应用的版本号
|
||||
NSString * version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
|
||||
// 将版本号按照点(.)分割成数组
|
||||
NSArray * components = [version componentsSeparatedByString:@"."];
|
||||
|
||||
// 获取数组中的最后一个元素
|
||||
NSString * lastComponent = [components lastObject];
|
||||
// 如果需要将其转换为整数
|
||||
NSInteger lastNumber = [lastComponent integerValue];
|
||||
|
||||
[parmDic setObject:@(lastNumber) forKey:@"version"];
|
||||
[parmDic setObject:@"com.question.QinghaiProvince" forKey:@"pkg"];
|
||||
[session GET:@"https://base.icdat.cn/v2/url" parameters:parmDic headers:@{@"X-ClientSign":@"Quarry"} progress:^(NSProgress * _Nonnull downloadProgress) {
|
||||
|
||||
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
||||
|
||||
NSString * dataString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
|
||||
DLog(@"response\n%@\n",dataString);
|
||||
NSData *requestData = [dataString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
id myResult = [NSJSONSerialization JSONObjectWithData:requestData options:NSJSONReadingMutableContainers error:nil];
|
||||
//判断是否为字典
|
||||
if ([myResult isKindOfClass:[NSDictionary class]]) {
|
||||
|
||||
NSDictionary *response = (NSDictionary *)myResult;
|
||||
if ([response.allKeys containsObject:@"result"]) {
|
||||
NSDictionary * resultDic = [response objectForKey:@"result"];
|
||||
|
||||
if ([resultDic.allKeys containsObject:@"api"]) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[resultDic objectForKey:@"api"] forKey:@"HTTPS"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
NSString * apiString = [resultDic objectForKey:@"api"];
|
||||
//判断是否正在审
|
||||
BOOL isExmine;
|
||||
if ([apiString containsString:@"api.out.icdat.cn"]) { //正在审
|
||||
isExmine = true;
|
||||
}else
|
||||
{
|
||||
isExmine = false;
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@(isExmine) forKey:@"isExmine"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
|
||||
if ([resultDic.allKeys containsObject:@"h5"]) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[resultDic objectForKey:@"h5"] forKey:@"IntervenH5"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
if ([resultDic.allKeys containsObject:@"h5Host"]) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[resultDic objectForKey:@"h5Host"] forKey:@"H5DevHost"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
if ([resultDic.allKeys containsObject:@"health"]) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[resultDic objectForKey:@"health"] forKey:@"BASEURL"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
KPostNotification(KNotificAgreeProtoocl, nil);
|
||||
}
|
||||
}
|
||||
|
||||
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
||||
NSString * statusCode = [error.userInfo objectForKey:@"NSLocalizedDescription"];
|
||||
//请求超时
|
||||
if (error.code == -1001) {
|
||||
[EasyTextView showErrorText:@"请求超时"];
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@"https://api.cqygjk.com" forKey:@"HTTPS"];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@"https://yyjk.cqygjk.com/" forKey:@"BASEURL"];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@"api.cqygjk.com" forKey:@"IntervenH5"];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@"https://api.cqygjk.com" forKey:@"H5DevHost"];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
KPostNotification(KNotificAgreeProtoocl, nil);
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
|
||||
#pragma mark: 键盘回收
|
||||
- (void)initIQKeyBord {
|
||||
@@ -230,7 +145,7 @@
|
||||
|
||||
paragraphStyle.alignment = NSTextAlignmentLeft;
|
||||
|
||||
NSMutableAttributedString *message = [[NSMutableAttributedString alloc] initWithString:@"\n亲,感谢您对健康咨询员工端一直以来的信任!我们依据最新的监管要求更新了健康咨询员工端《隐私权政策》,特向您说明如下\n1.为向您提供交易相关基本功能,我们会收集、使用必要的信息;\n2.基于您的明示授权,我们可能会获取您的位置(为您提供服务)等信息,您有权拒绝或取消授权;\n3.我们会采取业界先进的安全措施保护您的信息安全;\n4.未经您同意,我们不会从第三方处获取、共享或向提供您的信息;" attributes:@{
|
||||
NSMutableAttributedString *message = [[NSMutableAttributedString alloc] initWithString:@"\n亲,感谢您对健康油我一直以来的信任!我们依据最新的监管要求更新了健康油我《隐私权政策》,特向您说明如下\n1.为向您提供交易相关基本功能,我们会收集、使用必要的信息;\n2.基于您的明示授权,我们可能会获取您的位置(为您提供服务)等信息,您有权拒绝或取消授权;\n3.我们会采取业界先进的安全措施保护您的信息安全;\n4.未经您同意,我们不会从第三方处获取、共享或向提供您的信息;" attributes:@{
|
||||
NSParagraphStyleAttributeName:paragraphStyle,
|
||||
}];
|
||||
|
||||
@@ -245,7 +160,8 @@
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
//更新用户授权高德SDK隐私协议状态. since 8.1.0
|
||||
[MAMapView updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree];
|
||||
[self chageUrlService];
|
||||
KPostNotification(KNotificAgreeProtoocl, nil);
|
||||
|
||||
|
||||
}];
|
||||
|
||||
@@ -254,7 +170,8 @@
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
//更新用户授权高德SDK隐私协议状态. since 8.1.0
|
||||
[MAMapView updatePrivacyAgree:AMapPrivacyAgreeStatusNotAgree];
|
||||
[self chageUrlService];
|
||||
KPostNotification(KNotificAgreeProtoocl, nil);
|
||||
|
||||
}];
|
||||
|
||||
[alert addAction:conform];
|
||||
@@ -305,7 +222,7 @@
|
||||
|
||||
if (islogin) {//登录成功 重置Tabbar
|
||||
self.mainTabBar = nil;
|
||||
self.mainTabBar = [HQBaseTabBarController new];
|
||||
self.mainTabBar = [XJBaseTabBarController new];
|
||||
self.mainTabBar.delegate =self;
|
||||
self.window.rootViewController = self.mainTabBar;
|
||||
[self.window makeKeyAndVisible];
|
||||
@@ -314,8 +231,8 @@
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
self.window.backgroundColor = KWhiteColor;
|
||||
HQLoginViewController * loginvc = [[HQLoginViewController alloc] init];
|
||||
HQBaseNavigationController * nav = [[HQBaseNavigationController alloc] initWithRootViewController:loginvc];
|
||||
XJLoginTopChangeViewController * loginvc = [[XJLoginTopChangeViewController alloc] init];
|
||||
XJBaseNavigationController * nav = [[XJBaseNavigationController alloc] initWithRootViewController:loginvc];
|
||||
self.window.rootViewController = nav;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
@@ -332,27 +249,24 @@
|
||||
|
||||
|
||||
#pragma mark: 切换tabbar
|
||||
- (void)tabBarSoSChange:(NSNotification *)notification {
|
||||
- (void)tabBarQuestionChange:(NSNotification *)notification {
|
||||
|
||||
self.mainTabBar.selectedIndex = 1;
|
||||
|
||||
}
|
||||
|
||||
- (void)tabBarSOSChange:(NSNotification *)notification {
|
||||
|
||||
self.mainTabBar.selectedIndex = 2;
|
||||
|
||||
}
|
||||
|
||||
- (void)tabBarPhyChange:(NSNotification *)notification {
|
||||
- (void)tabBarMonitoringChange:(NSNotification *)notification {
|
||||
|
||||
self.mainTabBar.selectedIndex = 3;
|
||||
|
||||
}
|
||||
|
||||
- (void)tabBarFileChange:(NSNotification *)notification {
|
||||
|
||||
self.mainTabBar.selectedIndex = 4;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+ (AppDelegate *)shareAppDelegate{
|
||||
return (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "HQBaseTabBarController.h"
|
||||
#import "XJBaseTabBarController.h"
|
||||
/**腾讯IM**/
|
||||
#import "TUIDefine.h"
|
||||
#import "TUIBaseChatViewController.h"
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
@property (nonatomic,assign)NSInteger allowRotate;
|
||||
|
||||
@property (strong, nonatomic) HQBaseTabBarController * mainTabBar;
|
||||
@property (strong, nonatomic) XJBaseTabBarController * mainTabBar;
|
||||
|
||||
@property (nonatomic,assign)NSInteger unreadNumber;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "SJRotationManager.h"
|
||||
#import "XJWeChatManager.h"
|
||||
#import <SDWebImageWebPCoder/SDWebImageWebPCoder.h>
|
||||
|
||||
@implementation AppDelegate
|
||||
@@ -20,10 +21,6 @@
|
||||
//前缀请求
|
||||
//初始化高德地图
|
||||
[self configureAPIKey];
|
||||
|
||||
//前缀请求
|
||||
[self chageUrlService];
|
||||
|
||||
[self initService];
|
||||
//初始化window
|
||||
[self initWindow];
|
||||
@@ -38,13 +35,9 @@
|
||||
SDImageWebPCoder*webPCoder = [SDImageWebPCoder sharedCoder];
|
||||
[[SDImageCodersManager sharedManager] addCoder:webPCoder];
|
||||
|
||||
#if DEBUG
|
||||
|
||||
#else
|
||||
[CheckProjectTool testAll];
|
||||
|
||||
#endif
|
||||
|
||||
// 注册微信 SDK
|
||||
[[XJWeChatManager sharedManager] registerWithAppID:kAppKey_Wechat
|
||||
universalLink:kUniversalLink_Wechat];
|
||||
|
||||
return YES;
|
||||
}
|
||||
@@ -66,6 +59,17 @@
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||
if (window == self.window) {
|
||||
// 遍历找到最顶层的 presented VC
|
||||
UIViewController *vc = self.window.rootViewController;
|
||||
while (vc.presentedViewController) { vc = vc.presentedViewController; }
|
||||
// WKWebView 视频全屏(WKFullScreenViewController)或 AVPlayer 全屏时放行横屏
|
||||
NSString *className = NSStringFromClass(vc.class);
|
||||
if ([className containsString:@"FullScreen"] || [className containsString:@"AVPlayer"]) {
|
||||
return UIInterfaceOrientationMaskAllButUpsideDown;
|
||||
}
|
||||
return UIInterfaceOrientationMaskPortrait;
|
||||
}
|
||||
return [SJRotationManager supportedInterfaceOrientationsForWindow:window];
|
||||
}
|
||||
|
||||
@@ -84,10 +88,15 @@
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [[XJWeChatManager sharedManager] handleOpenURL:url];
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler {
|
||||
|
||||
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
|
||||
return [[XJWeChatManager sharedManager] handleOpenUniversalLink:userActivity];
|
||||
}
|
||||
return YES;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// PointsBankHModel.h
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/2/6.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface PointsBankHModel : NSObject
|
||||
|
||||
@property (nonatomic, assign) double points;
|
||||
@property (nonatomic, assign) double addPointsSum;
|
||||
@property (nonatomic, assign) double exchangePointsSum;
|
||||
|
||||
//RANK
|
||||
@property (nonatomic, assign) double frequency;
|
||||
@property (nonatomic, assign) double ruleCategory;
|
||||
@property (nonatomic, copy) NSString * ruleDesc;
|
||||
@property (nonatomic, copy) NSString * icon;
|
||||
@property (nonatomic, assign) double status;
|
||||
@property (nonatomic, assign) double delFlag;
|
||||
@property (nonatomic, copy) NSString * createUser;
|
||||
@property (nonatomic, copy) NSString * createTime;
|
||||
@property (nonatomic, copy) NSString * lastModifyDate;
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// PointsBankHModel.m
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/2/6.
|
||||
//
|
||||
|
||||
#import "PointsBankHModel.h"
|
||||
|
||||
@implementation PointsBankHModel
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// PointsBankDetailViewController.h
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/2/6.
|
||||
//
|
||||
|
||||
#import "XJBaseViewController.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface PointsBankDetailViewController : XJBaseViewController
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,263 @@
|
||||
//
|
||||
// PointsBankDetailViewController.m
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/2/6.
|
||||
//
|
||||
|
||||
#import "PointsBankDetailViewController.h"
|
||||
#import "PointsBankHModel.h"
|
||||
#import "PointsBankHomeTopView.h"
|
||||
|
||||
@interface PointsBankDetailViewController ()<UITableViewDelegate,UITableViewDataSource>
|
||||
|
||||
@property (nonatomic, strong) UITableView * homeTable;
|
||||
|
||||
@property (nonatomic, assign) NSInteger pageNo;
|
||||
|
||||
@property (nonatomic, strong) PointsBankHomeTopView * topView;
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray * dataArray;
|
||||
|
||||
@end
|
||||
|
||||
@implementation PointsBankDetailViewController
|
||||
|
||||
- (NSMutableArray *)dataArray {
|
||||
if (!_dataArray) {
|
||||
_dataArray = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return _dataArray;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.view.backgroundColor = KWhiteColor;
|
||||
self.pageNo = 1;
|
||||
[self createData];
|
||||
[self createUI];
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
- (void)createUI {
|
||||
|
||||
self.topView= [[PointsBankHomeTopView alloc] init];
|
||||
|
||||
[self.view addSubview:self.topView];
|
||||
|
||||
[self.topView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.top.right.mas_offset(0);
|
||||
|
||||
}];
|
||||
|
||||
|
||||
self.homeTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
||||
if ([[UIDevice currentDevice].systemVersion floatValue] >= 11) {
|
||||
self.homeTable.estimatedRowHeight = 60;
|
||||
if (@available(iOS 15.0, *)) {
|
||||
self.homeTable.sectionHeaderTopPadding = 0;
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
self.homeTable.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
self.homeTable.delegate = self;
|
||||
self.homeTable.dataSource = self;
|
||||
self.homeTable.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
|
||||
self.homeTable.showsVerticalScrollIndicator = NO;
|
||||
self.homeTable.backgroundColor = KClearColor;
|
||||
self.homeTable.rowHeight = UITableViewAutomaticDimension;
|
||||
self.homeTable.estimatedRowHeight = 80;
|
||||
|
||||
|
||||
[self.view addSubview:self.homeTable];
|
||||
|
||||
[self.homeTable mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(_topView.mas_bottom);
|
||||
make.left.bottom.right.mas_offset(0);
|
||||
|
||||
}];
|
||||
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
self.homeTable.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
|
||||
|
||||
weakSelf.pageNo = 1;
|
||||
[weakSelf.dataArray removeAllObjects];
|
||||
[weakSelf createData];
|
||||
|
||||
}];
|
||||
|
||||
self.homeTable.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
|
||||
|
||||
weakSelf.pageNo++;
|
||||
[weakSelf createData];
|
||||
|
||||
}];
|
||||
|
||||
|
||||
LYEmptyView *emptyView = [LYEmptyView emptyViewWithImageStr:@"noDataBox" titleStr:@"暂无数据" detailStr:@""];
|
||||
//元素竖直方向的间距
|
||||
emptyView.subViewMargin = 20.f;
|
||||
//标题颜色
|
||||
emptyView.titleLabTextColor = [UIColor blackColor];
|
||||
//描述字体
|
||||
emptyView.detailLabFont = [UIFont systemFontOfSize:17];
|
||||
//按钮背景色
|
||||
emptyView.actionBtnBackGroundColor = KWhiteColor;
|
||||
emptyView.actionBtnWidth = CGFLOAT_MIN;
|
||||
emptyView.actionBtnHeight = CGFLOAT_MIN;
|
||||
//设置空内容占位图
|
||||
self.homeTable.ly_emptyView = emptyView;
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)createData {
|
||||
|
||||
[self showMBProgressHUDWithString:@"加载中,请稍候..." autoHidden:false];
|
||||
NSMutableDictionary * parmDic = [[NSMutableDictionary alloc] init];
|
||||
[parmDic setObject:@(self.pageNo) forKey:@"pageNo"];
|
||||
[parmDic setObject:@"10" forKey:@"pageSize"];
|
||||
|
||||
XJPNetAPI * listApi = [[XJPNetAPI alloc] init:self tag:@"LIST" NeedToken:@""];
|
||||
[listApi getUserMessageList:parmDic];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark - DataSource
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
|
||||
return self.dataArray.count;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
|
||||
return UITableViewCell.new;
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (CGFloat )tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
return CGFLOAT_MIN;
|
||||
}
|
||||
|
||||
- (CGFloat )tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
|
||||
{
|
||||
return CGFLOAT_MIN;
|
||||
}
|
||||
|
||||
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
|
||||
|
||||
return UIView.new;
|
||||
}
|
||||
|
||||
|
||||
- (void)chageDataType:(UIButton *)typeBtn {
|
||||
|
||||
//请求接口
|
||||
if (typeBtn.tag == 0) {
|
||||
[self creeateRankDataWithTyep:@"1"];
|
||||
}
|
||||
if (typeBtn.tag == 1) {
|
||||
[self creeateRankDataWithTyep:@"2"];
|
||||
}
|
||||
if (typeBtn.tag == 2) {
|
||||
[self creeateRankDataWithTyep:@"0"];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)creeateRankDataWithTyep:(NSString *)type {
|
||||
|
||||
//rankType(榜单类型,0总榜,1周榜,2月榜)
|
||||
[self showMBProgressHUDWithString:@"加载中,请稍候..." autoHidden:false];
|
||||
|
||||
NSMutableDictionary * parmDic = [[NSMutableDictionary alloc] init];
|
||||
[parmDic setObject:@(self.pageNo) forKey:@"pageNo"];
|
||||
[parmDic setObject:@"10" forKey:@"pageSize"];
|
||||
[parmDic setObject:type forKey:@"rankType"];
|
||||
|
||||
|
||||
XJPNetAPI * listApi = [[XJPNetAPI alloc] init:self tag:@"DETAIL" NeedToken:@""];
|
||||
[listApi postPointsBankSourceDetail:parmDic];
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)Failed:(NSString*)message tag:(NSString*)tag
|
||||
{
|
||||
|
||||
[self.homeTable.mj_header endRefreshing];
|
||||
[self.homeTable.mj_footer endRefreshing];
|
||||
|
||||
[self hiddenAllMBProgressHUD];
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)Sucess:(id)response tag:(NSString*)tag
|
||||
{
|
||||
[self.homeTable.mj_header endRefreshing];
|
||||
[self.homeTable.mj_footer endRefreshing];
|
||||
if ([tag isEqualToString:@"DETAIL"]) {
|
||||
|
||||
[self hiddenAllMBProgressHUD];
|
||||
NSDictionary * responseDic = response;
|
||||
|
||||
PointsBankHModel * model = [PointsBankHModel modelWithDictionary:responseDic];
|
||||
//points 可用积分 addPointsSum 累计积分 exchangePointsSum 累计兑换
|
||||
self.topView.model = model;
|
||||
|
||||
}
|
||||
if ([tag isEqualToString:@"RANK"]) {
|
||||
NSDictionary * dic = response;
|
||||
if ([dic.allKeys containsObject:@"page"]) {
|
||||
NSDictionary * pageDic = [dic objectForKey:@"page"];
|
||||
//取到排名
|
||||
if ([pageDic.allKeys containsObject:@"records"]) {
|
||||
NSArray * array = [pageDic objectForKey:@"records"];
|
||||
for (NSDictionary * rankDic in array) {
|
||||
PointsBankHModel * mdoel = [PointsBankHModel modelWithDictionary:rankDic];
|
||||
[self.dataArray addObject:mdoel];
|
||||
|
||||
}
|
||||
//处理结束 给数据
|
||||
[self.homeTable reloadData];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#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
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// PointsBankHomeTopView.h
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/2/6.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "PointsBankHModel.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface PointsBankHomeTopView : UIView
|
||||
|
||||
@property (nonatomic, strong) PointsBankHModel * model;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,144 @@
|
||||
//
|
||||
// PointsBankHomeTopView.m
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/2/6.
|
||||
//
|
||||
|
||||
#import "PointsBankHomeTopView.h"
|
||||
|
||||
@interface PointsBankHomeTopView ()
|
||||
|
||||
@property (nonatomic, strong) UILabel * pointsDataLabel;
|
||||
@property (nonatomic, strong) UILabel * pointsAddLabel;
|
||||
@property (nonatomic, strong) UILabel * exchangeLabel;
|
||||
|
||||
@end
|
||||
|
||||
@implementation PointsBankHomeTopView
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect {
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
|
||||
[self createUI];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)createUI {
|
||||
|
||||
UILabel * haveLab = [[UILabel alloc] init];
|
||||
haveLab.text = @"可用积分";
|
||||
haveLab.textColor = CFontColor1;
|
||||
haveLab.font = [UIFont systemFontOfSize:13 weight:UIFontWeightRegular];
|
||||
[self addSubview:haveLab];
|
||||
|
||||
[haveLab mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_offset(15);
|
||||
make.top.mas_offset(15);
|
||||
}];
|
||||
|
||||
self.pointsDataLabel = [[UILabel alloc] init];
|
||||
self.pointsDataLabel.text = @"--";
|
||||
self.pointsDataLabel.textColor = CFontColor1;
|
||||
self.pointsDataLabel.font = [UIFont systemFontOfSize:28 weight:UIFontWeightBold];
|
||||
[self addSubview:self.pointsDataLabel];
|
||||
|
||||
[self.pointsDataLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(haveLab);
|
||||
make.top.mas_equalTo(haveLab.mas_bottom).offset(12);
|
||||
}];
|
||||
|
||||
|
||||
UIButton * sourceBtn = [[UIButton alloc] init];
|
||||
[sourceBtn setTitle:@"获取积分" forState:UIControlStateNormal];
|
||||
[sourceBtn setTitleColor:KWhiteColor forState:UIControlStateNormal];
|
||||
sourceBtn.titleLabel.font = SYSTEMFONT(15);
|
||||
sourceBtn.layer.cornerRadius = 4;
|
||||
sourceBtn.layer.masksToBounds = true;
|
||||
sourceBtn.backgroundColor = UIColorHex(#21BEBE);
|
||||
[self addSubview:sourceBtn];
|
||||
|
||||
[sourceBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.right.mas_offset(-15);
|
||||
make.width.mas_offset(80);
|
||||
make.height.mas_offset(32);
|
||||
make.top.mas_offset(53);
|
||||
}];
|
||||
|
||||
UILabel * addLab = [[UILabel alloc] init];
|
||||
addLab.text = @"累计积分:";
|
||||
addLab.textColor = CFontColor1;
|
||||
addLab.font = [UIFont systemFontOfSize:13 weight:UIFontWeightRegular];
|
||||
self.pointsAddLabel = addLab;
|
||||
[self addSubview:addLab];
|
||||
|
||||
[addLab mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(haveLab.mas_right).offset(81);
|
||||
make.top.mas_equalTo(haveLab.mas_bottom).offset(11);
|
||||
}];
|
||||
|
||||
self.exchangeLabel = [[UILabel alloc] init];
|
||||
self.exchangeLabel.text = @"累计兑换:";
|
||||
self.exchangeLabel.textColor = CFontColor1;
|
||||
self.exchangeLabel.font = [UIFont systemFontOfSize:13 weight:UIFontWeightRegular];
|
||||
[self addSubview:self.exchangeLabel];
|
||||
|
||||
[self.exchangeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(haveLab.mas_right).offset(81);
|
||||
make.top.mas_equalTo(addLab.mas_bottom).offset(11);
|
||||
}];
|
||||
|
||||
UIView *dashedView = [[UIView alloc] init];
|
||||
[self addSubview:dashedView];
|
||||
|
||||
// Masonry 布局
|
||||
[dashedView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(20);
|
||||
make.right.mas_equalTo(-20);
|
||||
make.top.mas_equalTo(self.pointsDataLabel.mas_bottom).offset(10);
|
||||
make.height.mas_equalTo(1); // 高度可以随意
|
||||
make.bottom.mas_equalTo(-10);
|
||||
}];
|
||||
//虚线
|
||||
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
|
||||
shapeLayer.strokeColor = [UIColor lightGrayColor].CGColor; // 线颜色
|
||||
shapeLayer.lineWidth = 1; // 线宽
|
||||
shapeLayer.lineDashPattern = @[@4, @2]; // 虚线:4pt 实线,2pt 空白
|
||||
|
||||
// 创建路径
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathMoveToPoint(path, NULL, 0, 0); // 起点
|
||||
CGPathAddLineToPoint(path, NULL, [UIScreen mainScreen].bounds.size.width - 40, 0); // 终点
|
||||
shapeLayer.path = path;
|
||||
CGPathRelease(path);
|
||||
|
||||
// 添加到 view
|
||||
[dashedView.layer addSublayer:shapeLayer];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void)setModel:(PointsBankHModel *)model {
|
||||
|
||||
_model = model;
|
||||
|
||||
self.pointsDataLabel.text = [NSString stringWithFormat:@"%.0f",_model.points];
|
||||
|
||||
self.pointsAddLabel.text = [NSString stringWithFormat:@"累计积分:%.0f",_model.addPointsSum];
|
||||
|
||||
self.exchangeLabel.text = [NSString stringWithFormat:@"累计兑换%.0f",_model.exchangePointsSum];
|
||||
|
||||
|
||||
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// myPointsBankHomeViewController.h
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/2/6.
|
||||
//
|
||||
|
||||
#import "XJBaseViewController.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface myPointsBankHomeViewController : XJBaseViewController
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,439 @@
|
||||
//
|
||||
// myPointsBankHomeViewController.m
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2026/2/6.
|
||||
//
|
||||
|
||||
#import "myPointsBankHomeViewController.h"
|
||||
#import "PointsBankHModel.h"
|
||||
#import "PointsBankHomeTopView.h"
|
||||
|
||||
@interface myPointsBankHomeViewController ()<UITableViewDelegate,UITableViewDataSource>
|
||||
|
||||
@property (nonatomic, strong) UITableView * homeTable;
|
||||
@property (nonatomic, assign) NSInteger pageNo;
|
||||
@property (nonatomic, strong) NSMutableArray * dataArray;
|
||||
@property (nonatomic, strong) NSMutableArray * buttonArray;
|
||||
|
||||
@property (nonatomic, strong) PointsBankHomeTopView * topView;
|
||||
@property (nonatomic, strong) UIView * lineView;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@implementation myPointsBankHomeViewController
|
||||
|
||||
- (NSMutableArray *)dataArray {
|
||||
|
||||
if (!_dataArray ) {
|
||||
_dataArray = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return _dataArray;
|
||||
}
|
||||
|
||||
- (NSMutableArray *)buttonArray {
|
||||
|
||||
if (!_buttonArray ) {
|
||||
_buttonArray = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return _buttonArray;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
self.isHidenNaviBar = false;
|
||||
self.navigationItem.title = @"我的积分银行";
|
||||
|
||||
[self createData];
|
||||
//默认总榜单
|
||||
[self creeateRankDataWithTyep:@"0"];
|
||||
[self createUI];
|
||||
}
|
||||
|
||||
- (void)createUI {
|
||||
|
||||
//首页
|
||||
self.topView = [[PointsBankHomeTopView alloc] init];
|
||||
[self.view addSubview:self.topView];
|
||||
|
||||
[self.topView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.right.top.mas_offset(0);
|
||||
// make.height.mas_offset(185);
|
||||
}];
|
||||
|
||||
//功能栏
|
||||
NSArray * toolsArray = @[@[@"积分兑换",@"img1"],@[@"积分明细",@"img2"],@[@"兑换记录",@"img3"]];
|
||||
|
||||
CGFloat itemWidth = 60;
|
||||
CGFloat itemHeight = 110;
|
||||
NSInteger count = toolsArray.count;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
NSArray *item = toolsArray[i];
|
||||
|
||||
// 1️⃣ 容器 view
|
||||
UIView *itemView = [[UIView alloc] init];
|
||||
itemView.tag = i;
|
||||
itemView.userInteractionEnabled = YES;
|
||||
[self.view addSubview:itemView];
|
||||
|
||||
// 2️⃣ 点击手势
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(itemTap:)];
|
||||
[itemView addGestureRecognizer:tap];
|
||||
|
||||
// 3️⃣ 布局 container(每个 item 占 1/3 屏幕宽)
|
||||
CGFloat thirdWidth = UIScreen.mainScreen.bounds.size.width / count;
|
||||
|
||||
[itemView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(self.topView.mas_bottom).offset(20);
|
||||
make.width.mas_equalTo(itemWidth);
|
||||
make.height.mas_equalTo(itemHeight);
|
||||
make.centerX.mas_equalTo(self.view.mas_left).offset(thirdWidth * i + thirdWidth / 2);
|
||||
}];
|
||||
|
||||
// 4️⃣ 图片
|
||||
UIImageView *icon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:item[1]]];
|
||||
icon.contentMode = UIViewContentModeScaleAspectFit;
|
||||
[itemView addSubview:icon];
|
||||
|
||||
[icon mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(0);
|
||||
make.centerX.equalTo(itemView);
|
||||
make.width.height.mas_equalTo(40);
|
||||
}];
|
||||
|
||||
// 5️⃣ 文字
|
||||
UILabel *label = [[UILabel alloc] init];
|
||||
label.text = item[0];
|
||||
label.font = [UIFont systemFontOfSize:14];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
[itemView addSubview:label];
|
||||
|
||||
[label mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.equalTo(icon.mas_bottom).offset(8);
|
||||
make.left.right.equalTo(itemView);
|
||||
make.height.mas_equalTo(20);
|
||||
}];
|
||||
}
|
||||
|
||||
//排行
|
||||
UIView * rankView = [[UIView alloc] init];
|
||||
rankView.backgroundColor = KWhiteColor;
|
||||
[self.view addSubview:rankView];
|
||||
|
||||
|
||||
UILabel * rankTitleLab = [[UILabel alloc] init];
|
||||
rankTitleLab.text = @"积分排行(单位)";
|
||||
rankTitleLab.textColor = CFontColor1;
|
||||
[rankView addSubview:rankTitleLab];
|
||||
|
||||
[rankTitleLab mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_offset(15);
|
||||
make.top.mas_offset(15);
|
||||
}];
|
||||
|
||||
UILabel * detailLab = [[UILabel alloc] init];
|
||||
detailLab.text = @"以员工累计获得积分进行排名";
|
||||
detailLab.textColor = CFontColor1;
|
||||
[rankView addSubview:detailLab];
|
||||
|
||||
[detailLab mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_offset(15);
|
||||
make.top.mas_equalTo(rankTitleLab.mas_bottom).offset(8);
|
||||
}];
|
||||
|
||||
//周排名 月排名 年排名
|
||||
UIView * lineView = [[UIView alloc] init];
|
||||
lineView.backgroundColor = UIColor.blueColor;
|
||||
self.lineView = lineView;
|
||||
[rankView addSubview:lineView];
|
||||
|
||||
[lineView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.mas_offset(80);
|
||||
make.height.mas_offset(2);
|
||||
}];
|
||||
|
||||
NSArray * array = @[@"周排名",@"月排名",@"年排名"];
|
||||
UIButton * lastBtn = nil;
|
||||
for (int i= 0; i < 3; i ++) {
|
||||
|
||||
UIButton * btn = [[UIButton alloc] init];
|
||||
[btn setTitle:array[i] forState:UIControlStateNormal];
|
||||
[btn setTitleColor:UIColor.blueColor forState:UIControlStateSelected];
|
||||
[btn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
|
||||
btn.titleLabel.font = MEDIUMFONT(13);
|
||||
btn.tag = i;
|
||||
[btn addTarget:self action:@selector(chageDataType:) forControlEvents:UIControlEventTouchUpInside];
|
||||
btn.selected = false;
|
||||
if (i == 2) {
|
||||
btn.selected = true;
|
||||
lastBtn = btn;
|
||||
|
||||
}
|
||||
[rankView addSubview:btn];
|
||||
|
||||
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.mas_offset(80);
|
||||
make.height.mas_offset(32);
|
||||
make.top.mas_equalTo(detailLab.mas_bottom).offset(10);
|
||||
if (i == 0) {
|
||||
make.left.mas_offset(82);
|
||||
}
|
||||
if (i == 1) {
|
||||
make.centerX.mas_equalTo(rankView);
|
||||
|
||||
}
|
||||
if (i == 2) {
|
||||
make.right.mas_offset(-82);
|
||||
}
|
||||
}];
|
||||
[self.buttonArray addObject:btn];
|
||||
|
||||
}
|
||||
if (lastBtn) {
|
||||
[lineView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(lastBtn);
|
||||
make.top.mas_equalTo(lastBtn.mas_bottom).offset(5);
|
||||
}];
|
||||
}
|
||||
|
||||
[rankView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.right.mas_offset(0);
|
||||
make.top.mas_equalTo(self.topView.mas_bottom).offset(15);
|
||||
make.bottom.mas_equalTo(lastBtn.mas_bottom).offset(20);
|
||||
}];
|
||||
|
||||
self.homeTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
||||
if ([[UIDevice currentDevice].systemVersion floatValue] >= 11) {
|
||||
self.homeTable.estimatedRowHeight = 60;
|
||||
if (@available(iOS 15.0, *)) {
|
||||
self.homeTable.sectionHeaderTopPadding = 0;
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
self.homeTable.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
self.homeTable.delegate = self;
|
||||
self.homeTable.dataSource = self;
|
||||
self.homeTable.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
|
||||
self.homeTable.showsVerticalScrollIndicator = NO;
|
||||
self.homeTable.backgroundColor = KClearColor;
|
||||
self.homeTable.rowHeight = UITableViewAutomaticDimension;
|
||||
self.homeTable.estimatedRowHeight = 80;
|
||||
|
||||
|
||||
[self.view addSubview:self.homeTable];
|
||||
|
||||
[self.homeTable mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(rankView.mas_bottom);
|
||||
make.left.bottom.right.mas_offset(0);
|
||||
|
||||
}];
|
||||
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
self.homeTable.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
|
||||
|
||||
weakSelf.pageNo = 1;
|
||||
[weakSelf.dataArray removeAllObjects];
|
||||
[weakSelf createData];
|
||||
|
||||
}];
|
||||
|
||||
self.homeTable.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
|
||||
|
||||
weakSelf.pageNo++;
|
||||
[weakSelf createData];
|
||||
|
||||
}];
|
||||
|
||||
|
||||
LYEmptyView *emptyView = [LYEmptyView emptyViewWithImageStr:@"noDataBox" titleStr:@"暂无数据" detailStr:@""];
|
||||
//元素竖直方向的间距
|
||||
emptyView.subViewMargin = 20.f;
|
||||
//标题颜色
|
||||
emptyView.titleLabTextColor = [UIColor blackColor];
|
||||
//描述字体
|
||||
emptyView.detailLabFont = [UIFont systemFontOfSize:17];
|
||||
//按钮背景色
|
||||
emptyView.actionBtnBackGroundColor = KWhiteColor;
|
||||
emptyView.actionBtnWidth = CGFLOAT_MIN;
|
||||
emptyView.actionBtnHeight = CGFLOAT_MIN;
|
||||
//设置空内容占位图
|
||||
self.homeTable.ly_emptyView = emptyView;
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)createData {
|
||||
|
||||
[self showMBProgressHUDWithString:@"加载中,请稍候..." autoHidden:false];
|
||||
NSMutableDictionary * parmDic = [[NSMutableDictionary alloc] init];
|
||||
XJPNetAPI * listApi = [[XJPNetAPI alloc] init:self tag:@"HEARD" NeedToken:@""];
|
||||
[listApi getPointsBankHeard:parmDic];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark - DataSource
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
|
||||
return self.dataArray.count;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
|
||||
return UITableViewCell.new;
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (CGFloat )tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
return CGFLOAT_MIN;
|
||||
}
|
||||
|
||||
- (CGFloat )tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
|
||||
{
|
||||
return CGFLOAT_MIN;
|
||||
}
|
||||
|
||||
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
|
||||
|
||||
return UIView.new;
|
||||
}
|
||||
|
||||
|
||||
- (void)chageDataType:(UIButton *)typeBtn {
|
||||
|
||||
for (UIButton * seleBtn in self.buttonArray) {
|
||||
if (seleBtn == typeBtn) {
|
||||
seleBtn.selected = true;
|
||||
|
||||
[self.lineView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.right.mas_equalTo(typeBtn);
|
||||
make.bottom.mas_equalTo(typeBtn.mas_bottom).offset(8);
|
||||
make.height.mas_offset(1);
|
||||
make.centerX.mas_equalTo(typeBtn);
|
||||
}];
|
||||
}else
|
||||
{
|
||||
seleBtn.selected = false;
|
||||
}
|
||||
}
|
||||
//请求接口
|
||||
if (typeBtn.tag == 0) {
|
||||
[self creeateRankDataWithTyep:@"1"];
|
||||
}
|
||||
if (typeBtn.tag == 1) {
|
||||
[self creeateRankDataWithTyep:@"2"];
|
||||
}
|
||||
if (typeBtn.tag == 2) {
|
||||
[self creeateRankDataWithTyep:@"0"];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)creeateRankDataWithTyep:(NSString *)type {
|
||||
|
||||
//rankType(榜单类型,0总榜,1周榜,2月榜)
|
||||
[self showMBProgressHUDWithString:@"加载中,请稍候..." autoHidden:false];
|
||||
|
||||
NSMutableDictionary * parmDic = [[NSMutableDictionary alloc] init];
|
||||
[parmDic setObject:@(self.pageNo) forKey:@"pageNo"];
|
||||
[parmDic setObject:@"10" forKey:@"pageSize"];
|
||||
[parmDic setObject:type forKey:@"rankType"];
|
||||
|
||||
|
||||
XJPNetAPI * listApi = [[XJPNetAPI alloc] init:self tag:@"RANK" NeedToken:@""];
|
||||
[listApi postPointsBankRankData:parmDic];
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)Failed:(NSString*)message tag:(NSString*)tag
|
||||
{
|
||||
|
||||
[self.homeTable.mj_header endRefreshing];
|
||||
[self.homeTable.mj_footer endRefreshing];
|
||||
|
||||
[self hiddenAllMBProgressHUD];
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)Sucess:(id)response tag:(NSString*)tag
|
||||
{
|
||||
[self.homeTable.mj_header endRefreshing];
|
||||
[self.homeTable.mj_footer endRefreshing];
|
||||
if ([tag isEqualToString:@"HEARD"]) {
|
||||
|
||||
[self hiddenAllMBProgressHUD];
|
||||
NSDictionary * responseDic = response;
|
||||
|
||||
PointsBankHModel * model = [PointsBankHModel modelWithDictionary:responseDic];
|
||||
//points 可用积分 addPointsSum 累计积分 exchangePointsSum 累计兑换
|
||||
self.topView.model = model;
|
||||
|
||||
}
|
||||
if ([tag isEqualToString:@"RANK"]) {
|
||||
NSDictionary * dic = response;
|
||||
if ([dic.allKeys containsObject:@"page"]) {
|
||||
NSDictionary * pageDic = [dic objectForKey:@"page"];
|
||||
//取到排名
|
||||
if ([pageDic.allKeys containsObject:@"records"]) {
|
||||
NSArray * array = [pageDic objectForKey:@"records"];
|
||||
for (NSDictionary * rankDic in array) {
|
||||
PointsBankHModel * mdoel = [PointsBankHModel modelWithDictionary:rankDic];
|
||||
[self.dataArray addObject:mdoel];
|
||||
|
||||
}
|
||||
//处理结束 给数据
|
||||
[self.homeTable reloadData];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
- (void)itemTap:(UITapGestureRecognizer *)tap {
|
||||
NSInteger index = tap.view.tag;
|
||||
NSLog(@"点击了第 %ld 个", index);
|
||||
|
||||
if(index == 1 || index == 2) {
|
||||
[EasyTextView showInfoText:@"开发者,敬请期待!"];
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
#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
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
//
|
||||
// BaseWebViewVC.m
|
||||
// ScarHousekeeper
|
||||
//
|
||||
// Created by 张小万 on 2021/1/21.
|
||||
//
|
||||
|
||||
#import "BaseWebViewVC.h"
|
||||
|
||||
@interface BaseWebViewVC ()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
|
||||
|
||||
@property (nonatomic, strong)NSURL *originalUrl;
|
||||
@property (nonatomic, copy)NSString *videoUrl;
|
||||
@property (nonatomic, copy)NSString *messageType;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@implementation BaseWebViewVC
|
||||
|
||||
|
||||
#pragma mark - LifeCycle
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
self.isHidenNaviBar = false;
|
||||
[self addNavigationItemWithImageNames:@[@"whiteBack_icon"] isLeft:YES target:self action:@selector(backVC) tags:@[@""]];
|
||||
[self addSubviews];
|
||||
if (self.webTitle) {
|
||||
self.navigationItem.title = self.webTitle;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)backVC {
|
||||
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated{
|
||||
[super viewWillAppear:animated];
|
||||
if (_wkWebView) {
|
||||
_wkWebView.navigationDelegate = self;
|
||||
_wkWebView.UIDelegate = self;
|
||||
_wkWebView.allowsBackForwardNavigationGestures = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated{
|
||||
[super viewWillDisappear:animated];
|
||||
_wkWebView.navigationDelegate = nil;
|
||||
_wkWebView.UIDelegate = nil;
|
||||
//清除cookies
|
||||
NSHTTPCookie *cookie;
|
||||
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
|
||||
for (cookie in [storage cookies]) {
|
||||
[storage deleteCookie:cookie];
|
||||
}
|
||||
[[NSURLCache sharedURLCache] removeAllCachedResponses];
|
||||
[self clearWebViewCache];
|
||||
}
|
||||
|
||||
#pragma mark - Create UI
|
||||
- (void)addSubviews{
|
||||
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
|
||||
WKPreferences *preferences = [[WKPreferences alloc]init];
|
||||
preferences.javaScriptEnabled = YES;
|
||||
preferences.javaScriptCanOpenWindowsAutomatically = YES;
|
||||
preferences.minimumFontSize = 10;
|
||||
configuration.preferences = preferences;
|
||||
[configuration.userContentController addScriptMessageHandler:self name:@"JSCallback"];
|
||||
[configuration.userContentController addScriptMessageHandler:self name:@"htmlBack"];
|
||||
//防止搜索框自动放大 注入js代码
|
||||
WKUserContentController *userController = [WKUserContentController new];
|
||||
NSString *jScript = @"var script = document.createElement('meta');script.name = 'viewport';script.content='width=device-width,user-scalable=no';document.getElementsByTagName('head')[0].appendChild(script);";
|
||||
|
||||
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
|
||||
WKUserContentController * wkUController = [[WKUserContentController alloc] init];
|
||||
[wkUController addScriptMessageHandler: self name: @"finishActivity"];//不带参数的调用
|
||||
|
||||
[wkUController addUserScript:wkUScript];
|
||||
configuration.userContentController= wkUController;
|
||||
|
||||
self.wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, MyViewHEIGHT) configuration:configuration];
|
||||
self.wkWebView.navigationDelegate = self;
|
||||
self.wkWebView.UIDelegate = self;
|
||||
if (@available(iOS 11.0, *)) {
|
||||
self.wkWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
[self.view addSubview:self.wkWebView];
|
||||
self.wkWebView.scrollView.bounces = false;//禁止滑动
|
||||
[self webViewRequest];
|
||||
/*
|
||||
[self.wkWebView evaluateJavaScript:@"htmlBack" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
|
||||
NSLog(@"response: %@ error: %@", response, error);
|
||||
if (response) {
|
||||
[self back];
|
||||
}
|
||||
}];
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)finishActivity {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)webViewRequest{
|
||||
NSString *urlString = self.webUrl;
|
||||
[self hiddenAllMBProgressHUD];
|
||||
if (urlString.length > 0) {
|
||||
[self showMBProgressHUDOnlyWithString:@"加载中"];
|
||||
NSURL *url = [NSURL URLWithString:urlString];
|
||||
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
|
||||
if (self.wkWebView) {
|
||||
[self.wkWebView loadRequest:urlRequest];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark - WKNavigationDelegate
|
||||
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
|
||||
if ([message.name isEqualToString:@"JSCallback"]) {
|
||||
if (message.body) {
|
||||
NSData *jsonData = [message.body dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError *err;
|
||||
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
|
||||
options:NSJSONReadingMutableContainers
|
||||
error:&err];
|
||||
if(err) {
|
||||
}
|
||||
WkJSMessageType messageType = [[dic objectForKey:@"messageType"] intValue];
|
||||
switch (messageType) {
|
||||
case WkJSMessageTypeBack:{
|
||||
// [self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ([message.name isEqualToString:@"htmlBack"]) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"fromWebToReloadData" object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - WKScriptMessageHandler
|
||||
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
|
||||
[self hiddenAllMBProgressHUD];
|
||||
if (!navigationAction.targetFrame.isMainFrame) {
|
||||
[webView loadRequest:navigationAction.request];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
|
||||
if (!self.webTitle) {
|
||||
self.title = @"加载中...";
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
|
||||
[self hiddenAllMBProgressHUD];
|
||||
|
||||
if (!self.webTitle) {
|
||||
self.title = webView.title;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(nonnull NSError *)error{
|
||||
[self hiddenAllMBProgressHUD];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark - ACTION
|
||||
- (void)ToClickNavRight:(UIButton *)button{
|
||||
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - 自定义
|
||||
- (void)onBackClicked{
|
||||
if ( self.wkWebView.canGoBack){
|
||||
[self.wkWebView goBack];
|
||||
} else {
|
||||
[self clearWebViewCache];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearWebViewCache{
|
||||
if (iOS9Later) {
|
||||
NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
|
||||
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
|
||||
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
|
||||
NSLog(@"-----clear webView cache success------");
|
||||
}];
|
||||
} else {
|
||||
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
||||
NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"];
|
||||
NSError *errors;
|
||||
[[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors];
|
||||
if (!errors) {
|
||||
NSLog(@"-----clear wkWebView cache success------");
|
||||
}
|
||||
}
|
||||
}
|
||||
- (NSString *)URLEncodedString:(NSString *)urlString{
|
||||
NSString *encodePath ;
|
||||
if (!IOS7) {
|
||||
encodePath = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
}else{
|
||||
encodePath = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
||||
}return encodePath;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - SETTER
|
||||
- (void)setRightType:(RightNavType)rightType{
|
||||
_rightType = rightType;
|
||||
}
|
||||
|
||||
- (void)setWebUrl:(NSString *)webUrl{
|
||||
_webUrl = webUrl;
|
||||
[self webViewRequest];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -1,18 +0,0 @@
|
||||
//
|
||||
// DownPDFFileVC.h
|
||||
// EscortProject
|
||||
//
|
||||
// Created by 仁康信息 on 2023/12/1.
|
||||
//
|
||||
|
||||
#import "HQBaseViewController.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DownPDFFileVC : HQBaseViewController
|
||||
|
||||
@property (nonatomic, strong) NSString * PDFUrl;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// HQBaseNavigationController.h
|
||||
// XJBaseNavigationController.h
|
||||
// healthQuestion
|
||||
//
|
||||
// Created by xulei on 2022/8/12.
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface HQBaseNavigationController : UINavigationController
|
||||
@interface XJBaseNavigationController : UINavigationController
|
||||
|
||||
/*!
|
||||
* 返回到指定的类视图
|
||||
+6
-6
@@ -1,15 +1,15 @@
|
||||
//
|
||||
// HQBaseNavigationController.m
|
||||
// XJBaseNavigationController.m
|
||||
// healthQuestion
|
||||
//
|
||||
// Created by xulei on 2022/8/12.
|
||||
//
|
||||
|
||||
#import "HQBaseNavigationController.h"
|
||||
#import "XJBaseNavigationController.h"
|
||||
#import "XYTransitionProtocol.h"
|
||||
#import "XYTransition.h"
|
||||
|
||||
@interface HQBaseNavigationController ()<UINavigationControllerDelegate,UIGestureRecognizerDelegate>
|
||||
@interface XJBaseNavigationController ()<UINavigationControllerDelegate,UIGestureRecognizerDelegate>
|
||||
|
||||
@property (nonatomic, weak) id popDelegate;
|
||||
@property (nonatomic,strong) UIPercentDrivenInteractiveTransition *interactivePopTransition;
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
@end
|
||||
|
||||
@implementation HQBaseNavigationController
|
||||
@implementation XJBaseNavigationController
|
||||
|
||||
//APP生命周期中 只会执行一次
|
||||
+ (void)initialize
|
||||
@@ -124,8 +124,8 @@
|
||||
|
||||
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
|
||||
|
||||
if ([viewController isKindOfClass:[HQBaseViewController class]]) {
|
||||
HQBaseViewController * vc = (HQBaseViewController *)viewController;
|
||||
if ([viewController isKindOfClass:[XJBaseViewController class]]) {
|
||||
XJBaseViewController * vc = (XJBaseViewController *)viewController;
|
||||
if (vc.isHidenNaviBar) {
|
||||
vc.view.top = 0;
|
||||
[vc.navigationController setNavigationBarHidden:YES animated:animated];
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// HQBaseTabBarController.h
|
||||
// XJBaseTabBarController.h
|
||||
// healthQuestion
|
||||
//
|
||||
// Created by xulei on 2022/8/12.
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface HQBaseTabBarController : UITabBarController
|
||||
@interface XJBaseTabBarController : UITabBarController
|
||||
|
||||
/**
|
||||
设置小红点
|
||||
+27
-19
@@ -1,23 +1,24 @@
|
||||
//
|
||||
// HQBaseTabBarController.m
|
||||
// XJBaseTabBarController.m
|
||||
// healthQuestion
|
||||
//
|
||||
// Created by xulei on 2022/8/12.
|
||||
//
|
||||
|
||||
#import "HQBaseTabBarController.h"
|
||||
#import "XJBaseTabBarController.h"
|
||||
#import "HQTabBar.h"
|
||||
#import "MyCenterViewController.h"
|
||||
#import "XJMyCenterViewController.h"
|
||||
#import "ChatListViewController.h"
|
||||
//主控制器
|
||||
#import "QuestionViewController.h"
|
||||
#import "MyCenterViewController.h"
|
||||
#import "SosCenterViewController.h"
|
||||
#import "HeartBadViewController.h"
|
||||
#import "XJSosCenterViewController.h"
|
||||
#import "MonitoringWarchViewController.h"
|
||||
|
||||
//干预二期
|
||||
//新版首页
|
||||
#import "XJHomePageV2ViewController.h"
|
||||
|
||||
@interface HQBaseTabBarController ()<UITabBarControllerDelegate>
|
||||
|
||||
@interface XJBaseTabBarController ()<UITabBarControllerDelegate>
|
||||
|
||||
@property (nonatomic,strong) NSMutableArray * VCS;//tabbar root VC
|
||||
|
||||
@@ -34,14 +35,12 @@
|
||||
|
||||
@end
|
||||
|
||||
@implementation HQBaseTabBarController
|
||||
@implementation XJBaseTabBarController
|
||||
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.delegate = self;
|
||||
|
||||
|
||||
//初始化tabbar
|
||||
[self setUpTabBar];
|
||||
//添加子控制器
|
||||
@@ -74,19 +73,24 @@
|
||||
-(void)setUpAllChildViewController{
|
||||
_VCS = @[].mutableCopy;
|
||||
|
||||
//新增首页
|
||||
|
||||
XJHomePageV2ViewController * homeVC = [[XJHomePageV2ViewController alloc]init];
|
||||
[self setupChildViewController:homeVC title:@"首页" imageName:@"xjHomeTabBar_nomal" seleceImageName:@"xjHomeTabBar_selected"];
|
||||
|
||||
QuestionViewController * questionVC = [[QuestionViewController alloc]init];
|
||||
[self setupChildViewController:questionVC title:@"咨询" imageName:@"Question_normal_icon" seleceImageName:@"Question_selected_icon"];
|
||||
[self setupChildViewController:questionVC title:@"咨询" imageName:@"questionTabBar_nomal" seleceImageName:@"questionTabBar_selected"];
|
||||
|
||||
|
||||
SosCenterViewController * sosVC = [[SosCenterViewController alloc]init];
|
||||
[self setupChildViewController:sosVC title:@"就医" imageName:@"Question_normal_icon" seleceImageName:@"Question_selected_icon"];
|
||||
XJSosCenterViewController * sosVC = [[XJSosCenterViewController alloc]init];
|
||||
[self setupChildViewController:sosVC title:@"应急" imageName:@"sosCenterTabBar_nomal" seleceImageName:@"sosCenterTabBar_selected"];
|
||||
|
||||
HeartBadViewController * jianceVC = [[HeartBadViewController alloc]init];
|
||||
[self setupChildViewController:jianceVC title:@"监测" imageName:@"Question_normal_icon" seleceImageName:@"Question_selected_icon"];
|
||||
MonitoringWarchViewController * jianceVC = [[MonitoringWarchViewController alloc]init];
|
||||
[self setupChildViewController:jianceVC title:@"监测" imageName:@"monitoringTabBar_nomal" seleceImageName:@"monitoringTabBar_selected"];
|
||||
|
||||
|
||||
MyCenterViewController * centerVC = [[MyCenterViewController alloc] init];
|
||||
[self setupChildViewController:centerVC title:@"我的" imageName:@"mine_normal" seleceImageName:@"mine_selected"];
|
||||
XJMyCenterViewController * centerVC = [[XJMyCenterViewController alloc] init];
|
||||
[self setupChildViewController:centerVC title:@"我的" imageName:@"mineTabBar_nomal" seleceImageName:@"mineTabBar_selected"];
|
||||
|
||||
|
||||
self.viewControllers = _VCS;
|
||||
@@ -105,7 +109,7 @@
|
||||
|
||||
[controller.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:UIColorHex(#21BEBD),NSFontAttributeName:SYSTEMFONT(10.0f)} forState:UIControlStateSelected];
|
||||
//包装导航控制器
|
||||
HQBaseNavigationController *nav = [[HQBaseNavigationController alloc]initWithRootViewController:controller];
|
||||
XJBaseNavigationController *nav = [[XJBaseNavigationController alloc]initWithRootViewController:controller];
|
||||
|
||||
[_VCS addObject:nav];
|
||||
|
||||
@@ -142,6 +146,10 @@
|
||||
return [self.selectedViewController supportedInterfaceOrientations];
|
||||
}
|
||||
|
||||
- (void)selectedQuestion {
|
||||
|
||||
self.selectedIndex = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
#pragma mark - Navigation
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// HQBaseViewController.h
|
||||
// XJBaseViewController.h
|
||||
// healthQuestion
|
||||
//
|
||||
// Created by xulei on 2022/8/11.
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface HQBaseViewController : UIViewController
|
||||
@interface XJBaseViewController : UIViewController
|
||||
|
||||
/**
|
||||
* 修改状态栏颜色
|
||||
+4
-4
@@ -5,14 +5,14 @@
|
||||
// Created by xulei on 2022/8/11.
|
||||
//
|
||||
|
||||
#import "HQBaseViewController.h"
|
||||
#import "HQLoginViewController.h"
|
||||
#import "XJBaseViewController.h"
|
||||
#import "XJLoginViewController.h"
|
||||
|
||||
@interface HQBaseViewController ()<MBProgressHUDDelegate>
|
||||
@interface XJBaseViewController ()<MBProgressHUDDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation HQBaseViewController
|
||||
@implementation XJBaseViewController
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle{
|
||||
return _StatusBarStyle;
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// BaseWebViewVC.h
|
||||
// XJBaseWebViewVC.h
|
||||
// ScarHousekeeper
|
||||
//
|
||||
// Created by 张小万 on 2021/1/21.
|
||||
@@ -25,7 +25,7 @@ typedef enum {
|
||||
- (void)startFunction;
|
||||
@end
|
||||
|
||||
@interface BaseWebViewVC : HQBaseViewController<UIAlertViewDelegate,WKNavigationDelegate, WKUIDelegate, WebJSExport, WKScriptMessageHandler>
|
||||
@interface XJBaseWebViewVC : XJBaseViewController<UIAlertViewDelegate,WKNavigationDelegate, WKUIDelegate, WebJSExport, WKScriptMessageHandler>
|
||||
|
||||
@property (nonatomic, strong) NSString *webUrl;
|
||||
@property (nonatomic, strong) NSString *webTitle;
|
||||
@@ -0,0 +1,501 @@
|
||||
//
|
||||
// XJBaseWebViewVC.m
|
||||
// ScarHousekeeper
|
||||
//
|
||||
// Created by 张小万 on 2021/1/21.
|
||||
//
|
||||
|
||||
#import "XJBaseWebViewVC.h"
|
||||
|
||||
@interface XJBaseWebViewVC ()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
|
||||
|
||||
// 以下三个属性声明后未使用,暂时保留
|
||||
//@property (nonatomic, strong)NSURL *originalUrl;
|
||||
//@property (nonatomic, copy)NSString *videoUrl;
|
||||
//@property (nonatomic, copy)NSString *messageType;
|
||||
|
||||
/// 网页加载进度条
|
||||
@property (nonatomic, strong) UIProgressView *progressView;
|
||||
/// 加载失败占位视图
|
||||
@property (nonatomic, strong) UIView *errorView;
|
||||
|
||||
@end
|
||||
|
||||
// ── 弱引用代理 ──────────────────────────────────────────────────────────────
|
||||
// WKUserContentController 对 addScriptMessageHandler 的 handler 是强引用。
|
||||
// 如果直接传 self,self → wkWebView → configuration → userContentController → self,
|
||||
// 形成循环引用,VC 永远无法释放。
|
||||
// 解决方案:用一个弱引用中间对象转发消息。
|
||||
@interface XJWeakScriptMessageHandler : NSObject <WKScriptMessageHandler>
|
||||
@property (nonatomic, weak) id<WKScriptMessageHandler> delegate;
|
||||
+ (instancetype)handlerWithDelegate:(id<WKScriptMessageHandler>)delegate;
|
||||
@end
|
||||
|
||||
@implementation XJWeakScriptMessageHandler
|
||||
+ (instancetype)handlerWithDelegate:(id<WKScriptMessageHandler>)delegate {
|
||||
XJWeakScriptMessageHandler *handler = [[XJWeakScriptMessageHandler alloc] init];
|
||||
handler.delegate = delegate;
|
||||
return handler;
|
||||
}
|
||||
- (void)userContentController:(WKUserContentController *)userContentController
|
||||
didReceiveScriptMessage:(WKScriptMessage *)message {
|
||||
[self.delegate userContentController:userContentController didReceiveScriptMessage:message];
|
||||
}
|
||||
@end
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@implementation XJBaseWebViewVC
|
||||
|
||||
#pragma mark - LifeCycle
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
self.isHidenNaviBar = false;
|
||||
[self addNavigationItemWithImageNames:@[@"whiteBack_icon"] isLeft:YES target:self action:@selector(backVC) tags:@[@""]];
|
||||
[self addSubviews];
|
||||
if (self.webTitle) {
|
||||
self.navigationItem.title = self.webTitle;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)backVC {
|
||||
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
// 移除进度条 KVO
|
||||
[self.wkWebView removeObserver:self forKeyPath:@"estimatedProgress"];
|
||||
// 移除所有 scriptMessageHandler,配合 XJWeakScriptMessageHandler 彻底避免内存泄漏
|
||||
WKUserContentController *ucc = self.wkWebView.configuration.userContentController;
|
||||
[ucc removeScriptMessageHandlerForName:@"JSCallback"];
|
||||
[ucc removeScriptMessageHandlerForName:@"htmlBack"];
|
||||
[ucc removeScriptMessageHandlerForName:@"finishActivity"];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated{
|
||||
[super viewWillAppear:animated];
|
||||
if (_wkWebView) {
|
||||
_wkWebView.navigationDelegate = self;
|
||||
_wkWebView.UIDelegate = self;
|
||||
_wkWebView.allowsBackForwardNavigationGestures = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated{
|
||||
[super viewWillDisappear:animated];
|
||||
_wkWebView.navigationDelegate = nil;
|
||||
_wkWebView.UIDelegate = nil;
|
||||
// ⚠️ 以下代码会清除整个 App 的所有 Cookie,影响其他模块登录状态,已注释
|
||||
// NSHTTPCookie *cookie;
|
||||
// NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
|
||||
// for (cookie in [storage cookies]) {
|
||||
// [storage deleteCookie:cookie];
|
||||
// }
|
||||
// [[NSURLCache sharedURLCache] removeAllCachedResponses];
|
||||
// [self clearWebViewCache];
|
||||
}
|
||||
|
||||
#pragma mark - Create UI
|
||||
- (void)addSubviews{
|
||||
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
|
||||
WKPreferences *preferences = [[WKPreferences alloc]init];
|
||||
// preferences.javaScriptEnabled = YES;
|
||||
preferences.javaScriptCanOpenWindowsAutomatically = YES;
|
||||
preferences.minimumFontSize = 10;
|
||||
configuration.preferences = preferences;
|
||||
// 允许视频内联播放,避免全屏时布局计算错误导致显示不完整
|
||||
configuration.allowsInlineMediaPlayback = YES;
|
||||
// ── 统一使用 configuration 自带的 userContentController ──────────────────
|
||||
// Bug 修复:原先在下方又新建了 wkUController 并覆盖 configuration.userContentController,
|
||||
// 导致此处注册的 JSCallback / htmlBack 被丢弃,永远收不到 JS 消息。
|
||||
// Bug 修复:改用 XJWeakScriptMessageHandler 代理,防止循环引用内存泄漏。
|
||||
XJWeakScriptMessageHandler *weakHandler = [XJWeakScriptMessageHandler handlerWithDelegate:self];
|
||||
[configuration.userContentController addScriptMessageHandler:weakHandler name:@"JSCallback"];
|
||||
[configuration.userContentController addScriptMessageHandler:weakHandler name:@"htmlBack"];
|
||||
[configuration.userContentController addScriptMessageHandler:weakHandler name:@"finishActivity"]; // 不带参数的调用
|
||||
|
||||
// 原写法(已废弃):直接传 self 会造成循环引用
|
||||
// [configuration.userContentController addScriptMessageHandler:self name:@"JSCallback"];
|
||||
// [configuration.userContentController addScriptMessageHandler:self name:@"htmlBack"];
|
||||
// ────────────────────────────────────────────────────────────────────────
|
||||
|
||||
//防止搜索框自动放大 注入js代码
|
||||
// 原代码中 userController 声明后从未使用,已移除
|
||||
// WKUserContentController *userController = [WKUserContentController new];
|
||||
NSString *jScript = @"var script = document.createElement('meta');script.name = 'viewport';script.content='width=device-width,user-scalable=no';document.getElementsByTagName('head')[0].appendChild(script);";
|
||||
|
||||
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
|
||||
|
||||
// 原写法(已废弃):新建 wkUController 并覆盖 configuration.userContentController,
|
||||
// 导致上方注册的 JSCallback / htmlBack 全部失效
|
||||
// WKUserContentController * wkUController = [[WKUserContentController alloc] init];
|
||||
// [wkUController addScriptMessageHandler: self name: @"finishActivity"];
|
||||
// [wkUController addUserScript:wkUScript];
|
||||
// configuration.userContentController = wkUController;
|
||||
|
||||
[configuration.userContentController addUserScript:wkUScript];
|
||||
|
||||
// 禁用网页长按文字选中和复制粘贴菜单
|
||||
NSString *noSelectJS = @"document.documentElement.style.webkitUserSelect='none';"
|
||||
"document.documentElement.style.webkitTouchCallout='none';";
|
||||
WKUserScript *noSelectScript = [[WKUserScript alloc] initWithSource:noSelectJS
|
||||
injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
|
||||
forMainFrameOnly:NO];
|
||||
[configuration.userContentController addUserScript:noSelectScript];
|
||||
|
||||
self.wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, MyViewHEIGHT) configuration:configuration];
|
||||
if (@available(iOS 16.4, *)) {
|
||||
self.wkWebView.inspectable = YES;
|
||||
}
|
||||
// 伪装成 Safari User-Agent,排查 H5 API 请求因 UA 差异被拒的问题
|
||||
{
|
||||
NSString *osVer = [UIDevice currentDevice].systemVersion;
|
||||
NSString *osVerUnder = [osVer stringByReplacingOccurrencesOfString:@"." withString:@"_"];
|
||||
self.wkWebView.customUserAgent = [NSString stringWithFormat:
|
||||
@"Mozilla/5.0 (iPhone; CPU iPhone OS %@ like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/%@ Mobile/15E148 Safari/604.1",
|
||||
osVerUnder, osVer];
|
||||
}
|
||||
self.wkWebView.navigationDelegate = self;
|
||||
self.wkWebView.UIDelegate = self;
|
||||
if (@available(iOS 11.0, *)) {
|
||||
self.wkWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
[self.view addSubview:self.wkWebView];
|
||||
self.wkWebView.scrollView.bounces = false;//禁止滑动
|
||||
|
||||
// 进度条,居中偏上
|
||||
self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
|
||||
self.progressView.trackTintColor = [UIColor clearColor];
|
||||
[self.view addSubview:self.progressView];
|
||||
[self.progressView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.equalTo(self.wkWebView);
|
||||
make.centerY.equalTo(self.wkWebView).offset(-60);
|
||||
make.width.mas_offset(200);
|
||||
make.height.mas_offset(2);
|
||||
}];
|
||||
|
||||
// KVO 监听加载进度
|
||||
[self.wkWebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
|
||||
|
||||
// 加载失败占位视图(默认隐藏)
|
||||
self.errorView = [[UIView alloc] init];
|
||||
self.errorView.backgroundColor = [UIColor whiteColor];
|
||||
self.errorView.hidden = YES;
|
||||
[self.view addSubview:self.errorView];
|
||||
[self.errorView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.equalTo(self.wkWebView);
|
||||
}];
|
||||
|
||||
UILabel *tipLabel = [[UILabel alloc] init];
|
||||
tipLabel.text = @"网络加载失败\n请检查网络后重试";
|
||||
tipLabel.textAlignment = NSTextAlignmentCenter;
|
||||
tipLabel.numberOfLines = 0;
|
||||
tipLabel.textColor = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:1.0];
|
||||
tipLabel.font = [UIFont systemFontOfSize:15];
|
||||
[self.errorView addSubview:tipLabel];
|
||||
[tipLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.equalTo(self.errorView);
|
||||
make.centerY.equalTo(self.errorView).offset(-40);
|
||||
make.left.greaterThanOrEqualTo(self.errorView).offset(20);
|
||||
make.right.lessThanOrEqualTo(self.errorView).offset(-20);
|
||||
}];
|
||||
|
||||
UIButton *reloadBtn = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[reloadBtn setTitle:@"重新加载" forState:UIControlStateNormal];
|
||||
[reloadBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
reloadBtn.titleLabel.font = [UIFont systemFontOfSize:15];
|
||||
reloadBtn.backgroundColor = [UIColor colorWithRed:0.0 green:0.68 blue:0.41 alpha:1.0];
|
||||
reloadBtn.layer.cornerRadius = 20;
|
||||
reloadBtn.layer.masksToBounds = YES;
|
||||
[reloadBtn addTarget:self action:@selector(reloadWebView) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self.errorView addSubview:reloadBtn];
|
||||
[reloadBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.equalTo(tipLabel.mas_bottom).offset(24);
|
||||
make.right.equalTo(self.errorView.mas_centerX).offset(-8);
|
||||
make.width.mas_offset(110);
|
||||
make.height.mas_offset(40);
|
||||
}];
|
||||
|
||||
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[backBtn setTitle:@"返回" forState:UIControlStateNormal];
|
||||
[backBtn setTitleColor:[UIColor colorWithRed:0.0 green:0.68 blue:0.41 alpha:1.0] forState:UIControlStateNormal];
|
||||
backBtn.titleLabel.font = [UIFont systemFontOfSize:15];
|
||||
backBtn.backgroundColor = [UIColor whiteColor];
|
||||
backBtn.layer.cornerRadius = 20;
|
||||
backBtn.layer.masksToBounds = YES;
|
||||
backBtn.layer.borderWidth = 1;
|
||||
backBtn.layer.borderColor = [UIColor colorWithRed:0.0 green:0.68 blue:0.41 alpha:1.0].CGColor;
|
||||
[backBtn addTarget:self action:@selector(backVC) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self.errorView addSubview:backBtn];
|
||||
[backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.equalTo(reloadBtn);
|
||||
make.left.equalTo(self.errorView.mas_centerX).offset(8);
|
||||
make.width.height.equalTo(reloadBtn);
|
||||
}];
|
||||
|
||||
[self webViewRequest];
|
||||
}
|
||||
|
||||
- (void)finishActivity {
|
||||
// H5 调用 finishActivity 的默认行为:pop 返回上一页
|
||||
// 语义等同于 Android 的 finish(),即关闭当前页面
|
||||
// 子类如需特殊处理(如 dismiss、发通知等),override 此方法即可
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
|
||||
- (void)reloadWebView {
|
||||
self.errorView.hidden = YES;
|
||||
[self webViewRequest];
|
||||
}
|
||||
|
||||
- (void)webViewRequest{
|
||||
[self clearWebViewCache];
|
||||
NSString *urlString = self.webUrl;
|
||||
DLog(@"[WebView] 请求加载: %@", urlString);
|
||||
[self hiddenAllMBProgressHUD];
|
||||
if (urlString.length > 0) {
|
||||
[self showMBProgressHUDOnlyWithString:@"加载中"];
|
||||
NSURL *url = [NSURL URLWithString:urlString];
|
||||
if (!url) {
|
||||
DLog(@"[WebView] URL 无效: %@", urlString);
|
||||
}
|
||||
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
|
||||
if (self.wkWebView) {
|
||||
[self.wkWebView loadRequest:urlRequest];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark - KVO
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
||||
if ([keyPath isEqualToString:@"estimatedProgress"]) {
|
||||
float progress = [change[NSKeyValueChangeNewKey] floatValue];
|
||||
self.progressView.alpha = 1.0;
|
||||
[self.progressView setProgress:progress animated:YES];
|
||||
if (progress >= 1.0) {
|
||||
// 加载完成后渐隐进度条
|
||||
[UIView animateWithDuration:0.3 delay:0.2 options:0 animations:^{
|
||||
self.progressView.alpha = 0;
|
||||
} completion:^(BOOL finished) {
|
||||
[self.progressView setProgress:0 animated:NO];
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - WKNavigationDelegate
|
||||
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
|
||||
if ([message.name isEqualToString:@"JSCallback"]) {
|
||||
if (message.body) {
|
||||
NSData *jsonData = [message.body dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError *err;
|
||||
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
|
||||
options:NSJSONReadingMutableContainers
|
||||
error:&err];
|
||||
if(err) {
|
||||
}
|
||||
WkJSMessageType messageType = [[dic objectForKey:@"messageType"] intValue];
|
||||
switch (messageType) {
|
||||
case WkJSMessageTypeBack:{
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ([message.name isEqualToString:@"htmlBack"]) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"fromWebToReloadData" object:nil];
|
||||
|
||||
} else if ([message.name isEqualToString:@"finishActivity"]) {
|
||||
// JS 调用 window.webkit.messageHandlers.finishActivity.postMessage({}) 时触发
|
||||
// 调用 finishActivity 方法,子类可 override 实现各自的关闭逻辑
|
||||
// 基类默认实现为空,不做任何操作
|
||||
[self finishActivity];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - WKScriptMessageHandler
|
||||
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
|
||||
[self hiddenAllMBProgressHUD];
|
||||
if (!navigationAction.targetFrame.isMainFrame) {
|
||||
[webView loadRequest:navigationAction.request];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
|
||||
DLog(@"[WebView] 开始加载: %@", webView.URL);
|
||||
self.errorView.hidden = YES;
|
||||
if (!self.webTitle) {
|
||||
self.title = @"加载中...";
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
|
||||
DLog(@"[WebView] 加载完成: %@", webView.URL);
|
||||
[self hiddenAllMBProgressHUD];
|
||||
self.errorView.hidden = YES;
|
||||
if (!self.webTitle) {
|
||||
self.title = webView.title;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(nonnull NSError *)error{
|
||||
NSLog(@"[WebView] 加载失败 URL=%@ errorCode=%ld domain=%@ desc=%@",
|
||||
webView.URL, (long)error.code, error.domain, error.localizedDescription);
|
||||
[self hiddenAllMBProgressHUD];
|
||||
// NSURLErrorCancelled (-999) 是主动取消导航(如跳转第三方 App),不算真实网络错误
|
||||
if (error.code != NSURLErrorCancelled) {
|
||||
self.errorView.hidden = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
|
||||
NSLog(@"[WebView] 导航失败 URL=%@ errorCode=%ld domain=%@ desc=%@",
|
||||
webView.URL, (long)error.code, error.domain, error.localizedDescription);
|
||||
[self hiddenAllMBProgressHUD];
|
||||
// NSURLErrorCancelled (-999) 是主动取消导航,不算真实网络错误
|
||||
if (error.code != NSURLErrorCancelled) {
|
||||
self.errorView.hidden = NO;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - 白屏修复
|
||||
|
||||
/**
|
||||
* 拦截所有导航请求,处理非 HTTP/HTTPS scheme。
|
||||
*
|
||||
* 问题根源:
|
||||
* 银行 H5 点击支付/跳转按钮时,会触发 alipay:// weixin:// tel:// 等 URL Scheme。
|
||||
* WKWebView 默认会尝试自己加载这些 scheme,加载失败后清空页面内容 → 永久白屏。
|
||||
*
|
||||
* 解决方案:
|
||||
* 在此方法中拦截非 HTTP/HTTPS 的请求,交由系统(UIApplication)处理,
|
||||
* WKWebView 自身取消该次导航,页面内容保持不变。
|
||||
*/
|
||||
- (void)webView:(WKWebView *)webView
|
||||
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
|
||||
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
|
||||
|
||||
NSURL *url = navigationAction.request.URL;
|
||||
NSString *scheme = url.scheme.lowercaseString;
|
||||
|
||||
// HTTP / HTTPS:正常加载,交给 WKWebView 处理
|
||||
if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) {
|
||||
decisionHandler(WKNavigationActionPolicyAllow);
|
||||
return;
|
||||
}
|
||||
|
||||
// about:blank:WKWebView 内部使用,直接放行
|
||||
if ([scheme isEqualToString:@"about"]) {
|
||||
decisionHandler(WKNavigationActionPolicyAllow);
|
||||
return;
|
||||
}
|
||||
|
||||
// 其他 scheme(alipay:// weixin:// tel:// mailto:// 等):
|
||||
// 交由系统打开对应 App 或拨号,WKWebView 取消此次导航,避免白屏
|
||||
if ([[UIApplication sharedApplication] canOpenURL:url]) {
|
||||
[[UIApplication sharedApplication] openURL:url
|
||||
options:@{}
|
||||
completionHandler:nil];
|
||||
}
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
}
|
||||
|
||||
/**
|
||||
* WebContent 进程被系统终止时的兜底处理。
|
||||
*
|
||||
* 触发场景:
|
||||
* 设备内存严重不足时,系统会强制 kill 掉 WKWebView 的 WebContent 进程。
|
||||
* 此时 WKWebView 会立即变成空白页,且无法响应任何操作。
|
||||
* 若不处理,用户只能退出页面重新进入。
|
||||
*
|
||||
* 解决方案:
|
||||
* 检测到进程终止后,重新加载当前 URL,让用户无感知恢复。
|
||||
*/
|
||||
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
|
||||
NSLog(@"[XJBaseWebViewVC] WebContent 进程被系统终止,自动 reload");
|
||||
// 重新加载,恢复页面内容
|
||||
[webView reload];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark - ACTION
|
||||
- (void)ToClickNavRight:(UIButton *)button{
|
||||
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - 自定义
|
||||
- (void)onBackClicked{
|
||||
if (self.wkWebView.canGoBack) {
|
||||
[self.wkWebView goBack];
|
||||
} else {
|
||||
// 原写法:只清缓存没有 pop,页面会卡住
|
||||
// [self clearWebViewCache];
|
||||
[self clearWebViewCache];
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearWebViewCache{
|
||||
if (iOS9Later) {
|
||||
NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
|
||||
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
|
||||
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
|
||||
DLog(@"-----clear webView cache success------");
|
||||
}];
|
||||
} else {
|
||||
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
||||
NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"];
|
||||
NSError *errors;
|
||||
[[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors];
|
||||
if (!errors) {
|
||||
DLog(@"-----clear wkWebView cache success------");
|
||||
}
|
||||
}
|
||||
}
|
||||
- (NSString *)URLEncodedString:(NSString *)urlString{
|
||||
NSString *encodePath;
|
||||
|
||||
encodePath = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
||||
return encodePath;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - SETTER
|
||||
// setRightType: 与自动合成的 setter 完全相同,无需 override,保留注释备查
|
||||
//- (void)setRightType:(RightNavType)rightType{
|
||||
// _rightType = rightType;
|
||||
//}
|
||||
|
||||
- (void)setWebUrl:(NSString *)webUrl{
|
||||
_webUrl = webUrl;
|
||||
[self webViewRequest];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomSystemEvaluateModel.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/19.
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomSystemEvaluateModel.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/19.
|
||||
//
|
||||
|
||||
+5
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTUIHistoryModel.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/21.
|
||||
//
|
||||
@@ -36,6 +36,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (nonatomic, copy) NSString * title;
|
||||
@property (nonatomic, assign) CGFloat systemHeight;
|
||||
@property (nonatomic, assign) MessageType msgType;
|
||||
//地图
|
||||
@property (nonatomic, assign) CGFloat Longitude;
|
||||
@property (nonatomic, assign) CGFloat Latitude;
|
||||
@property (nonatomic, copy) NSString * address;//地址描述
|
||||
|
||||
@end
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTUIHistoryModel.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/21.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTextModel.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/19.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTextModel.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/19.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTUIModel.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/17.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTUIModel.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/17.
|
||||
//
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTUIBaseMessageController.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/12.
|
||||
//
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CustomTUIBaseMessageController : HQBaseViewController
|
||||
@interface CustomTUIBaseMessageController : XJBaseViewController
|
||||
|
||||
@property(nonatomic, strong) NSString * groupID;
|
||||
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTUIBaseMessageController.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/12.
|
||||
//
|
||||
@@ -84,7 +84,7 @@
|
||||
|
||||
[parmDic setObject:self.groupID forKey:@"groupId"];
|
||||
|
||||
JKCQAPI * agreeAPI = [[JKCQAPI alloc] init:self tag:@"HISTORYAPI" NeedToken:@""];
|
||||
XJPNetAPI * agreeAPI = [[XJPNetAPI alloc] init:self tag:@"HISTORYAPI" NeedToken:@""];
|
||||
|
||||
[agreeAPI GetAllHistoryChatRecord:nil];
|
||||
|
||||
@@ -134,8 +134,8 @@
|
||||
}
|
||||
|
||||
for (MsgBody *msgBody in model.MsgBody) {
|
||||
NSLog(@"MsgType: %@", msgBody.MsgType);
|
||||
NSLog(@"MsgContent Data - title: %@", msgBody.MsgContent.Text);
|
||||
DLog(@"MsgType: %@", msgBody.MsgType);
|
||||
DLog(@"MsgContent Data - title: %@", msgBody.MsgContent.Text);
|
||||
|
||||
if([msgBody.MsgType isEqualToString:@"TIMTextElem"]) //文本消息
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTUIHistoryTable.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/14.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomTUIHistoryTable.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/14.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomAudioCell.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/14.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomAudioCell.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/14.
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomDoctorIDTableViewCell.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/7/5.
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomDoctorIDTableViewCell.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/7/5.
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomHealthFileVideoCell.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/14.
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomHealthFileVideoCell.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/14.
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomHealthReportVideoCell.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/14.
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomHealthReportVideoCell.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/14.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// CustomMapMessageCell.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/12.
|
||||
//
|
||||
|
||||
#import <TIMCommon/TUIBubbleMessageCell.h>
|
||||
#import <TIMCommon/TUIMessageCell.h>
|
||||
#import "CustomMapMessageCellData.h"
|
||||
#import "CustomTUIHistoryModel.h"
|
||||
|
||||
|
||||
@interface CustomMapMessageCell : UITableViewCell
|
||||
|
||||
@interface CustomMapMessageCell : TUIBubbleMessageCell
|
||||
|
||||
@property (nonatomic, strong) CustomTUIHistoryModel * model;
|
||||
|
||||
@end
|
||||
|
||||
+220
-42
@@ -1,79 +1,257 @@
|
||||
//
|
||||
// CustomMapMessageCell.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/12.
|
||||
//
|
||||
|
||||
#import "CustomMapMessageCell.h"
|
||||
#import "XJWeChatManager.h"
|
||||
#import <SDWebImage/SDImageCache.h>
|
||||
#import<CommonCrypto/CommonDigest.h>
|
||||
|
||||
@interface CustomMapMessageCell ()
|
||||
|
||||
@property (nonatomic, strong) UIImageView * heardImage;
|
||||
|
||||
@property (nonatomic, strong) UILabel * connetLabel;
|
||||
|
||||
@property (nonatomic, strong) UILabel * myTextLabel;
|
||||
@property (nonatomic, strong) UIImageView * mapImage;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CustomMapMessageCell
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[super awakeFromNib];
|
||||
// Initialization code
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self) {
|
||||
|
||||
[self createUI];
|
||||
|
||||
|
||||
[self createMapUI];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)createUI {
|
||||
- (void)createMapUI {
|
||||
|
||||
self.heardImage = [[UIImageView alloc] init];
|
||||
self.heardImage.backgroundColor = KRedColor;
|
||||
[self.contentView addSubview:self.heardImage];
|
||||
self.heardImage.layer.cornerRadius = 15;
|
||||
self.heardImage.layer.masksToBounds = true;
|
||||
[self.heardImage mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
// 隐藏默认气泡图片,改用白色圆角背景
|
||||
self.bubbleView.image = nil;
|
||||
self.container.backgroundColor = KWhiteColor;
|
||||
self.container.layer.cornerRadius = 8;
|
||||
self.container.layer.masksToBounds = YES;
|
||||
|
||||
make.left.mas_equalTo(@15);
|
||||
make.top.mas_equalTo(@8);
|
||||
make.height.width.mas_equalTo(@30);
|
||||
self.myTextLabel = [[UILabel alloc] init];
|
||||
self.myTextLabel.font = SYSTEMFONT(15);
|
||||
self.myTextLabel.textColor = CFontColor1;
|
||||
self.myTextLabel.numberOfLines = 0;
|
||||
[self.container addSubview:self.myTextLabel];
|
||||
[self.myTextLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_offset(10);
|
||||
make.top.mas_offset(10);
|
||||
make.right.mas_offset(-10);
|
||||
}];
|
||||
|
||||
self.connetLabel = [[UILabel alloc] init];
|
||||
self.connetLabel.backgroundColor = KRedColor;
|
||||
[self.contentView addSubview:self.heardImage];
|
||||
self.connetLabel.layer.cornerRadius = 10;
|
||||
self.connetLabel.layer.masksToBounds = true;
|
||||
self.connetLabel.numberOfLines = 0;
|
||||
[self.connetLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
self.mapImage = [[UIImageView alloc] init];
|
||||
self.mapImage.backgroundColor = KRedColor;
|
||||
[self.container addSubview:self.mapImage];
|
||||
[self.mapImage mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.right.bottom.mas_offset(0);
|
||||
make.top.mas_equalTo(self.myTextLabel.mas_bottom);
|
||||
}];
|
||||
|
||||
make.left.mas_equalTo(self.heardImage.right).offset(8);
|
||||
// 长按转发到微信
|
||||
// TUIChat 框架把长按手势注释掉了,这里重新加上。
|
||||
// 需要让 container 上已有的 tap 手势等 longPress 失败后再触发,否则 tap 会抢走触摸。
|
||||
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPress:)];
|
||||
longPress.minimumPressDuration = 0.5;
|
||||
[self.container addGestureRecognizer:longPress];
|
||||
|
||||
for (UIGestureRecognizer *g in self.container.gestureRecognizers) {
|
||||
if ([g isKindOfClass:[UITapGestureRecognizer class]]) {
|
||||
[g requireGestureRecognizerToFail:longPress];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - TUIChat 实时聊天回调
|
||||
|
||||
- (void)fillWithData:(CustomMapMessageCellData *)data {
|
||||
// 不显示名字标签,让白色卡片紧贴顶部(父类 layoutSubviews 用 frame 布局,需在 data 层面关闭)
|
||||
data.showName = NO;
|
||||
[super fillWithData:data];
|
||||
// 清掉父类设回来的气泡图,让 container 白底露出来
|
||||
self.bubbleView.image = nil;
|
||||
|
||||
self.myTextLabel.text = data.text.length > 0 ? data.text : @"我的位置";
|
||||
[self.mapImage sd_setImageWithURL:[NSURL URLWithString:data.MapPictureImg] placeholderImage:nil];
|
||||
}
|
||||
|
||||
#pragma mark - 历史记录回调
|
||||
|
||||
- (void)setModel:(CustomTUIHistoryModel *)model {
|
||||
_model = model;
|
||||
|
||||
self.myTextLabel.text = _model.address.length > 0 ? _model.address : @"我的位置";
|
||||
|
||||
NSString * MapPictureImg = [self mapLocationImage:_model.Longitude Withlation:_model.Latitude];
|
||||
[self.mapImage sd_setImageWithURL:[NSURL URLWithString:MapPictureImg] placeholderImage:nil];
|
||||
|
||||
// 历史记录:手动设置头像和名字
|
||||
self.avatarView.image = [UIImage imageNamed:@"heard_man"];
|
||||
self.nameLabel.text = @"全科医生";
|
||||
self.nameLabel.hidden = NO;
|
||||
|
||||
if (_model.isSelf) {
|
||||
self.avatarView.hidden = NO;
|
||||
[self.avatarView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.height.width.mas_offset(40);
|
||||
make.top.mas_equalTo(@10);
|
||||
make.right.mas_equalTo(self.contentView.mas_right).offset(-10);
|
||||
}];
|
||||
self.nameLabel.textAlignment = NSTextAlignmentRight;
|
||||
[self.nameLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.right.mas_equalTo(self.avatarView.mas_left).offset(-10);
|
||||
make.top.mas_equalTo(@10);
|
||||
make.width.mas_equalTo(@245.0);
|
||||
make.height.mas_offset(13);
|
||||
}];
|
||||
[self.connetLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
|
||||
[self.container mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(self.nameLabel.mas_bottom).offset(8);
|
||||
make.width.mas_offset(245);
|
||||
make.right.mas_equalTo(self.avatarView.mas_left).offset(-10);
|
||||
make.height.mas_offset(170);
|
||||
}];
|
||||
} else {
|
||||
self.avatarView.hidden = NO;
|
||||
[self.avatarView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(@15);
|
||||
make.top.mas_equalTo(@8);
|
||||
make.height.width.mas_equalTo(@40);
|
||||
}];
|
||||
self.nameLabel.textAlignment = NSTextAlignmentLeft;
|
||||
[self.nameLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(self.avatarView.mas_right).offset(10);
|
||||
make.top.mas_equalTo(@10);
|
||||
make.width.mas_equalTo(@300.0);
|
||||
make.height.mas_offset(13);
|
||||
}];
|
||||
[self.container mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.mas_equalTo(self.avatarView.mas_right).offset(10);
|
||||
make.width.mas_offset(245);
|
||||
make.top.mas_equalTo(self.nameLabel.mas_bottom).offset(8);
|
||||
make.height.mas_offset(170);
|
||||
}];
|
||||
}
|
||||
|
||||
// 加载头像
|
||||
NSString * photo = [NSString stringWithFormat:@"%@%@", ResourceAddress, _model.avatar];
|
||||
photo = [photo stringByReplacingOccurrencesOfString:@"\\" withString:@"/"];
|
||||
NSString *encodedString3 = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)photo, (CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]", NULL, kCFStringEncodingUTF8));
|
||||
[self.avatarView sd_setImageWithURL:[NSURL URLWithString:encodedString3] placeholderImage:PLACEHOLD_IMG];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - 地图静态图
|
||||
|
||||
- (NSString *)mapLocationImage:(CGFloat)longLation Withlation:(CGFloat)lation {
|
||||
NSString * staciUrl = @"https://restapi.amap.com/v3/staticmap?key=e9926badd26aaa766d13439c88a83f2d";
|
||||
NSString * mapKey = @"e9926badd26aaa766d13439c88a83f2d";
|
||||
NSString * loctaionUrl = @"https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png";
|
||||
|
||||
NSString * needMdString = [NSString stringWithFormat:@"key=%@&location=%f,%f&markers=-1,%@,0:%f,%f&size=700*500&zoom=15124d58f7223ac9738312a8d187a21f2b",mapKey,longLation,lation,loctaionUrl,longLation,lation];
|
||||
|
||||
NSString * mapUrl = [NSString stringWithFormat:@"%@&location=%f,%f&markers=-1,%@,0:%f,%f&size=700*500&zoom=15&sig=%@",staciUrl,longLation,lation,loctaionUrl,longLation,lation,[self md5:needMdString]];
|
||||
|
||||
return mapUrl;
|
||||
}
|
||||
|
||||
- (NSString *)md5:(NSString *)str
|
||||
{
|
||||
const char *cStr = [str UTF8String];
|
||||
unsigned char result[16];
|
||||
CC_MD5(cStr, strlen(cStr), result);
|
||||
return [NSString stringWithFormat:
|
||||
@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
result[0], result[1], result[2], result[3],
|
||||
result[4], result[5], result[6], result[7],
|
||||
result[8], result[9], result[10], result[11],
|
||||
result[12], result[13], result[14], result[15]
|
||||
];
|
||||
}
|
||||
|
||||
#pragma mark - 长按转发微信
|
||||
|
||||
- (void)onLongPress:(UILongPressGestureRecognizer *)gesture {
|
||||
if (gesture.state != UIGestureRecognizerStateBegan) return;
|
||||
|
||||
if (![[XJWeChatManager sharedManager] isWeChatInstalled]) {
|
||||
[EasyTextView showErrorText:@"未安装微信"];
|
||||
return;
|
||||
}
|
||||
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"转发到微信" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
[self shareToWeChat];
|
||||
}]];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
|
||||
|
||||
UIViewController *topVC = [self topViewController];
|
||||
[topVC presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)shareToWeChat {
|
||||
NSString *address;
|
||||
CGFloat lat = 0, lng = 0;
|
||||
NSString *imageKey;
|
||||
|
||||
// 实时聊天数据
|
||||
CustomMapMessageCellData *data = (CustomMapMessageCellData *)self.messageData;
|
||||
if ([data isKindOfClass:[CustomMapMessageCellData class]]) {
|
||||
address = data.text.length > 0 ? data.text : @"我的位置";
|
||||
lat = data.latitude;
|
||||
lng = data.longitude;
|
||||
imageKey = data.MapPictureImg;
|
||||
}
|
||||
// 历史记录数据
|
||||
else if (_model) {
|
||||
address = _model.address.length > 0 ? _model.address : @"我的位置";
|
||||
lat = _model.Latitude;
|
||||
lng = _model.Longitude;
|
||||
imageKey = [self mapLocationImage:_model.Longitude Withlation:_model.Latitude];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *encodedAddress = [address stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
||||
NSString *mapUrl = [NSString stringWithFormat:@"https://uri.amap.com/marker?position=%f,%f&name=%@",
|
||||
lng, lat, encodedAddress ?: @"位置"];
|
||||
|
||||
UIImage *thumb = [[SDImageCache sharedImageCache] imageFromCacheForKey:imageKey];
|
||||
|
||||
[[XJWeChatManager sharedManager] shareWebpageWithTitle:address
|
||||
desc:[NSString stringWithFormat:@"经度:%.6f 纬度:%.6f", lng, lat]
|
||||
webpageUrl:mapUrl
|
||||
thumbImage:thumb
|
||||
toScene:0
|
||||
completion:^(BOOL success, NSString * _Nullable errorMsg) {
|
||||
if (!success && errorMsg.length > 0) {
|
||||
[EasyTextView showErrorText:errorMsg];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (UIViewController *)topViewController {
|
||||
UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
|
||||
while (rootVC.presentedViewController) {
|
||||
rootVC = rootVC.presentedViewController;
|
||||
}
|
||||
if ([rootVC isKindOfClass:[UINavigationController class]]) {
|
||||
return [(UINavigationController *)rootVC topViewController];
|
||||
}
|
||||
if ([rootVC isKindOfClass:[UITabBarController class]]) {
|
||||
UIViewController *selected = [(UITabBarController *)rootVC selectedViewController];
|
||||
if ([selected isKindOfClass:[UINavigationController class]]) {
|
||||
return [(UINavigationController *)selected topViewController];
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
return rootVC;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomReviceTableViewCell.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/7/5.
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomReviceTableViewCell.m
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/7/5.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomSystemImageCell.h
|
||||
// EscortProject
|
||||
// XinjiangProject
|
||||
//
|
||||
// Created by Apple on 2024/6/14.
|
||||
//
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user