Compare commits

...

210 Commits

Author SHA1 Message Date
edwinQQQ
96c44cb032 删除阿拉伯语首充相关图像资源及其配置文件;在 UIImage+Utils.m 中优化语言图像处理逻辑,新增对葡萄牙语的支持;在多个文件中添加对葡萄牙语的支持,包括本地化字符串和 InfoPlist 配置;更新 UI 组件以适应新的语言设置,确保用户界面的一致性和可用性。 2025-07-15 14:35:05 +08:00
edwinQQQ
16f9041ba9 chore: 更新 .gitignore 文件,移除不必要的包文件类型;新增邮箱验证码登录流程和 OAuth/Ticket 认证系统 API 文档;更新勋章相关逻辑,优化用户信息获取失败处理;调整勋章展示逻辑,支持多等级高亮功能。 2025-07-14 17:37:10 +08:00
edwinQQQ
99db078b62 feat(勋章): 新增多等级高亮功能并优化勋章展示逻辑
refactor(勋章排行): 重构排行榜分页加载和刷新逻辑

fix(会话): 优化官方账号判断逻辑和跳转处理

style(UI): 调整勋章排行榜和游戏菜单UI布局

chore: 更新Podfile配置和bitcode框架列表
2025-07-03 19:35:17 +08:00
edwinQQQ
e32e5653fd change page item limit 2025-07-03 18:04:56 +08:00
edwinQQQ
8a096239da 新增 next-chat.mdc 文件以定义对话上下文的规则;在 Assets.xcassets 中添加多个图像资源及其对应的 Contents.json 文件;更新 AttachmentModel.h 中的枚举值以修正飘屏消息类型;在 SessionViewController.h 和 SessionViewController.m 中添加 userInfo 属性并调整相关逻辑;在 SessionListViewController.h 和 SessionListViewController.m 中优化会话列表的展示逻辑;在多个模型和视图文件中进行小幅调整以提升代码可读性和一致性。 2025-07-02 15:52:48 +08:00
edwinQQQ
f0dad8886f 更新 MedalsModel.h 和 MedalsModel.m,新增 expireDateString 方法以格式化过期时间;在 MedalsCollectionViewCell.m 和 MedalsCyclePagerCell.m 中优化 MP4 和图片的显示逻辑,增强降级处理;在 MedalsDetailView.m 中更新勋章显示逻辑,使用新的 URL 优先级;在 MedalsLevelIndicatorView.h 和 MedalsLevelIndicatorView.m 中新增重置等级指示器的方法;在 MedalsWearingControlCollectionViewCell.m 和 MedalsWearingListCollectionViewCell.m 中实现新的显示逻辑,支持 MP4 和图片的降级处理;在 NSString+Utils.h 和 NSString+Utils.m 中新增图片格式验证方法,提升代码健壮性和可读性。 2025-06-27 19:56:03 +08:00
edwinQQQ
0d6570a086 更新 .vscode/settings.json 文件,新增拼写检查词汇 "Defalut" 和 "MAXFLOAT";在 XPRoomSendTextView.m 中调整约束逻辑,确保 editTextFiled 和 imageButton 的布局正确;在 XPRoomMessageTableViewCell.m 中优化消息内容标签的约束,确保气泡和内容标签的布局一致性,增强代码可读性和健壮性。 2025-06-27 16:15:12 +08:00
edwinQQQ
f52af5d620 更新 YUMIHtmlUrl.h 和 YUMIHtmlUrl.m,新增首充相关的 URL 类型和路径;在 FeedBackViewController.h 和 FeedBackViewController.m 中,调整属性类型为强引用以增强内存管理;重构 FeedBackViewController 的视图设置逻辑,添加子视图的初始化方法以提高代码可读性;移除不再使用的 FeedBackViewController.xib 文件,优化项目结构;在 XPGiftBarView.h 和 XPGiftBarView.m 中,移除首充按钮相关代码,替换为新的首充视图逻辑;更新 XPWebViewController.h 和 XPWebViewController.m,调整 webview 属性为可写以支持动态更新;在 FirstRechargeManager.m 中,优化首充状态检查逻辑,确保在调试模式下始终显示首充信息。 2025-06-27 11:33:16 +08:00
edwinQQQ
86094da26f 添加首充管理功能,新增 FirstRechargeManager 和相关模型以支持首充监控;在多个模块中集成首充监控逻辑,确保在登录和页面加载时正确启动和停止监控;移除不再使用的首充相关代码,优化代码结构和可读性。 2025-06-26 11:08:21 +08:00
edwinQQQ
6f59274ca0 更新 XPRoomMessageParser.m,优化房间表情属性创建逻辑,简化代码结构;新增 createImageAttribute:size: 方法以支持自定义图像大小,增强代码可读性和灵活性;调整图像处理逻辑,确保在不同条件下正确展示表情图像,保持代码一致性。 2025-06-25 15:22:09 +08:00
edwinQQQ
e01148a3a9 更新 pi_area_info.json,新增突尼斯地区信息;更新 Assets.xcassets 中的 Contents.json,修复幸运数字图像的文件名;移除多个文件中的调试代码以优化勋章展示逻辑,保持代码结构一致性;在 XPRoomFaceTool.m 中改进表情文件加载路径和错误处理,增强代码健壮性;在 XPRoomFaceViewController.m 中添加消息发送错误日志;更新 XPRoomMessageContainerView.m 和 XPRoomMessageParser.m,调整索引类型以提高代码一致性。 2025-06-25 14:29:23 +08:00
edwinQQQ
1190e0f6d9 更新 XPMineUserInfoHeaderView.m,调整勋章显示逻辑,允许最多显示 10 个勋章;在 UserRoomCardViewController.m 中新增 UserRoomCardMedalCell 以支持勋章的展示,优化勋章区域的高度计算和更新逻辑,保持代码结构一致性。 2025-06-24 18:50:45 +08:00
edwinQQQ
c5d966317b 更新 XPMineUserInfoHeaderView.m,新增 UIScrollView 作为勋章展示的容器,调整勋章 StackView 的布局逻辑以适应 ScrollView,更新勋章显示方法以处理勋章的内容尺寸,保持代码结构一致性。 2025-06-24 17:10:11 +08:00
edwinQQQ
6573c0f6fe 更新 XPMineUserInfoHeaderView.m,新增 medalsStackView 和 medalMP4Views 属性以支持勋章展示逻辑;添加 medalsHeight 方法计算勋章高度;实现 setupMedalsArea 方法以配置勋章视图;更新 updateMedalsDisplay 方法以处理勋章的 MP4 和图片展示,保持代码结构一致性。同时,更新 .vscode/settings.json 文件以添加拼写检查词汇。 2025-06-24 16:45:26 +08:00
edwinQQQ
7810057542 更新 MedalsViewController.m,移除调试代码以优化勋章展示逻辑;在 XPMineUserInfoHeaderView.m 中新增 medalsStackView 和 userMedals 属性以支持用户勋章的显示;在 UserInfoModel.m 中更新 medalsPic 属性以增强模型的兼容性,保持代码结构一致性。 2025-06-24 15:42:56 +08:00
edwinQQQ
059305d3df 更新 MedalsViewController.m,新增其他用户勋章的显示逻辑,包括 MP4 播放和图片展示,优化相关方法以提升用户体验,保持代码结构一致性。同时,更新 MedalsWearingControlCollectionViewCell.m,移除调试背景颜色设置,保持代码整洁。 2025-06-24 15:01:33 +08:00
edwinQQQ
a15d6b34ed 更新 MedalsRankViewController.m,添加勋章排行视图的点击手势和回调处理,优化用户交互体验,保持代码结构一致性。 2025-06-23 19:09:45 +08:00
edwinQQQ
6d0122f3d1 更新 MedalsViewController.m,调整背景约束和底部勋章列表高度以适应不同显示类型,优化底部背景图像的拉伸处理,保持代码结构一致性。 2025-06-23 18:57:05 +08:00
edwinQQQ
286e68b5e3 更新 MedalsCyclePagerCell 和 MedalsViewController 以优化勋章展示和自动轮播功能,调整可见性管理逻辑,确保在视图切换时正确处理播放状态,保持代码结构一致性。 2025-06-23 18:43:17 +08:00
edwinQQQ
c0500397b6 删除不再使用的资源文件,包括多个图像集和其对应的 Contents.json 文件,更新 MedalsModel.h 和 MedalsModel.m 以支持使用勋章的类型,新增 MedalsCyclePagerCell 组件以优化勋章展示,保持代码结构一致性。 2025-06-23 16:36:39 +08:00
edwinQQQ
f62af24c48 更新勋章相关模型和视图,添加对使用勋章的支持,优化可见性管理和状态更新逻辑,保持代码结构一致性。 2025-06-23 15:55:11 +08:00
edwinQQQ
a72c010b56 新增勋章 VIP 控制相关的资源,包括 medals_control_vip4、medals_control_vip6、medals_control_vip7 和 medals_control_vip9 的 Contents.json 文件及其对应的 vip@3x.png 图片,保持代码结构一致性。 2025-06-23 14:29:08 +08:00
edwinQQQ
143ad115bc 新增勋章排行相关的 UI 组件,包括 MedalsRankViewController、MedalsRankTopView 和 MedalsRankListCell,更新 MedalsViewController 以支持展示其他用户的勋章信息,优化相关逻辑以提升用户体验,保持代码结构一致性。 2025-06-20 18:44:20 +08:00
edwinQQQ
4c76813273 新增勋章相关的 UI 组件,包括 MedalsWearingViewController、MedalsWearingControlCollectionViewCell 和 MedalsWearingListCollectionViewCell,更新相关逻辑以支持勋章的使用状态管理和展示,保持代码结构一致性。 2025-06-19 19:22:56 +08:00
edwinQQQ
da8d88347e 更新 Api+Medals.m 中的请求路径为 "medal/square",修改 MedalsViewController.m 中的导航栏标题以支持勋章广场,新增本地化字符串 "20.20.61_text_10" 以表示勋章广场,保持代码结构一致性。 2025-06-19 14:09:36 +08:00
edwinQQQ
06fecf1bf4 调整 MedalsDetailView.m 中的高度约束以适应内容,优化 MedalsLevelIndicatorView.m 中的图片视图创建和加载逻辑,新增缓存图片 URL 属性以支持延迟加载,确保代码结构一致性。 2025-06-19 11:49:25 +08:00
edwinQQQ
c978a8c355 优化 UIImage+Utils.m 中的灰度图像处理逻辑,调整 MedalsLevelIndicatorView.m 中的图片视图约束和间距,更新图像加载逻辑以使用裁剪后的图像,保持代码结构一致性。 2025-06-19 11:28:07 +08:00
edwinQQQ
a0fc15fefd 更新 MedalsCollectionViewCell 和 MedalsDetailView 以支持带图片的等级指示器,新增 MedalsLevelIndicatorType 枚举以区分指示器类型,优化手势识别功能,确保用户体验流畅,保持代码结构一致性。 2025-06-18 19:47:39 +08:00
edwinQQQ
c1b9dd3d9f 新增手势识别功能以处理背景和内容区域的点击事件,确保用户体验流畅。重写 removeFromSuperview 方法以停止 MP4 播放并释放资源,添加 dealloc 方法以确保资源正确释放,保持代码结构一致性。 2025-06-18 19:00:01 +08:00
edwinQQQ
887bb19056 新增 MedalsDetailView 和 MedalsLevelIndicatorView 组件,更新 MedalsCollectionViewCell 以支持 MP4 播放控制和可见性管理,优化相关逻辑以提升用户体验,保持代码结构一致性。 2025-06-18 18:31:13 +08:00
edwinQQQ
413b2c6944 新增等级指示器视图和容器视图,更新 MedalsCollectionViewCell 以集成等级指示器功能,支持等级选择回调。更新 .vscode/settings.json 文件以包含新组件 QGVAP 的配置,保持代码结构一致性。 2025-06-18 17:11:13 +08:00
edwinQQQ
89d9b57dea 更新 Podfile 以注释掉不再使用的 ZLCollectionViewFlowLayout 依赖,同时新增勋章相关功能,包括勋章使用、广场、排行和管理列表的 API 方法,新增 MedalsModel、MedalsPresenter 和 MedalsViewController 相关文件,保持代码结构一致性。新增勋章相关的 UI 组件和本地化字符串支持。 2025-06-18 16:28:13 +08:00
edwinQQQ
8c0276a208 优化数组操作,新增 NSMutableArray 的安全方法,包括安全移除、插入和替换对象,确保在索引超出范围时不发生崩溃。更新相关文件以使用新方法,保持代码结构一致性。 2025-06-16 17:30:20 +08:00
edwinQQQ
68ce148abb 新增勋章相关功能,包括勋章使用、广场、排行和管理列表的 API 方法,更新 Api+Mine.h 和 Api+Mine.m 文件以支持新功能。同时,新增 BaseModelVo.h 和 BaseModelVo.m 文件以定义勋章相关数据模型,并在 UserInfoModel.h 中引入 BaseModelVo。保持代码结构一致性。 2025-06-11 15:00:02 +08:00
edwinQQQ
4416e9f9c8 新增 VIP 和转账功能的 URL 路径,更新相关文件以使用 XPWebViewController 替代 VIPCenterViewController,保持代码结构一致性。调整公屏礼物消失的显示内容。 2025-06-11 11:27:00 +08:00
edwinQQQ
6e814f76cb 移除与 Agora 相关的 SDK 代码和引用,更新 Podfile 以删除不再使用的依赖项,调整房间初始化逻辑以使用 TRTC 引擎。保持代码结构一致性。 2025-06-10 16:07:59 +08:00
edwinQQQ
443e1a4332 新增分享功能的多个方法,包括提取 URL 和剩余字符串、强制关闭分享弹窗,以及分享内容的构建逻辑。更新 ShareProvider 类以支持新的初始化方法和不同分享类型的内容提供。保持代码结构一致性。 2025-06-09 16:39:32 +08:00
edwinQQQ
8dab721de9 在 SessionListViewController 中添加了对最近会话的日志输出。在 LuckyGiftWinningBannerView 和 BravoGiftBannerView 中引入了可配置的显示时间,注释掉了不再使用的代码。在 XPRoomFunctionContainerView 中优化了 hitTest 方法以增强用户交互体验,确保子视图的点击响应逻辑更加清晰。更新了 MicroView 中的表情加载逻辑,增加了对下载失败情况的处理。保持代码结构一致性。 2025-06-09 15:52:34 +08:00
edwinQQQ
5985b5701e 新增排行榜功能,更新 YUMIHtmlUrl.h 和 YUMIHtmlUrl.m 文件以支持新路径 kRankV2,调整 XPNewHomeViewController.m 中的相关逻辑以使用新排行榜链接,更新 XPMineUserInfoViewController.m 和 XPMineUserInfoHeaderView.m 文件以修复用户信息展示。保持代码结构一致性。 2025-06-03 11:00:10 +08:00
edwinQQQ
5ff62bafee 优化房间退出逻辑,更新退出事件处理,修复房间类型判断。更新分享功能以支持内容参数。调整游戏状态处理,重置当前游戏ID。 2025-05-29 11:50:00 +08:00
edwinQQQ
ca25ed14ac 新增搜索视图的 UITextFieldDelegate 实现,优化搜索逻辑,添加 isReturnKey 属性以区分回车触发的搜索。更新 GiftComboManager 和 HttpRequestHelper 中的错误处理逻辑,修复条件判断中的错误。移除不再使用的代码。版本号更新至1.0.28.2。 2025-05-27 16:02:11 +08:00
edwinQQQ
e5c8baad34 更新版本号至1.0.28.1,移除调试代码,新增隐私信息文件,优化房间消息处理逻辑,增加网络检测相关功能,调整部分接口参数,修复UI问题,更新本地化字符串,更新 SUD SDK 2025-05-26 15:24:31 +08:00
edwinQQQ
c765e78ec6 更新资源文件,替换部分图片文件名,调整图片内容,更新版本号至1.0.28。增加新的图片资源并删除不再使用的图片文件。 2025-05-23 14:43:39 +08:00
edwinQQQ
95e3e2601f 新增自定义麦位布局和房间麦位选择视图,优化房间用户界面,更新本地化字符串,调整部分UI组件约束。版本号更新至20.20.65。 2025-05-22 18:04:39 +08:00
edwinQQQ
0d01b1e6e9 更新事件中心模块,新增 HomeBannerInfoModel 相关功能,优化事件列表数据处理,调整时间选择器逻辑,修复部分 UI 问题,更新本地化字符串。版本号更新至20.20.64。 2025-05-22 11:50:53 +08:00
edwinQQQ
298a7e80c4 优化内购交易重试机制,增加交易重试次数记录,完善后台任务处理,更新相关API接口,调整UI组件约束,修复部分UI问题,更新本地化字符串。版本号更新至20.20.63。 2025-05-21 18:59:32 +08:00
edwinQQQ
b688962559 更新事件创建功能,新增金钱加载接口,优化事件时长选择器,调整UI组件约束,修复部分UI问题,更新本地化字符串。增加删除事件功能的提示确认。版本号更新至20.20.62。 2025-05-20 18:49:04 +08:00
edwinQQQ
353491f56f 更新活动中心模块,新增事件配置模型及相关API接口,优化事件列表展示,修复部分UI问题,更新本地化字符串,调整部分UI组件。删除不再使用的视图控制器。版本号更新至20.20.61。 2025-05-19 19:27:53 +08:00
edwinQQQ
a99e650d45 新增活动详情页相关功能,包括事件模型、API接口、UI组件及相关资源文件。更新版本号至20.20.60。 2025-05-15 16:24:43 +08:00
edwinQQQ
bd2e5e380f 增加选择房间 vc 2025-05-12 18:53:42 +08:00
edwinQQQ
2c5a1a289e 创建事件 create event UI 2025-05-12 17:37:58 +08:00
edwinQQQ
ffdfa121f9 新增 JoyPlay 游戏支持 2025-05-08 17:10:54 +08:00
AI Health Developer
07ebee2fc1 修正部分体验问题; 房间表情新增 api; 房间表情新增 svga 支持以及持久化缓存 2025-05-07 19:30:50 +08:00
AI Health Developer
69863a91ff feat(EventCenter): 添加活动中心模块
新增活动中心模块,包括官方活动、活动广场和我的活动三个页面。支持活动列表展示、倒计时功能及创建活动按钮。优化了页面切换和UI交互体验。
2025-05-06 16:45:34 +08:00
AI Health Developer
a9538c61ff 修正表情播放问题 2025-04-28 18:28:59 +08:00
AI Health Developer
41aae87dd6 修改 UI 需求和问题 2025-04-28 14:52:00 +08:00
AI Health Developer
ff365e8ae4 修正审核问题,适配后端修改 2025-04-25 15:54:30 +08:00
AI Health Developer
40311a1d85 完成 1.0.26 需求 2025-04-21 13:52:13 +08:00
AI Health Developer
2caa476640 temp save 2025-04-11 10:46:17 +08:00
AI Health Developer
faa6a2c4dc 修正 combo 金币显示问题 2025-04-11 10:45:49 +08:00
edwinQQQ
0275decc7e Finish 2.7.34 2025-04-02 11:04:07 +08:00
edwinQQQ
bc9a02802d boom 重构暂存 2025-03-25 15:22:01 +08:00
edwinQQQ
d9850e2c8b 需求暫存 2025-03-24 16:09:48 +08:00
edwinQQQ
e27b564fdc 完成 2.7.32 需求 2025-03-21 16:19:07 +08:00
edwinQQQ
d6e13ac0fe 修正线上首页显示内容不对问题
阿语环境下,有概率会 hot 列表显示为最后一个 tab 的内容
2025-03-14 19:44:58 +08:00
edwinQQQ
e7b2f594e8 版本需求修改暂存 2025-03-14 19:43:04 +08:00
edwinQQQ
e152d0f8a1 Feature: 完成金币兑换 UX 调整 2025-03-07 11:03:35 +08:00
edwinQQQ
9d3f08c9b3 2.3.31 finish 2025-03-06 15:26:44 +08:00
edwinQQQ
7807824a97 Finish all works! 2025-02-28 19:04:09 +08:00
edwinQQQ
8a1ed09905 移除不使用代码 2025-02-10 19:12:27 +08:00
edwinQQQ
fc399e0afc Dangerous Modify: 移除 Firebase/Analytics lib; 移除埋点文件(不使用);移除部分不使用的 分享功能 相关代码; 2025-02-10 18:49:34 +08:00
edwinQQQ
f582077804 Promotion: 优化首页API 加载逻辑 2025-02-05 18:16:27 +08:00
edwinQQQ
b592097865 Promotion: 优化 API 请求基类 2025-02-05 18:15:41 +08:00
edwinQQQ
a4651740bd Fix: 尝试修复线上 crash 问题 2025-02-05 14:31:39 +08:00
edwinQQQ
d958a3ca36 feat: 修正最后验收问题 2025-01-22 21:22:58 +08:00
edwinQQQ
f963f0ed81 完成房间动画类重构 2025-01-16 16:00:12 +08:00
edwinQQQ
e2f022246f 重构 room 动画层 50% 2025-01-15 19:02:58 +08:00
edwinQQQ
b6325180d4 feat: 更新房间管理弹窗内容 2025-01-14 14:29:14 +08:00
edwinQQQ
471b8e945f 优化:调整送礼动画代码 2025-01-13 15:29:58 +08:00
edwinQQQ
d71a139afb 隐藏埋点上报代码(已没有使用) 2025-01-13 14:17:57 +08:00
edwinQQQ
9b0520c1eb feat:移除不使用图片资源 | 新增新需求图片资源 | 部分代码优化 2025-01-13 14:10:27 +08:00
edwinQQQ
311868fde6 Version Update 2025-01-09 18:36:30 +08:00
edwinQQQ
a79bf667cc fix: bug fix 2025-01-09 18:05:02 +08:00
edwinQQQ
bc02ca29fc fix: Bug fix 2025-01-09 14:22:59 +08:00
edwinQQQ
93c3304601 fix: 修正 UI 验收问题 2025-01-08 12:10:02 +08:00
edwinQQQ
d9e8d6639b fix: 修正验收问题 2025-01-07 20:07:54 +08:00
edwinQQQ
893c1ab647 fix: 修正房间聊天开关问题 | 修复部分 crash 场景 2025-01-02 17:31:17 +08:00
edwinQQQ
ed25b30a35 feat: 优化 UI 体验 2025-01-02 14:34:56 +08:00
edwinQQQ
54cc9ebde3 feat: 修正房间聊天框中文显示不全问题 2024-12-31 18:47:48 +08:00
edwinQQQ
81a0094dbf feat: 完成 代充页面修改 | 开屏 & 首页banner 支持 svga 2024-12-31 15:09:44 +08:00
edwinQQQ
4abb686790 feat: 优化首页 tab 加载逻辑 | 补全 side menu 控制逻辑 | 基本完成 20 mic | 部分小需求 | 优化房间聊天气泡 2024-12-28 15:41:56 +08:00
edwinQQQ
2c5d72846d feat: 重构房间右下菜单栏 2024-12-20 19:05:43 +08:00
edwinQQQ
ab544a2d84 补充部分 UI 验收问题 2024-12-19 15:10:41 +08:00
edwinQQQ
83d1a1df95 Version update 2024-12-19 14:04:51 +08:00
edwinQQQ
75a9bac88a Version update 2024-12-19 14:04:39 +08:00
edwinQQQ
c0e7e7ff83 修复验收问题 2024-12-19 14:02:37 +08:00
edwinQQQ
47c0f141a8 Update version 2024-12-18 17:12:48 +08:00
edwinQQQ
a0b2dea116 100% 完成需求 2024-12-18 17:12:03 +08:00
edwinQQQ
e82939f767 70% 完成需求 2024-12-16 19:41:23 +08:00
edwinQQQ
68370912b2 fix: 修正线上问题 2024-12-11 10:48:01 +08:00
edwinQQQ
57735e37c4 fix: 优化送礼的内存效率 |
TODO:调整 combo 时的金币变动效果
2024-12-09 19:27:02 +08:00
edwinQQQ
8ba4eaf2f5 try to fix send gift animation problems 2024-12-06 21:00:20 +08:00
edwinQQQ
612b84e47b Version update 2024-12-06 14:41:12 +08:00
edwinQQQ
4c94a61da6 1.0.30 封版 2024-12-06 14:38:45 +08:00
edwinQQQ
50bc8a28b3 修正热度值 UI 2024-12-04 22:03:31 +08:00
edwinQQQ
80abf631c6 Merge branch 'test/fix-chat-bug' into 1.0.30
# Conflicts:
#	YuMi/Modules/YMRoom/View/MessageContainerView/Model/XPMessageInfoModel.m
#	YuMi/Modules/YMRoom/View/MessageContainerView/Tool/XPRoomMessageParser.m
#	YuMi/Modules/YMRoom/View/MessageContainerView/View/XPNetImageYYLabel.m
#	YuMi/Modules/YMRoom/View/MessageContainerView/View/XPRoomMessageHeaderView.m
#	YuMi/Modules/YMRoom/View/MessageContainerView/View/XPRoomMessageTableViewCell.m
#	YuMi/Modules/YMRoom/View/MessageContainerView/XPRoomMessageContainerView.m
#	YuMi/Modules/YMRoom/View/ThemeColor+Room.m
2024-12-04 21:24:28 +08:00
edwinQQQ
2b4de25c80 完成版本需求 2024-12-04 21:22:38 +08:00
edwinQQQ
2637ae065e feat: 增加超级封禁 2024-12-03 17:40:29 +08:00
edwinQQQ
c49517dd94 feat: 修正发送礼物的处理 2024-12-02 19:33:20 +08:00
edwinQQQ
4d6e71450a temp save: 基本完成房间聊天列表的内容高度适配 | 调整房间音乐面板入口 & UI 2024-12-02 16:49:16 +08:00
edwinQQQ
c77bb17b03 temp save: 更好的效果 2024-11-29 21:50:24 +08:00
edwinQQQ
6b2dbee88c temp save: 基本完整显示聊天内容 2024-11-29 16:46:36 +08:00
edwinQQQ
5fa7595965 调整铭牌的大小 2024-11-28 20:39:27 +08:00
edwinQQQ
b7ebe93013 尝试修复房间聊天列表显示问题 2024-11-28 18:45:28 +08:00
edwinQQQ
a6af37e51b fix:修正切换语言后 tabbar 显示顺序不正确问题 2024-11-28 11:05:57 +08:00
edwinQQQ
2415016337 feat:修正需求验收问题 2024-11-28 10:40:21 +08:00
P
cafb009362 修正 UI & 补充本地化语言文本 2024-11-25 11:53:00 +08:00
P
cd582b52f3 feat: 基本完成需求 2024-11-22 21:05:47 +08:00
P
786f15cae7 feat: 基本完成礼物支持嵌入元素功能 2024-11-22 13:47:34 +08:00
P
9fe30ce255 feat: 基本完成首页 UI 调整 2024-11-20 20:20:43 +08:00
P
f07773ff03 feat:90% 完成新商场/我的装扮 2024-11-20 18:25:13 +08:00
P
17fbd340d6 fix: 修复首页 API 可能被 block 住的bug | 修正 API 可能被设置过短超时的场景 2024-11-20 10:35:59 +08:00
eggmanQQQ
b936d7dea5 feat:新商城增加 svga 播放处理 2024-11-18 19:39:38 +08:00
eggmanQQQ
ab4a9cf88b feat:新商城增加 svga 播放处理 2024-11-15 18:17:15 +08:00
eggmanQQQ
dd247c0688 feat: 新商城暂存 2024-11-15 16:36:03 +08:00
eggmanQQQ
cb1172eb8c fix:修正阿语房间背景价格显示问题 2024-11-15 16:36:03 +08:00
eggmanQQQ
a1306b32b8 fix: 修正首页列表加载逻辑 | 修正部分 UI 效果 2024-11-15 16:36:01 +08:00
eggmanQQQ
98e38008be fix:修正首页列表显示问题 2024-11-15 10:57:12 +08:00
eggmanQQQ
dcd5e04503 feat: 新商城暂存 2024-11-15 10:56:54 +08:00
eggmanQQQ
e47259c82c feat: 新商城框架 2024-11-13 19:17:06 +08:00
eggmanQQQ
9a3aab22e9 代码整理 2024-11-13 14:21:00 +08:00
eggmanQQQ
4cf14841cf 1.0.30 feat:version update 2024-11-13 11:23:14 +08:00
eggmanQQQ
219a591f3d Bug fix 2024-11-13 11:20:56 +08:00
eggmanQQQ
80facecd80 修复自定义背景选择逻辑问题 2024-11-12 16:47:29 +08:00
eggmanQQQ
d876d7759d 修正测试代码 2024-11-12 15:40:13 +08:00
eggmanQQQ
4648dd3b53 1.0.19 feat:UI 改进 & 修复线上 crash 问题 2024-11-12 15:35:56 +08:00
eggmanQQQ
00014f0327 1.0.19 feat:基本完成所有需求 & bug fix 2024-11-11 19:35:21 +08:00
eggmanQQQ
efefa94d3c temp save 2024-11-07 16:16:09 +08:00
eggmanQQQ
694d56b604 1.0.19 feat:首页 UI 配置更新 2024-11-06 17:57:32 +08:00
eggmanQQQ
a5f7a5eb87 1.0.19 feat:移除 API:privateChat/check 2024-11-05 17:24:52 +08:00
eggmanQQQ
b3fee0eef9 1.0.19 feat:个性化房间背景-free 部分 / 首页支持 API 更新 UI 2024-11-05 17:09:22 +08:00
eggmanQQQ
faacf7b22d 1.0.19 feat:个性化房间背景 API / 新礼物飘屏 UI 2024-11-01 20:49:31 +08:00
eggmanQQQ
ec70554f9d 1.0.19 feat:个性化房间背景 UI 2024-10-31 19:24:04 +08:00
eggmanQQQ
ae4229675d 1.0.19 feat:开始个性化房间背景 2024-10-30 17:22:29 +08:00
eggmanQQQ
9e9e5fa0e8 1.0.19 feat:Vip 权限显示调整 2024-10-30 14:09:05 +08:00
eggmanQQQ
cd93cc1024 优化个播房主播头像 2024-10-29 17:14:38 +08:00
eggmanQQQ
0e00f4df11 代码 & UI 小优化 2024-10-29 17:10:56 +08:00
eggmanQQQ
1f6b060898 1.0.18 feat:多语言支持 2024-10-29 17:00:27 +08:00
eggmanQQQ
0adb06fcd3 移除不使用文件 2024-10-29 11:07:56 +08:00
eggmanQQQ
4051a94dd4 1.0.18 feat:重构 VIP 页面,修正发现问题,更新地区选择 API 2024-10-24 19:43:46 +08:00
eggmanQQQ
fc323bd470 1.0.18 feat:基本完成 1.0.18 功能 2024-10-23 19:08:51 +08:00
eggmanQQQ
d0ea8932cc 1.0.18 feat:增加 VIP 权限设置页面 & API 2024-10-22 18:46:06 +08:00
eggmanQQQ
d5572c204a 1.0.18 feat:增加图片资源,修正游戏列表 UI 问题 2024-10-22 17:14:20 +08:00
eggmanQQQ
37f9457532 1.0.18 feat:完成更新房间头像 2024-10-22 15:26:41 +08:00
eggmanQQQ
6bc081dbad 1.0.18 feat:调整 web 小游戏逻辑 2024-10-22 14:34:42 +08:00
eggmanQQQ
602789ab5c 1.0.18 feat:房间设置增加修改房间头像的选项 2024-10-21 18:38:57 +08:00
eggmanQQQ
01743623f2 1.0.18 feat:支持给自己送礼物 2024-10-21 18:38:27 +08:00
eggmanQQQ
442af3d760 1.0.18 fix:修正个播房 mic 为不能点击问题 2024-10-21 18:37:55 +08:00
eggmanQQQ
d043adf7e8 1.0.18 feat:菜单入口支持新的小游戏 2024-10-21 18:34:48 +08:00
eggmanQQQ
a946ee1c50 1.0.18 feat:处理 GIF 头像上传入口 2024-10-21 18:34:18 +08:00
eggmanQQQ
8c64d6fdc0 1.0.18 feat:连击礼物请求加入到每 0.2s 执行一次的队列 2024-10-21 18:31:09 +08:00
eggmanQQQ
b34e8ccb16 1.0.18 feat:支持新的小游戏 2024-10-21 18:29:30 +08:00
eggmanQQQ
81167d8e0f temp save 2024-10-18 20:24:47 +08:00
eggmanQQQ
c9cacb388b fix:修正部分问题 2024-10-17 16:05:02 +08:00
eggmanQQQ
e72f39ffde fix:修正部分问题 2024-10-16 17:28:37 +08:00
eggmanQQQ
0505054aec version update 2024-10-15 21:06:19 +08:00
eggmanQQQ
f576d9c3cf finish:1.0.17 2024-10-15 20:56:25 +08:00
eggmanQQQ
0b14b6bf5f feat: 修正各种小问题,补充多语言 2024-10-14 15:26:57 +08:00
eggmanQQQ
3f6fae9c07 feat: 修正初步 debug 问题 2024-10-12 19:30:41 +08:00
eggmanQQQ
80549b57aa feat: 基本完成房间内消息列表的调整 2024-10-11 16:41:55 +08:00
eggmanQQQ
b79adfa576 feat: 基本完成 boom 需求 2024-10-11 12:31:37 +08:00
eggmanQQQ
5c87f850e7 temp save 2024-10-10 20:16:23 +08:00
eggmanQQQ
94c11e5148 feat:强制 web 使用 initWithRoomUID 初始化 2024-10-08 11:47:06 +08:00
eggmanQQQ
259d161df8 feat:引入资源和新建火箭视图 2024-10-08 11:30:40 +08:00
eggmanQQQ
a2795817ac feat: Version Update 2024-09-27 11:18:28 +08:00
eggmanQQQ
931887fc8c feat: 完成 1.0.16 验收 2024-09-27 11:17:04 +08:00
eggmanQQQ
4d46e1505c feat: 优化 PIIAPRegulate 2024-09-24 18:02:05 +08:00
eggmanQQQ
6ba054c694 feat: 新建内购管理 IAPManager 2024-09-24 18:01:08 +08:00
eggmanQQQ
a43b34b934 feat: 补充多语言 | 修正自测问题 2024-09-23 20:35:29 +08:00
eggmanQQQ
9fa668a0d8 feat: 完成 CP 相关动效 2024-09-23 18:01:54 +08:00
eggmanQQQ
a09a1d20f0 fix: 修正玩小游戏时,送礼会遮挡 UI 问题 2024-09-23 12:21:11 +08:00
eggmanQQQ
240846c809 fix: 修正公会管理列表选中不响应问题 2024-09-23 11:01:27 +08:00
eggmanQQQ
eb46a2b002 feat: 基本cp绑定飘屏 2024-09-20 21:19:08 +08:00
eggmanQQQ
f8d387aa84 feat: 基本完成用户页面 2024-09-20 20:16:20 +08:00
eggmanQQQ
ea3dbd4cb4 hot fix:修正部分类型礼物连击后送礼异常问题 2024-09-20 10:47:49 +08:00
eggmanQQQ
513cabbedc feat: 补充个人资料页公会信息 2024-09-19 18:58:23 +08:00
eggmanQQQ
61e316044d feat:完善个人主页 cp 模块 2024-09-19 16:52:32 +08:00
eggmanQQQ
994df0af28 temp save 2024-09-18 17:45:11 +08:00
eggmanQQQ
1b0b461fd8 调整用户资料页的 UI 2024-09-18 17:04:07 +08:00
eggmanQQQ
25b82beaf6 移除不使用的 pod 和代码 2024-09-18 17:03:45 +08:00
eggmanQQQ
c67bad9481 feat: 修改部分用户详情页内容 2024-09-18 10:31:21 +08:00
eggmanQQQ
11c31b6616 feat: 完成房间 UI 调整 2024-09-14 18:29:36 +08:00
eggmanQQQ
76a80eaf1e fix: 修正发现问题 2024-09-12 18:49:42 +08:00
eggmanQQQ
3c024b808f feat: 完成礼物连击功能 2024-09-12 14:01:12 +08:00
eggmanQQQ
f668f43a42 feat: 完成礼物连击功能 | 更换金币资源图片 2024-09-10 15:27:47 +08:00
eggmanQQQ
e45176485d feat: 构建送礼连击 manager, 从 send gift view 中抽离发送礼物-发送消息功能 2024-09-05 19:43:01 +08:00
eggmanQQQ
ccbdfb7ee2 version update to 1.0.21 2024-09-04 20:21:45 +08:00
eggmanQQQ
fa6934299c logic fix and version update 2024-09-04 20:18:20 +08:00
eggmanQQQ
b9edaddf7c 修正反馈问题 2024-09-04 18:26:30 +08:00
eggmanQQQ
1f9e998b00 修正翻译 2024-09-04 17:16:28 +08:00
eggmanQQQ
cf0a0a87c7 feat: 更新 UI 2024-09-04 16:11:11 +08:00
eggmanQQQ
4dbc7422ec feat: 更新 VIP 页面内容 | 更新一级页面 UI 2024-09-03 20:22:54 +08:00
eggmanQQQ
966aedcc7d feat: 更新 VIP 页面内容 2024-09-02 19:28:36 +08:00
eggmanQQQ
c8674be186 feat: 移除公聊 2024-08-22 11:40:50 +08:00
eggmanQQQ
3e6fec0601 feat: 调整 UI 效果,调整剩余日期计算 2024-08-22 10:32:42 +08:00
eggmanQQQ
0f54b562e2 完善新 VIP 页 2024-08-19 19:41:22 +08:00
eggmanQQQ
3d2fb62d19 feat: 新 VIP 充值页 2024-08-16 21:14:11 +08:00
eggmanQQQ
d555f5815c fix:修正所有礼物缓存问题 2024-08-14 16:32:40 +08:00
eggmanQQQ
39f928be02 fix: 修正玩百顺游戏时,礼物动画会在最上层的问题 2024-08-13 14:18:08 +08:00
eggmanQQQ
218d312b73 Version Update: 1.0.20 / 20.20.34 2024-08-13 10:35:46 +08:00
2604 changed files with 89888 additions and 37550 deletions

View File

@@ -0,0 +1,7 @@
---
description:
globs:
alwaysApply: false
---
本次对话的上下文已经太长了,我打算关掉并重新开一个新的会话。
你有什么想对你的继任者说的,以便它能更好的理解你当前的工作并顺利继续?

7
.gitignore vendored
View File

@@ -82,12 +82,6 @@ iOSInjectionProject/
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.war
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
@@ -151,3 +145,4 @@ iOS/Podfile.lock
Podfile.lock
*/.DS_Store
.DS_Store
YuMi.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

40
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,40 @@
{
"cSpell.ignoreWords": [
"DJDKMIMOM",
"Strongify",
"Weakify",
"instancetype",
"nonatomic"
],
"cSpell.words": [
"autoreleasepool",
"Autoresizing",
"BGMP",
"Bugly",
"Commont",
"Contol",
"CPSVGA",
"Defalut",
"erban",
"exper",
"Headwear",
"HWDMP",
"Interitem",
"kindof",
"MAXFLOAT",
"MSRTL",
"NIMSDK",
"Nonnull",
"NSEC",
"NSURL",
"Offical",
"Procotol",
"QGVAP",
"Subview",
"subviews",
"Superview",
"Uids",
"XNDJTDD"
],
"C_Cpp.errorSquiggles": "disabled"
}

View File

@@ -0,0 +1,434 @@
# 邮箱验证码登录流程文档
## 概述
本文档详细描述了 YuMi iOS 应用中 `LoginTypesViewController``LoginDisplayType_email` 模式下的邮箱验证码登录流程。该流程实现了基于邮箱和验证码的用户认证机制。
## 系统架构
### 核心组件
- **LoginTypesViewController**: 登录类型控制器,负责 UI 展示和用户交互
- **LoginPresenter**: 登录业务逻辑处理器,负责与 API 交互
- **LoginInputItemView**: 输入组件,提供邮箱和验证码输入界面
- **Api+Login**: 登录相关 API 接口封装
- **AccountInfoStorage**: 账户信息本地存储管理
### 数据模型
#### LoginDisplayType 枚举
```objc
typedef NS_ENUM(NSUInteger, LoginDisplayType) {
LoginDisplayType_id, // ID 登录
LoginDisplayType_email, // 邮箱登录 ✓
LoginDisplayType_phoneNum, // 手机号登录
LoginDisplayType_email_forgetPassword, // 邮箱忘记密码
LoginDisplayType_phoneNum_forgetPassword, // 手机号忘记密码
};
```
#### LoginInputType 枚举
```objc
typedef NS_ENUM(NSUInteger, LoginInputType) {
LoginInputType_email, // 邮箱输入
LoginInputType_verificationCode, // 验证码输入
LoginInputType_login, // 登录按钮
// ... 其他类型
};
```
#### GetSmsType 验证码类型
```objc
typedef NS_ENUM(NSUInteger, GetSmsType) {
GetSmsType_Regist = 1, // 注册(邮箱登录使用此类型)
GetSmsType_Login = 2, // 登录
GetSmsType_Reset_Password = 3, // 重设密码
// ... 其他类型
};
```
## 登录流程详解
### 1. 界面初始化流程
#### 1.1 控制器初始化
```objc
// 在 LoginViewController 中点击邮箱登录按钮
- (void)didTapEntrcyButton:(UIButton *)sender {
if (sender.tag == LoginType_Email) {
LoginTypesViewController *vc = [[LoginTypesViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
[vc updateLoginType:LoginDisplayType_email]; // 设置为邮箱登录模式
}
}
```
#### 1.2 输入区域设置
```objc
- (void)setupEmailInputArea {
[self setupInpuArea:LoginInputType_email // 第一行:邮箱输入
second:LoginInputType_verificationCode // 第二行:验证码输入
third:LoginInputType_none // 第三行:无
action:LoginInputType_login // 操作按钮:登录
showForgetPassword:NO]; // 不显示忘记密码
}
```
#### 1.3 UI 组件配置
- **第一行输入框**: 邮箱地址输入
- 占位符: "请输入邮箱地址"
- 键盘类型: `UIKeyboardTypeEmailAddress`
- 回调: `handleFirstInputContentUpdate`
- **第二行输入框**: 验证码输入
- 占位符: "请输入验证码"
- 键盘类型: `UIKeyboardTypeDefault`
- 附带"获取验证码"按钮
- 回调: `handleSecondInputContentUpdate`
### 2. 验证码获取流程
#### 2.1 用户交互触发
```objc
// 用户点击"获取验证码"按钮
[self.secondLineInputView setHandleItemAction:^(LoginInputType inputType) {
if (inputType == LoginInputType_verificationCode) {
if (self.type == LoginDisplayType_email) {
[self handleTapGetMailVerificationCode];
}
}
}];
```
#### 2.2 邮箱验证码获取处理
```objc
- (void)handleTapGetMailVerificationCode {
NSString *email = [self.firstLineInputView inputContent];
// 邮箱地址验证
if (email.length == 0) {
[self.secondLineInputView endVerificationCountDown];
return;
}
// 调用 Presenter 发送验证码
[self.presenter sendMailVerificationCode:email type:GetSmsType_Regist];
}
```
#### 2.3 Presenter 层处理
```objc
- (void)sendMailVerificationCode:(NSString *)emailAddress type:(NSInteger)type {
// DES 加密邮箱地址
NSString *desEmail = [DESEncrypt encryptUseDES:emailAddress
key:KeyWithType(KeyType_PasswordEncode)];
@kWeakify(self);
[Api emailGetCode:[self createHttpCompletion:^(BaseModel *data) {
@kStrongify(self);
if ([[self getView] respondsToSelector:@selector(emailCodeSucess:type:)]) {
[[self getView] emailCodeSucess:@"" type:type];
}
} fail:^(NSInteger code, NSString *msg) {
@kStrongify(self);
if ([[self getView] respondsToSelector:@selector(emailCodeFailure)]) {
[[self getView] emailCodeFailure];
}
} showLoading:YES errorToast:YES]
emailAddress:desEmail
type:@(type)];
}
```
#### 2.4 API 接口调用
```objc
+ (void)emailGetCode:(HttpRequestHelperCompletion)completion
emailAddress:(NSString *)emailAddress
type:(NSNumber *)type {
[self makeRequest:@"email/getCode"
method:HttpRequestHelperMethodPOST
completion:completion, __FUNCTION__, emailAddress, type, nil];
}
```
**API 详情**:
- **接口路径**: `POST /email/getCode`
- **请求参数**:
- `emailAddress`: 邮箱地址DES 加密)
- `type`: 验证码类型1=注册)
#### 2.5 获取验证码成功处理
```objc
- (void)emailCodeSucess:(NSString *)message type:(GetSmsType)type {
[self showSuccessToast:YMLocalizedString(@"XPLoginPhoneViewController2")]; // "验证码已发送"
[self.secondLineInputView startVerificationCountDown]; // 开始倒计时
[self.secondLineInputView displayKeyboard]; // 显示键盘
}
```
#### 2.6 获取验证码失败处理
```objc
- (void)emailCodeFailure {
[self.secondLineInputView endVerificationCountDown]; // 结束倒计时
}
```
### 3. 邮箱登录流程
#### 3.1 登录按钮状态检查
```objc
- (void)checkActionButtonStatus {
switch (self.type) {
case LoginDisplayType_email: {
NSString *accountString = [self.firstLineInputView inputContent]; // 邮箱
NSString *codeString = [self.secondLineInputView inputContent]; // 验证码
// 只有当邮箱和验证码都不为空时才启用登录按钮
if (![NSString isEmpty:accountString] && ![NSString isEmpty:codeString]) {
self.bottomActionButton.enabled = YES;
} else {
self.bottomActionButton.enabled = NO;
}
}
break;
}
}
```
#### 3.2 登录按钮点击处理
```objc
- (void)didTapActionButton {
[self.view endEditing:true];
switch (self.type) {
case LoginDisplayType_email: {
// 调用 Presenter 进行邮箱登录
[self.presenter loginWithEmail:[self.firstLineInputView inputContent]
code:[self.secondLineInputView inputContent]];
}
break;
}
}
```
#### 3.3 Presenter 层登录处理
```objc
- (void)loginWithEmail:(NSString *)email code:(NSString *)code {
// DES 加密邮箱地址
NSString *desMail = [DESEncrypt encryptUseDES:email
key:KeyWithType(KeyType_PasswordEncode)];
@kWeakify(self);
[Api loginWithCode:[self createHttpCompletion:^(BaseModel *data) {
@kStrongify(self);
// 解析账户模型
AccountModel *accountModel = [AccountModel modelWithDictionary:data.data];
// 保存账户信息
if (accountModel && accountModel.access_token.length > 0) {
[[AccountInfoStorage instance] saveAccountInfo:accountModel];
}
// 通知登录成功
if ([[self getView] respondsToSelector:@selector(loginSuccess)]) {
[[self getView] loginSuccess];
}
} fail:^(NSInteger code, NSString *msg) {
@kStrongify(self);
[[self getView] loginFailWithMsg:msg];
} errorToast:NO]
email:desMail
code:code
client_secret:clinet_s // 客户端密钥
version:@"1"
client_id:@"erban-client"
grant_type:@"email"]; // 邮箱登录类型
}
```
#### 3.4 API 接口调用
```objc
+ (void)loginWithCode:(HttpRequestHelperCompletion)completion
email:(NSString *)email
code:(NSString *)code
client_secret:(NSString *)client_secret
version:(NSString *)version
client_id:(NSString *)client_id
grant_type:(NSString *)grant_type {
NSString *fang = [NSString stringFromBase64String:@"b2F1dGgvdG9rZW4="]; // oauth/token
[self makeRequest:fang
method:HttpRequestHelperMethodPOST
completion:completion, __FUNCTION__, email, code, client_secret,
version, client_id, grant_type, nil];
}
```
**API 详情**:
- **接口路径**: `POST /oauth/token`
- **请求参数**:
- `email`: 邮箱地址DES 加密)
- `code`: 验证码
- `client_secret`: 客户端密钥
- `version`: 版本号 "1"
- `client_id`: 客户端ID "erban-client"
- `grant_type`: 授权类型 "email"
#### 3.5 登录成功处理
```objc
- (void)loginSuccess {
[self showSuccessToast:YMLocalizedString(@"XPLoginPhoneViewController1")]; // "登录成功"
[PILoginManager loginWithVC:self isLoginPhone:NO]; // 执行登录后续处理
}
```
#### 3.6 登录失败处理
```objc
- (void)loginFailWithMsg:(NSString *)msg {
[self showSuccessToast:msg]; // 显示错误信息
}
```
## 数据流时序图
```mermaid
sequenceDiagram
participant User as 用户
participant VC as LoginTypesViewController
participant IV as LoginInputItemView
participant P as LoginPresenter
participant API as Api+Login
participant Storage as AccountInfoStorage
Note over User,Storage: 1. 初始化邮箱登录界面
User->>VC: 选择邮箱登录
VC->>VC: updateLoginType(LoginDisplayType_email)
VC->>VC: setupEmailInputArea()
VC->>IV: 创建邮箱输入框
VC->>IV: 创建验证码输入框
Note over User,Storage: 2. 获取邮箱验证码
User->>IV: 输入邮箱地址
User->>IV: 点击"获取验证码"
IV->>VC: handleTapGetMailVerificationCode
VC->>VC: 验证邮箱地址非空
VC->>P: sendMailVerificationCode(email, GetSmsType_Regist)
P->>P: DES加密邮箱地址
P->>API: emailGetCode(encryptedEmail, type=1)
API-->>P: 验证码发送结果
P-->>VC: emailCodeSucess / emailCodeFailure
VC->>IV: startVerificationCountDown / endVerificationCountDown
VC->>User: 显示成功/失败提示
Note over User,Storage: 3. 邮箱验证码登录
User->>IV: 输入验证码
IV->>VC: 输入内容变化回调
VC->>VC: checkActionButtonStatus()
VC->>User: 启用/禁用登录按钮
User->>VC: 点击登录按钮
VC->>VC: didTapActionButton()
VC->>P: loginWithEmail(email, code)
P->>P: DES加密邮箱地址
P->>API: loginWithCode(email, code, ...)
API-->>P: OAuth Token 响应
P->>P: 解析 AccountModel
P->>Storage: saveAccountInfo(accountModel)
P-->>VC: loginSuccess / loginFailWithMsg
VC->>User: 显示登录结果
VC->>User: 跳转到主界面
```
## 安全机制
### 1. 数据加密
- **邮箱地址加密**: 使用 DES 算法加密邮箱地址后传输
```objc
NSString *desEmail = [DESEncrypt encryptUseDES:email key:KeyWithType(KeyType_PasswordEncode)];
```
### 2. 输入验证
- **邮箱格式验证**: 通过 `UIKeyboardTypeEmailAddress` 键盘类型引导正确输入
- **非空验证**: 邮箱和验证码都必须非空才能执行登录
### 3. 验证码安全
- **时效性**: 验证码具有倒计时机制,防止重复获取
- **类型标识**: 使用 `GetSmsType_Regist = 1` 标识登录验证码
### 4. 网络安全
- **错误处理**: 完整的成功/失败回调机制
- **加载状态**: `showLoading:YES` 防止重复请求
- **错误提示**: `errorToast:YES` 显示网络错误
## 错误处理机制
### 1. 邮箱验证码获取错误
```objc
- (void)emailCodeFailure {
[self.secondLineInputView endVerificationCountDown]; // 停止倒计时
// 用户可以重新获取验证码
}
```
### 2. 登录失败处理
```objc
- (void)loginFailWithMsg:(NSString *)msg {
[self showSuccessToast:msg]; // 显示具体错误信息
// 用户可以重新尝试登录
}
```
### 3. 网络请求错误
- **自动重试**: 用户可以手动重新点击获取验证码或登录
- **错误提示**: 通过 Toast 显示具体错误信息
- **状态恢复**: 失败后恢复按钮可点击状态
## 本地化支持
### 关键文本资源
- `@"20.20.51_text_1"`: "邮箱登录"
- `@"20.20.51_text_4"`: "请输入邮箱地址"
- `@"20.20.51_text_7"`: "请输入验证码"
- `@"XPLoginPhoneViewController2"`: "验证码已发送"
- `@"XPLoginPhoneViewController1"`: "登录成功"
### 多语言支持
- 简体中文 (`zh-Hant.lproj`)
- 英文 (`en.lproj`)
- 阿拉伯语 (`ar.lproj`)
- 土耳其语 (`tr.lproj`)
## 依赖组件
### 外部框架
- **MASConstraintMaker**: 自动布局
- **ReactiveObjC**: 响应式编程(部分组件使用)
### 内部组件
- **YMLocalizedString**: 本地化字符串管理
- **DESEncrypt**: DES 加密工具
- **AccountInfoStorage**: 账户信息存储
- **HttpRequestHelper**: 网络请求管理
## 扩展和维护
### 新增功能建议
1. **邮箱格式验证**: 添加正则表达式验证邮箱格式
2. **验证码长度限制**: 限制验证码输入长度
3. **自动填充**: 支持系统邮箱自动填充
4. **记住邮箱**: 保存最近使用的邮箱地址
### 性能优化
1. **请求去重**: 防止短时间内重复请求验证码
2. **缓存机制**: 缓存验证码倒计时状态
3. **网络优化**: 添加请求超时和重试机制
### 代码维护
1. **常量管理**: 将硬编码字符串提取为常量
2. **错误码统一**: 统一管理API错误码
3. **日志记录**: 添加详细的操作日志
## 总结
邮箱验证码登录流程是一个完整的用户认证系统,包含了界面展示、验证码获取、用户登录、数据存储等完整环节。该流程具有良好的安全性、用户体验和错误处理机制,符合现代移动应用的认证标准。
通过本文档,开发人员可以全面了解邮箱登录的实现细节,便于后续的功能扩展和维护工作。

View File

@@ -0,0 +1,262 @@
# OAuth/Ticket 认证系统 API 文档
## 概述
本文档描述了 YuMi 应用中 OAuth 认证和 Ticket 会话管理的完整流程。系统采用两阶段认证机制:
1. **OAuth 阶段**:用户登录获取 `access_token`
2. **Ticket 阶段**:使用 `access_token` 获取业务会话 `ticket`
## 认证流程架构
### 核心组件
- **AccountInfoStorage**: 负责账户信息和 ticket 的本地存储
- **HttpRequestHelper**: 网络请求管理,自动添加认证头
- **Api+Login**: 登录相关 API 接口
- **Api+Main**: Ticket 获取相关 API 接口
### 认证数据模型
#### AccountModel
```objc
@interface AccountModel : PIBaseModel
@property (nonatomic, assign) NSString *uid; // 用户唯一标识
@property (nonatomic, copy) NSString *jti; // JWT ID
@property (nonatomic, copy) NSString *token_type; // Token 类型
@property (nonatomic, copy) NSString *refresh_token; // 刷新令牌
@property (nonatomic, copy) NSString *netEaseToken; // 网易云信令牌
@property (nonatomic, copy) NSString *access_token; // OAuth 访问令牌
@property (nonatomic, assign) NSNumber *expires_in; // 过期时间
@end
```
## API 接口详情
### 1. OAuth 登录接口
#### 1.1 手机验证码登录
```objc
+ (void)loginWithCode:(HttpRequestHelperCompletion)completion
phone:(NSString *)phone
code:(NSString *)code
client_secret:(NSString *)client_secret
version:(NSString *)version
client_id:(NSString *)client_id
grant_type:(NSString *)grant_type
phoneAreaCode:(NSString *)phoneAreaCode;
```
**接口路径**: `POST /oauth/token`
**请求参数**:
| 参数名 | 类型 | 必填 | 描述 |
|--------|------|------|------|
| phone | String | 是 | 手机号DES加密 |
| code | String | 是 | 验证码 |
| client_secret | String | 是 | 客户端密钥,固定值:"uyzjdhds" |
| version | String | 是 | 版本号,固定值:"1" |
| client_id | String | 是 | 客户端ID固定值"erban-client" |
| grant_type | String | 是 | 授权类型,验证码登录为:"sms_code" |
| phoneAreaCode | String | 是 | 手机区号 |
**返回数据**: AccountModel 对象
#### 1.2 手机密码登录
```objc
+ (void)loginWithPassword:(HttpRequestHelperCompletion)completion
phone:(NSString *)phone
password:(NSString *)password
client_secret:(NSString *)client_secret
version:(NSString *)version
client_id:(NSString *)client_id
grant_type:(NSString *)grant_type;
```
**接口路径**: `POST /oauth/token`
**请求参数**:
| 参数名 | 类型 | 必填 | 描述 |
|--------|------|------|------|
| phone | String | 是 | 手机号DES加密 |
| password | String | 是 | 密码DES加密 |
| client_secret | String | 是 | 客户端密钥 |
| version | String | 是 | 版本号 |
| client_id | String | 是 | 客户端ID |
| grant_type | String | 是 | 授权类型,密码登录为:"password" |
#### 1.3 第三方登录
```objc
+ (void)loginWithThirdPart:(HttpRequestHelperCompletion)completion
openid:(NSString *)openid
unionid:(NSString *)unionid
access_token:(NSString *)access_token
type:(NSString *)type;
```
**接口路径**: `POST /acc/third/login`
**请求参数**:
| 参数名 | 类型 | 必填 | 描述 |
|--------|------|------|------|
| openid | String | 是 | 第三方平台用户唯一标识 |
| unionid | String | 是 | 第三方平台联合ID |
| access_token | String | 是 | 第三方平台访问令牌 |
| type | String | 是 | 第三方平台类型1:Apple, 2:Facebook, 3:Google等 |
### 2. Ticket 获取接口
#### 2.1 获取 Ticket
```objc
+ (void)requestTicket:(HttpRequestHelperCompletion)completion
access_token:(NSString *)accessToken
issue_type:(NSString *)issueType;
```
**接口路径**: `POST /oauth/ticket`
**请求参数**:
| 参数名 | 类型 | 必填 | 描述 |
|--------|------|------|------|
| access_token | String | 是 | OAuth 登录获取的访问令牌 |
| issue_type | String | 是 | 签发类型,固定值:"multi" |
**返回数据**:
```json
{
"code": 200,
"data": {
"tickets": [
{
"ticket": "eyJhbGciOiJIUzI1NiJ9..."
}
]
}
}
```
### 3. HTTP 请求头配置
所有业务 API 请求都会自动添加以下请求头:
```objc
// 在 HttpRequestHelper 中自动配置
- (void)setupHeader {
AFHTTPSessionManager *client = [HttpRequestHelper requestManager];
// 用户ID头
if ([[AccountInfoStorage instance] getUid].length > 0) {
[client.requestSerializer setValue:[[AccountInfoStorage instance] getUid]
forHTTPHeaderField:@"pub_uid"];
}
// Ticket 认证头
if ([[AccountInfoStorage instance] getTicket].length > 0) {
[client.requestSerializer setValue:[[AccountInfoStorage instance] getTicket]
forHTTPHeaderField:@"pub_ticket"];
}
// 其他公共头
[client.requestSerializer setValue:[NSBundle uploadLanguageText]
forHTTPHeaderField:@"Accept-Language"];
[client.requestSerializer setValue:PI_App_Version
forHTTPHeaderField:@"App-Version"];
}
```
## 使用流程
### 完整登录流程示例
```objc
// 1. 用户登录获取 access_token
[Api loginWithCode:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if (code == 200) {
// 保存账户信息
AccountModel *accountModel = [AccountModel modelWithDictionary:data.data];
[[AccountInfoStorage instance] saveAccountInfo:accountModel];
// 2. 使用 access_token 获取 ticket
[Api requestTicket:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if (code == 200) {
NSArray *tickets = [data.data valueForKey:@"tickets"];
NSString *ticket = [tickets[0] valueForKey:@"ticket"];
// 保存 ticket
[[AccountInfoStorage instance] saveTicket:ticket];
// 3. 登录成功,可以进行业务操作
[self navigateToMainPage];
}
} access_token:accountModel.access_token issue_type:@"multi"];
}
} phone:encryptedPhone
code:verificationCode
client_secret:@"uyzjdhds"
version:@"1"
client_id:@"erban-client"
grant_type:@"sms_code"
phoneAreaCode:areaCode];
```
### 自动登录流程
```objc
- (void)autoLogin {
// 检查本地是否有账户信息
AccountModel *accountModel = [[AccountInfoStorage instance] getCurrentAccountInfo];
if (accountModel == nil || accountModel.access_token == nil) {
[self tokenInvalid]; // 跳转到登录页
return;
}
// 检查是否有有效的 ticket
if ([[AccountInfoStorage instance] getTicket].length > 0) {
[[self getView] autoLoginSuccess];
return;
}
// 使用 access_token 重新获取 ticket
[Api requestTicket:^(BaseModel * _Nonnull data) {
NSArray *tickets = [data.data valueForKey:@"tickets"];
NSString *ticket = [tickets[0] valueForKey:@"ticket"];
[[AccountInfoStorage instance] saveTicket:ticket];
[[self getView] autoLoginSuccess];
} fail:^(NSInteger code, NSString * _Nullable msg) {
[self logout]; // ticket 获取失败,重新登录
} access_token:accountModel.access_token issue_type:@"multi"];
}
```
## 错误处理
### 401 未授权错误
当接收到 401 状态码时,系统会自动处理:
```objc
// 在 HttpRequestHelper 中
if (response && response.statusCode == 401) {
failure(response.statusCode, YMLocalizedString(@"HttpRequestHelper7"));
// 通常需要重新登录
}
```
### Ticket 过期处理
- Ticket 过期时服务器返回 401 错误
- 客户端应该使用保存的 `access_token` 重新获取 ticket
- 如果 `access_token` 也过期,则需要用户重新登录
## 安全注意事项
1. **数据加密**: 敏感信息(手机号、密码)使用 DES 加密传输
2. **本地存储**:
- `access_token` 存储在文件系统中
- `ticket` 存储在内存中,应用重启需重新获取
3. **请求头**: 所有业务请求自动携带 `pub_uid``pub_ticket`
4. **错误处理**: 建立完善的 401 错误重试机制
## 相关文件
- `YuMi/Structure/MVP/Model/AccountInfoStorage.h/m` - 账户信息存储管理
- `YuMi/Modules/YMLogin/Api/Api+Login.h/m` - 登录相关接口
- `YuMi/Modules/YMTabbar/Api/Api+Main.h/m` - Ticket 获取接口
- `YuMi/Network/HttpRequestHelper.h/m` - 网络请求管理
- `YuMi/Structure/MVP/Model/AccountModel.h/m` - 账户数据模型

11
Podfile
View File

@@ -6,12 +6,9 @@ target 'YuMi' do
#pag动画
pod 'libpag'
pod 'Bugly'
pod 'Adjust'
pod 'Firebase/Analytics'
pod 'FBSDKLoginKit'
pod 'FBSDKCoreKit'
pod 'FBSDKShareKit'
pod 'LineSDKSwift'
# 滑动标签栏
pod 'JXCategoryView'
pod 'JXPagingView/Pager'
@@ -47,7 +44,7 @@ target 'YuMi' do
#上传音乐
pod 'CocoaAsyncSocket',:modular_headers => true
#声网
pod 'AgoraRtcEngine_iOS'
pod 'SSKeychain'
pod 'Base64'
#pop动画
@@ -60,17 +57,15 @@ target 'YuMi' do
pod 'mob_linksdk_pro'
pod 'mob_sharesdk'
pod 'mob_sharesdk/ShareSDKPlatforms/Apple'
#pod 'mob_sharesdk/ShareSDKPlatforms/Line'
pod 'mob_sharesdk/ShareSDKExtension'
pod 'UMCommon'
pod 'UMDevice'
# pod 'lottie-ios'
pod 'ZLCollectionViewFlowLayout'
# pod 'WMZDropDownMenu'
pod 'TABAnimated'
pod 'YuMi',:path=>'yum'
pod 'QCloudCOSXML'
pod 'TYCyclePagerView'
end
post_install do |installer|
@@ -78,6 +73,8 @@ post_install do |installer|
project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf-with-dsym'
config.build_settings['ENABLE_BITCODE'] = 'NO'
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
xcconfig_mod = xcconfig.gsub(/DT_TOOLCHAIN_DIR/, "TOOLCHAIN_DIR")

File diff suppressed because it is too large Load Diff

View File

@@ -50,6 +50,13 @@
ReferencedContainer = "container:YuMi.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "OS_ACTIVITY_MODE"
value = "disable"
isEnabled = "NO">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -72,7 +79,7 @@
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -24,10 +24,10 @@
#import "XPRoomViewController.h"
#import "XCCurrentVCStackManager.h"
#import "ClientConfig.h"
#import <Adjust/Adjust.h>
#import <UserNotifications/UserNotifications.h>
#import <Bugly/Bugly.h>
#import <UIKit/UIDevice.h>
#import "YuMi-swift.h"
@@ -41,7 +41,6 @@ UIKIT_EXTERN NSString * adImageName;
[self setLanguage];
[self configShareSDK];
[self configNIMSDK];
[self configAdjust];
[self configBugly];
[self registerNot];
[self initEmojiData];
@@ -77,28 +76,26 @@ UIKIT_EXTERN NSString * adImageName;
/**
Bugly
*/
- (void) configBugly {
BuglyConfig *config = [[BuglyConfig alloc] init];
config.blockMonitorTimeout = 5;
config.unexpectedTerminatingDetectionEnable = YES; // 退
#ifdef DEBUG
config.debugMode = NO;//YES; // debug
config.channel = [YYUtility getAppSource];
// config.blockMonitorEnable = YES; //
config.reportLogLevel = BuglyLogLevelError; // BuglyLogLevelVerbose; //
config.reportLogLevel = BuglyLogLevelWarn;// BuglyLogLevelSilent; // BuglyLogLevelVerbose; //
[Bugly startWithAppId:@"c937fd00f7" config:config];
#else
config.unexpectedTerminatingDetectionEnable = YES; // 退
config.debugMode = NO; // release
config.channel = [YYUtility getAppSource];;
config.blockMonitorEnable = NO; //
config.blockMonitorEnable = YES; //
config.reportLogLevel = BuglyLogLevelWarn; //
NSString *buylyKey = @"8627948559"; // isEnterprise == NO ? @"5334684d86" : @"d65df59a68";
NSString *buylyKey = @"8627948559";
[Bugly startWithAppId:buylyKey config:config];
#endif
}
- (void)configNIMSDK {
// NIMSDK
@@ -123,29 +120,9 @@ UIKIT_EXTERN NSString * adImageName;
#endif
}
-(void)configAdjust{
NSString *appToken = @"p5sndfu9udq8";
NSString *environment;
#ifdef DEBUG
environment = ADJEnvironmentSandbox;
#else
environment = ADJEnvironmentProduction;
#endif
ADJConfig*adjustConfig = [ADJConfig configWithAppToken:appToken
environment:environment];
#ifdef DEBUG
[adjustConfig setLogLevel:ADJLogLevelVerbose];
#else
#endif
[Adjust appDidLaunch:adjustConfig];
}
- (void)configShareSDK {
[PILineLoginManager registerLine];
// [PILineLoginManager registerLine];
[ShareSDK registPlatforms:^(SSDKRegister *platformsRegister) {
///faceBook
@@ -169,12 +146,18 @@ UIKIT_EXTERN NSString * adImageName;
NSArray * emojiArray = dic[@"data"];
NSMutableArray * array = [NSMutableArray array];
for (int i = 0; i < emojiArray.count; i++) {
NSDictionary * dic = [emojiArray objectAtIndex:i];
UIImage * image = [UIImage imageNamed:dic[@"file"]];
QEmotion * info = [[QEmotion alloc] init];
info.identifier = dic[@"id"];
NSDictionary * dic = [emojiArray xpSafeObjectAtIndex:i];
if (dic) {
info.displayName = dic[@"tag"];
info.identifier = dic[@"id"];
}
info.image = image;
info.displayName = dic[@"tag"];
[array addObject:info];
}
//
@@ -195,18 +178,13 @@ UIKIT_EXTERN NSString * adImageName;
NSString *filePath = [XPAdImageTool.shareImageTool getFilePathWithImageName:adName];
BOOL isExist = [XPAdImageTool.shareImageTool isFileExistWithFilePath:filePath];
if ([kUserDefaults integerForKey:@"adShow"]) {
[kUserDefaults setInteger:[kUserDefaults integerForKey:@"adShow"]+1
forKey:@"adShow"];
} else {
[kUserDefaults setInteger:1 forKey:@"adShow"];
}
if (isExist) {//
if ([kUserDefaults integerForKey:@"adShow"] > 4) {
// if ([kUserDefaults integerForKey:@"adShow"] > 4) {
@kWeakify(self);
AdvertiseModel *info = [XPAdImageTool.shareImageTool getAdInfoFromCacheInMainWith:adName];
XPAdvertiseView *advertiseView = [[XPAdvertiseView alloc] initWithFrame:self.window.bounds];
advertiseView.type = info.type;
advertiseView.fileModel = info.fillVo;
advertiseView.filePath = filePath;
advertiseView.dismissHandler = ^(BOOL shouldJump) {
@kStrongify(self)
@@ -218,7 +196,7 @@ UIKIT_EXTERN NSString * adImageName;
});
};
[advertiseView show];
}
// }
}
}
@@ -241,10 +219,13 @@ UIKIT_EXTERN NSString * adImageName;
}
}
break;
case SplashInfoSkipTypeWeb: {
case SplashInfoSkipTypeWeb:
case SplashInfoSkipTypeWeb_CP:
case SplashInfoSkipTypeWeb_Custom:
case SplashInfoSkipTypeWeb_WeekStar: {
// H5
if (info.link.length > 0) {
XPWebViewController *webView = [[XPWebViewController alloc]init];
XPWebViewController *webView = [[XPWebViewController alloc] initWithRoomUID:nil];
webView.url = info.link;
[[[XCCurrentVCStackManager shareManager]currentNavigationController] pushViewController:webView animated:YES];
}

View File

@@ -10,7 +10,6 @@
#import <UMCommon/UMCommon.h>
#import <MobLinkPro/MobLink.h>
#import <MobLinkPro/MLSDKScene.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import "TabbarViewController.h"
#import "BaseNavigationController.h"
#import "AppDelegate+ThirdConfig.h"
@@ -18,14 +17,15 @@
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import "ClientConfig.h"
#import <GoogleSignIn/GoogleSignIn.h>
#import "GULAppDelegateSwizzler.h"
#import <GoogleSignIn/GoogleSignIn.h>
#import "XPLoginViewController.h"
#import "LoginViewController.h"
#import "AccountModel.h"
#import "YuMi-swift.h"
#import "SessionViewController.h"
#import "LoginFullInfoViewController.h"
@import Firebase;
#import "UIView+VAP.h"
#import "SocialShareManager.h"
UIKIT_EXTERN NSString * const kOpenRoomNotification;
@interface AppDelegate ()<IMLSDKRestoreDelegate>
@@ -34,18 +34,54 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
@implementation AppDelegate
//
void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const char* func, NSString *module, NSString *format, ...) {
// MP4 log
return;
// if (format.UTF8String == nil) {
// NSLog(@"log包含非utf-8字符");
// return;
// }
// if (level > VAPLogLevelDebug) {
// va_list argList;
// va_start(argList, format);
// NSString* message = [[NSString alloc] initWithFormat:format arguments:argList];
// file = [NSString stringWithUTF8String:file].lastPathComponent.UTF8String;
// NSLog(@"<%@> %s(%@):%s [%@] - %@",@(level), file, @(line), func, module, message);
// va_end(argList);
// }
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/// sdk
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:@"Launch Screen" bundle:nil];
UIViewController *launchScreenVC = [launchStoryboard instantiateInitialViewController];
self.window.rootViewController = launchScreenVC;
[self.window makeKeyAndVisible];
[VAPView registerHWDLog:qg_VAP_Logger_handler];
/// sdk
[self initThirdConfig];
[self initUM:application launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.window makeKeyAndVisible];
[self loadMainPage];
[self setupLaunchADView];
@kWeakify(self);
[[ClientConfig shareConfig] clientConfig:^{
@kStrongify(self);
dispatch_async(dispatch_get_main_queue(), ^{
[self loadMainPage];
[self setupLaunchADView];
});
}];
if (@available(iOS 15, *)) {
[[UITableView appearance] setSectionHeaderTopPadding:0];
}
return YES;
}
@@ -57,8 +93,6 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
[UMConfigure initWithAppkey:@"6434c6dfd64e686139618269"
channel:@"appstore"];
}
[[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
[FIRApp configure];
[MobLink setDelegate:self];
}
@@ -71,10 +105,12 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
}else{
[self toHomeTabbarPage];
}
[[ClientConfig shareConfig] clientInit];
}
- (void)toLoginPage {
XPLoginViewController *lvc = [[XPLoginViewController alloc] init];
LoginViewController *lvc = [[LoginViewController alloc] init];
BaseNavigationController * navigationController = [[BaseNavigationController alloc] initWithRootViewController:lvc];
navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
self.window.rootViewController = navigationController;
@@ -112,16 +148,16 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
ATTrackingManagerAuthorizationStatus status = ATTrackingManager.trackingAuthorizationStatus;
switch (status) {
case ATTrackingManagerAuthorizationStatusDenied:
NSLog(@"用户拒绝IDFA");
// NSLog(@"用户拒绝IDFA");
break;
case ATTrackingManagerAuthorizationStatusAuthorized:
NSLog(@"用户允许IDFA");
// NSLog(@"用户允许IDFA");
break;
case ATTrackingManagerAuthorizationStatusNotDetermined: {
NSLog(@"用户未做选择或未弹窗IDFA");
// NSLog(@"用户未做选择或未弹窗IDFA");
//1app
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
NSLog(@"app追踪IDFA权限%lu",(unsigned long)status);
// NSLog(@"app追踪IDFA权限%lu",(unsigned long)status);
}];
}
break;
@@ -166,57 +202,47 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
///URL Scheme
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
NSString *bundleID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
if ([url.scheme isEqualToString:[NSString stringWithFormat:@"line3rdp.%@",bundleID]]) {
return [PILineLoginManager applicationOpenurl:app open:url];
}
[[SocialShareManager sharedManager] handleURL:url];
NSString *text = [url query];
if(text.length){
NSMutableDictionary *paramsDict = [NSMutableDictionary dictionary];
NSArray *paramArray = [text componentsSeparatedByString:@"&"];
for (NSString *param in paramArray) {
if (param && param.length) {
NSArray *parArr = [param componentsSeparatedByString:@"="];
if (parArr.count == 2) {
[paramsDict setObject:parArr[1] forKey:parArr[0]];
}
}
}
if(paramsDict[@"type"] != nil){
NSInteger type = [paramsDict[@"type"] integerValue];
if (type == 2) {
NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
[[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"uid":uid}];
ClientConfig *config = [ClientConfig shareConfig];
config.roomId = uid;
}else if(type == 7){
NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
[[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"type":@"kOpenChat",@"uid":uid}];
ClientConfig *config = [ClientConfig shareConfig];
config.chatId = uid;
}else if (type == 8){
NSString *inviteCode = paramsDict[@"inviteCode"];
if (inviteCode != nil && [[AccountInfoStorage instance]getUid].length == 0){
ClientConfig *config = [ClientConfig shareConfig];
config.inviteCode = inviteCode;
}
}
return YES;
}
}
if([url.absoluteString containsString:@"fb1266232494209868"]){
return [[FBSDKApplicationDelegate sharedInstance] application:app
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
return [GIDSignIn.sharedInstance handleURL:url];
}
//- (void)__oldApplicationOpenURLMethod:(NSURL *)url {
// NSString *text = [url query];
// if(text.length){
// NSMutableDictionary *paramsDict = [NSMutableDictionary dictionary];
// NSArray *paramArray = [text componentsSeparatedByString:@"&"];
// for (NSString *param in paramArray) {
// if (param && param.length) {
// NSArray *parArr = [param componentsSeparatedByString:@"="];
// if (parArr.count == 2) {
// [paramsDict setObject:parArr[1] forKey:parArr[0]];
// }
// }
// }
// if(paramsDict[@"type"] != nil){
// NSInteger type = [paramsDict[@"type"] integerValue];
// if (type == 2) {
// NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
// [[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"uid":uid}];
// ClientConfig *config = [ClientConfig shareConfig];
// config.roomId = uid;
// }else if(type == 7){
// NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
// [[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"type":@"kOpenChat",@"uid":uid}];
// ClientConfig *config = [ClientConfig shareConfig];
// config.chatId = uid;
// }else if (type == 8){
// NSString *inviteCode = paramsDict[@"inviteCode"];
// if (inviteCode != nil && [[AccountInfoStorage instance]getUid].length == 0){
// ClientConfig *config = [ClientConfig shareConfig];
// config.inviteCode = inviteCode;
// }
// }
//// return YES;
// }
// }
//}
#pragma mark - Core Data stack
@synthesize managedObjectContext = _managedObjectContext;
@@ -258,7 +284,7 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
@@ -290,7 +316,7 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}

View File

@@ -1,16 +0,0 @@
//
// FBSDKSettings+PISDKSettings.h
// YuMi
//
// Created by duoban on 2023/9/22.
//
#import <FBSDKCoreKit/FBSDKCoreKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface FBSDKSettings (PISDKSettings)
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,19 +0,0 @@
//
// FBSDKSettings+PISDKSettings.m
// YuMi
//
// Created by duoban on 2023/9/22.
//
#import "FBSDKSettings+PISDKSettings.h"
#import "GULAppDelegateSwizzler.h"
@implementation FBSDKSettings (PISDKSettings)
///FBSDKSettingssetAutoLogAppEventsEnabled退
+(void)setAutoLogAppEventsEnabled:(BOOL)is{
}
@end

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

@@ -9,7 +9,7 @@
"scale" : "2x"
},
{
"filename" : "图层 2@3x.png",
"filename" : "1@3x (1).png",
"idiom" : "universal",
"scale" : "3x"
}

View File

@@ -9,7 +9,7 @@
"scale" : "2x"
},
{
"filename" : "图层 1@3x.png",
"filename" : "椭圆 6@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -9,7 +9,7 @@
"scale" : "2x"
},
{
"filename" : "头条框@3x.png",
"filename" : "组 4.jpg@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

View File

@@ -9,7 +9,7 @@
"scale" : "2x"
},
{
"filename" : "路径 6@2x@3x.png",
"filename" : "组 4.jpg@3x-2.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

View File

@@ -1,7 +1,6 @@
{
"images" : [
{
"filename" : "common_new_user_ar.png",
"idiom" : "universal",
"scale" : "1x"
},
@@ -10,6 +9,7 @@
"scale" : "2x"
},
{
"filename" : "moli_money_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -9,7 +9,7 @@
"scale" : "2x"
},
{
"filename" : "示例图@3x.png",
"filename" : "组 7122@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_flag_lv_1@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_flag_lv_2@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_flag_lv_3@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_flag_lv_4@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_flag_lv_5@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_flag_lv_6@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_head_lv_2@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_head_lv_3@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_head_lv_4@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_head_lv_5@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_avatar_head_lv_6@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

View File

@@ -1,7 +1,6 @@
{
"images" : [
{
"filename" : "gift_tag_latest_ar.png",
"idiom" : "universal",
"scale" : "1x"
},
@@ -10,6 +9,7 @@
"scale" : "2x"
},
{
"filename" : "cp_avatar_heart@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "容器 8171@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "框@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "切图 32@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "头像@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "爱心@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "返回 1@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "3@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "3@3x-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "3@3x-3.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "3@3x-4.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "3@3x-5.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "切图 32@3x-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "切图 31@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_relationship_bg@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_relationship_lv_0@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_relationship_lv_1@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_relationship_lv_2@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_relationship_lv_3@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_relationship_lv_4@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cp_relationship_lv_5@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "切图 45@3x-3.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "切图 45@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "切图 45@3x-2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "2@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Some files were not shown because too many files have changed in this diff Show More