HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

从一次被抄袭经历谈起:iOS App 安全保护实战

iOS

'''### 如何保护 iOS App 的最后一道防线:那些你可能忽略的混淆技巧

如果你曾认真反编译过别人的 .ipa 文件,很可能会有这种感受:“哇,这代码也太干净了吧。”
类名像 UserManager,方法名是 getUserToken,甚至资源图片都还叫 btn_login.png。一目了然,直接理解业务逻辑。

当然,安全问题远不止这些,但代码易读性本身就是安全隐患。

继续阅读 »

'''### 如何保护 iOS App 的最后一道防线:那些你可能忽略的混淆技巧

如果你曾认真反编译过别人的 .ipa 文件,很可能会有这种感受:“哇,这代码也太干净了吧。”
类名像 UserManager,方法名是 getUserToken,甚至资源图片都还叫 btn_login.png。一目了然,直接理解业务逻辑。

当然,安全问题远不止这些,但代码易读性本身就是安全隐患。

收起阅读 »

日常开发中,iOS 性能调优我们怎么做?

iOS

'''# 日常开发中,iOS 性能调优我们怎么做?聊聊我用过的几款工具

最近在给一个 iOS 视频类 App 做性能优化,过程中踩了不少坑,也用了一些不错的工具,今天就以一个开发者视角随便聊聊我在调试过程中的一些经验。

一、性能问题到底从哪里开始查?

大多数性能问题其实都是用户先反馈“卡”、“慢”、“闪退”等感知,或者自己在测试设备上感受到不流畅。而到了我们开发者手上,第一步通常不是去改代码,而是定位问题源头。

我的习惯是先观察资源占用,CPU、内存、GPU 都要看。官方工具 Instruments 是首选,功能强大,但也有学习成本高、启动慢的问题。在这方面,我现在更常用的是一个轻量级的监控工具 KeyMob,可以实时显示系统资源占用情况,还支持卡顿帧率监测、网络请求记录等,对我来说特别方便快速地排查方向。

二、调试日志与崩溃分析靠什么?

写 iOS 的都知道,Xcode 控制台输出的日志信息一旦真机多,杂讯就特别多。尤其是一些系统级别的日志经常被覆盖。

我用过一个组合是:Xcode 自带日志 + Bugly 崩溃收集 + KeyMob 实时日志辅助。KeyMob 有一个让我觉得比较贴心的地方,它能抓住 app 的 crash 日志,而且和用户实际操作时间贴合,还能抓住瞬时崩溃前几秒的操作链,这在做重现定位时非常有帮助。

三、文件操作与数据导出效率怎么提升?

开发过程中有时候我们需要查看应用沙盒内的文件,尤其是在处理一些导出调试数据、查看缓存文件的情况。我以前是用 iTools,但后来苹果对系统权限限制越来越多,导致很多工具失效。

KeyMob 的文件浏览和导出功能可以不越狱就查看 App 内部数据,这点我一开始没注意,但在查某个缓存泄漏问题时,确实靠这个省了不少工夫。另外也试过 iMazing,功能更全但偏重,对我这种调试为主的场景稍显复杂。

四、优化点滴靠积累,工具只是手段

其实调优这件事,说到底是靠细节积累的。比如我现在做的一件小事,是每次提交 PR 前会手动在测试机上跑一下性能监控,哪怕不是性能相关的功能,也至少确认一下是否出现新的内存峰值或线程异常增长。

我现在在用的组合大概是:

  • Instruments(系统级别)
  • KeyMob(日常监控与导出)
  • Bugly(线上崩溃)
  • Xcode 控制台 + Console 工具(日志)
  • Occasionally iMazing(高级文件管理)

不是说哪个工具最好,而是哪个在不同阶段、不同问题上用着最顺手。

最后

现在很多开发工具都在“打广告”,但真正做开发的我们其实不太在乎界面多炫酷,更在意稳定和实用。希望这篇小记对你有启发,也欢迎你留言推荐你在用的性能工具,说不定我下次调 bug 就靠它了。'''

继续阅读 »

'''# 日常开发中,iOS 性能调优我们怎么做?聊聊我用过的几款工具

最近在给一个 iOS 视频类 App 做性能优化,过程中踩了不少坑,也用了一些不错的工具,今天就以一个开发者视角随便聊聊我在调试过程中的一些经验。

一、性能问题到底从哪里开始查?

大多数性能问题其实都是用户先反馈“卡”、“慢”、“闪退”等感知,或者自己在测试设备上感受到不流畅。而到了我们开发者手上,第一步通常不是去改代码,而是定位问题源头。

我的习惯是先观察资源占用,CPU、内存、GPU 都要看。官方工具 Instruments 是首选,功能强大,但也有学习成本高、启动慢的问题。在这方面,我现在更常用的是一个轻量级的监控工具 KeyMob,可以实时显示系统资源占用情况,还支持卡顿帧率监测、网络请求记录等,对我来说特别方便快速地排查方向。

二、调试日志与崩溃分析靠什么?

写 iOS 的都知道,Xcode 控制台输出的日志信息一旦真机多,杂讯就特别多。尤其是一些系统级别的日志经常被覆盖。

我用过一个组合是:Xcode 自带日志 + Bugly 崩溃收集 + KeyMob 实时日志辅助。KeyMob 有一个让我觉得比较贴心的地方,它能抓住 app 的 crash 日志,而且和用户实际操作时间贴合,还能抓住瞬时崩溃前几秒的操作链,这在做重现定位时非常有帮助。

三、文件操作与数据导出效率怎么提升?

开发过程中有时候我们需要查看应用沙盒内的文件,尤其是在处理一些导出调试数据、查看缓存文件的情况。我以前是用 iTools,但后来苹果对系统权限限制越来越多,导致很多工具失效。

KeyMob 的文件浏览和导出功能可以不越狱就查看 App 内部数据,这点我一开始没注意,但在查某个缓存泄漏问题时,确实靠这个省了不少工夫。另外也试过 iMazing,功能更全但偏重,对我这种调试为主的场景稍显复杂。

四、优化点滴靠积累,工具只是手段

其实调优这件事,说到底是靠细节积累的。比如我现在做的一件小事,是每次提交 PR 前会手动在测试机上跑一下性能监控,哪怕不是性能相关的功能,也至少确认一下是否出现新的内存峰值或线程异常增长。

我现在在用的组合大概是:

  • Instruments(系统级别)
  • KeyMob(日常监控与导出)
  • Bugly(线上崩溃)
  • Xcode 控制台 + Console 工具(日志)
  • Occasionally iMazing(高级文件管理)

不是说哪个工具最好,而是哪个在不同阶段、不同问题上用着最顺手。

最后

现在很多开发工具都在“打广告”,但真正做开发的我们其实不太在乎界面多炫酷,更在意稳定和实用。希望这篇小记对你有启发,也欢迎你留言推荐你在用的性能工具,说不定我下次调 bug 就靠它了。'''

收起阅读 »

跨平台移动网页调试:那些年踩过的坑和解决方法

iOS

'''### 多端调试的那些坑,你踩过几个?

做移动端网页开发久了,最怕听到一句话:“iPhone 上这块显示有问题。”
你翻出模拟器、查 CSS、开控制台,花上半小时,最后发现——Android 正常,只有 iOS 的 WebView 出现样式错乱。更尴尬的是,问题只在某个具体版本的 Safari 中重现,模拟器甚至都复现不了。

这类 bug,调试难度常常不在逻辑,而在环境。

我们都试过这些“曲线救国”的办法:

  • 用远程桌面连接物理设备,在控制台里尝试 console.log
  • 把日志打印到后端,再看接口调用顺序
  • 甚至用录屏、截图,把现象“传”给自己看

但效率真的很低,尤其当项目迭代频繁、上线时间紧张时,这种方法只会拖慢节奏。


几个值得一试的工具和方法(亲测有用)

我自己在项目中用过几种调试方式,分享几种组合,给有需要的朋友参考:

  1. Chrome DevTools + Remote Debugging
    Android WebView 和 Chrome 浏览器调试效果不错,但不支持 iOS。
  2. Safari Web Inspector
    支持 macOS + iOS 调试,但只能用 mac,还必须用特定版本的 Safari 搭配设备系统版本。
  3. WebDebugX
    最近开始试用的一款工具,支持跨平台(Windows、Linux、macOS)调试 iOS 和 Android 的 WebView 或网页内容。
    调试流程接近 DevTools 的使用习惯,网络监控、DOM 观察、性能指标都比较完整。
    实际场景:之前有个小程序里的 H5 页面在低端 Android 上加载巨慢,网络分析面板一开,就发现原来是图片资源没压缩。优化后加载时间缩短了一半。
  4. Charles/Fiddler 抓包
    网络层面抓包还是挺重要的,尤其是排查 HTTPS 请求失败或 token 错误的情况。

一点体会:调试手段决定了交付速度

我们常说“开发只是一半,调试才是上线的关键一步”。
尤其在多人协作或混合开发环境中,前端页面表现出现问题时,能够快速定位、复现并修复,是保障版本质量的核心能力。

如果你还在用模拟器 + 截图调 bug,不妨试试更新一些的调试方法,也许会带来意想不到的效率提升。


以上经验分享仅供参考,如果你有其他更顺手的跨平台调试组合,也欢迎评论区一起探讨。'''

继续阅读 »

'''### 多端调试的那些坑,你踩过几个?

做移动端网页开发久了,最怕听到一句话:“iPhone 上这块显示有问题。”
你翻出模拟器、查 CSS、开控制台,花上半小时,最后发现——Android 正常,只有 iOS 的 WebView 出现样式错乱。更尴尬的是,问题只在某个具体版本的 Safari 中重现,模拟器甚至都复现不了。

这类 bug,调试难度常常不在逻辑,而在环境。

我们都试过这些“曲线救国”的办法:

  • 用远程桌面连接物理设备,在控制台里尝试 console.log
  • 把日志打印到后端,再看接口调用顺序
  • 甚至用录屏、截图,把现象“传”给自己看

但效率真的很低,尤其当项目迭代频繁、上线时间紧张时,这种方法只会拖慢节奏。


几个值得一试的工具和方法(亲测有用)

我自己在项目中用过几种调试方式,分享几种组合,给有需要的朋友参考:

  1. Chrome DevTools + Remote Debugging
    Android WebView 和 Chrome 浏览器调试效果不错,但不支持 iOS。
  2. Safari Web Inspector
    支持 macOS + iOS 调试,但只能用 mac,还必须用特定版本的 Safari 搭配设备系统版本。
  3. WebDebugX
    最近开始试用的一款工具,支持跨平台(Windows、Linux、macOS)调试 iOS 和 Android 的 WebView 或网页内容。
    调试流程接近 DevTools 的使用习惯,网络监控、DOM 观察、性能指标都比较完整。
    实际场景:之前有个小程序里的 H5 页面在低端 Android 上加载巨慢,网络分析面板一开,就发现原来是图片资源没压缩。优化后加载时间缩短了一半。
  4. Charles/Fiddler 抓包
    网络层面抓包还是挺重要的,尤其是排查 HTTPS 请求失败或 token 错误的情况。

一点体会:调试手段决定了交付速度

我们常说“开发只是一半,调试才是上线的关键一步”。
尤其在多人协作或混合开发环境中,前端页面表现出现问题时,能够快速定位、复现并修复,是保障版本质量的核心能力。

如果你还在用模拟器 + 截图调 bug,不妨试试更新一些的调试方法,也许会带来意想不到的效率提升。


以上经验分享仅供参考,如果你有其他更顺手的跨平台调试组合,也欢迎评论区一起探讨。'''

收起阅读 »

关于subNvue的创建与销毁

uniapp nvue subnvue

subNvue的创建

subNvue作为vue或nvue页面的原生子窗体,当其父页面创建时,subNvue也随之创建,且仅创建一次,其生命周期也只会触发一次(包括onShow)。

subNvue的生命周期

在宿主页面创建时,subNvue的生命周期会依次执行,如onLoad\onMounted\onShow\onReady;
当宿主页面销毁时,剩下的如onUnmounted\onUnload也会依次执行。

值得一提的是,由于subNvue并非页面,即使返回打开,其onShow也只会在初始化时执行一次,如果想要监听其出现和隐藏的事件,可以利用其webview的性质,通过plus.webview.getWebviewById获取到势力,而后添加监听事件,例如:

const webView = plus.webview.getWebviewById(id);  
webView.addEventListener('show', doSomething);  
webView.addEventListener('hide', doSomething);

subNvue的销毁

从官方文档和社区了解到,官方并未给出明确的销毁方法,而是只提供了隐藏方法,然而实践下来,依然可以利用其webview的性质调用close方法进行销毁,不过这种方式官方并不推荐。

经过实践,subNvue的创建与销毁,是与其宿主界面强绑定的,宿主界面创建,它也创建,宿主界面销毁,它也自动销毁(宿主是tabbar的除外),大部分情况下是无需手动销毁的。

然而,上面的规律只对二级界面有效,对于一些寄宿在tabbar页面内的subNvue,其销毁就不知为何无法执行了。

当你多次创建tabbar界面(如reLaunch应用后重进tabbar),那个页面包含的subNvue也会随之多次创建,并保留在内存里。

通过调用 plus.webview.all 方法,在返回的webview列表里,你可以看到多个 id 相同但是 __uniapp_origin_id(父页面的id)不同的subNvue,这也就导致了几个问题:

  • 当你想要通过getSubNVueById方法获取子窗体实例时,你获取到的可能并不是最新的实例,一旦你的子窗体有动态元素,最终渲染出的窗口也大概率是旧内容。
  • 当你想要隐藏某个窗口时,情况也差不多,你无法精准拿到目前在界面上显示的子窗口实例,hide方法虽然执行了,但具体是哪个实例在执行,你也不知道。
  • 所有旧的subNvue都会保存在内存里,即使父页面销毁也依然存留,无疑会增加性能消耗。

所幸,webview提供了close方法,我们可以筛选出id重复的subNvue,通过__uniapp_origin_id进行排序(新创建的页面,其id是递增的),之后手动清理即可。

const clearOldSubNvue = (id) => {  
  const webview = plus.webview  
    .all()  
    .filter((view) => view.id === id)  
    .sort((a, b) => +a.__uniapp_origin_id - +b.__uniapp_origin_id);  

  if (webview.length <= 1) return;  

  webview.forEach((view, index) => {  
    if (index < webview.length - 1) {  
      view.close();  
    }  
  });  
};

关于销毁的时机,可以利用其重复创建的性质,放在subNvue的onLoad或onReady里执行。

值得注意的是,如果我们在父页面销毁前统一销毁子窗口,之后再打开任意subNvue,都会导致navigateBack连续触发两次的bug,原因不明。

继续阅读 »

subNvue的创建

subNvue作为vue或nvue页面的原生子窗体,当其父页面创建时,subNvue也随之创建,且仅创建一次,其生命周期也只会触发一次(包括onShow)。

subNvue的生命周期

在宿主页面创建时,subNvue的生命周期会依次执行,如onLoad\onMounted\onShow\onReady;
当宿主页面销毁时,剩下的如onUnmounted\onUnload也会依次执行。

值得一提的是,由于subNvue并非页面,即使返回打开,其onShow也只会在初始化时执行一次,如果想要监听其出现和隐藏的事件,可以利用其webview的性质,通过plus.webview.getWebviewById获取到势力,而后添加监听事件,例如:

const webView = plus.webview.getWebviewById(id);  
webView.addEventListener('show', doSomething);  
webView.addEventListener('hide', doSomething);

subNvue的销毁

从官方文档和社区了解到,官方并未给出明确的销毁方法,而是只提供了隐藏方法,然而实践下来,依然可以利用其webview的性质调用close方法进行销毁,不过这种方式官方并不推荐。

经过实践,subNvue的创建与销毁,是与其宿主界面强绑定的,宿主界面创建,它也创建,宿主界面销毁,它也自动销毁(宿主是tabbar的除外),大部分情况下是无需手动销毁的。

然而,上面的规律只对二级界面有效,对于一些寄宿在tabbar页面内的subNvue,其销毁就不知为何无法执行了。

当你多次创建tabbar界面(如reLaunch应用后重进tabbar),那个页面包含的subNvue也会随之多次创建,并保留在内存里。

通过调用 plus.webview.all 方法,在返回的webview列表里,你可以看到多个 id 相同但是 __uniapp_origin_id(父页面的id)不同的subNvue,这也就导致了几个问题:

  • 当你想要通过getSubNVueById方法获取子窗体实例时,你获取到的可能并不是最新的实例,一旦你的子窗体有动态元素,最终渲染出的窗口也大概率是旧内容。
  • 当你想要隐藏某个窗口时,情况也差不多,你无法精准拿到目前在界面上显示的子窗口实例,hide方法虽然执行了,但具体是哪个实例在执行,你也不知道。
  • 所有旧的subNvue都会保存在内存里,即使父页面销毁也依然存留,无疑会增加性能消耗。

所幸,webview提供了close方法,我们可以筛选出id重复的subNvue,通过__uniapp_origin_id进行排序(新创建的页面,其id是递增的),之后手动清理即可。

const clearOldSubNvue = (id) => {  
  const webview = plus.webview  
    .all()  
    .filter((view) => view.id === id)  
    .sort((a, b) => +a.__uniapp_origin_id - +b.__uniapp_origin_id);  

  if (webview.length <= 1) return;  

  webview.forEach((view, index) => {  
    if (index < webview.length - 1) {  
      view.close();  
    }  
  });  
};

关于销毁的时机,可以利用其重复创建的性质,放在subNvue的onLoad或onReady里执行。

值得注意的是,如果我们在父页面销毁前统一销毁子窗口,之后再打开任意subNvue,都会导致navigateBack连续触发两次的bug,原因不明。

收起阅读 »

关于更新到新版本,运行到app基座 后 始终卡在ready in ……ms. 基座没反应 解决方案

退回HBuilderX老版本 别更新,我怀疑手机 怀疑数据线 怀疑adb 就是没怀疑版本 我草!!!!!!!!!!!!!

退回HBuilderX老版本 别更新,我怀疑手机 怀疑数据线 怀疑adb 就是没怀疑版本 我草!!!!!!!!!!!!!

没有 Mac,如何把 iOS App 成功上架?

iOS

'''开发者的 iOS 上架折腾记:没有 Mac,也能搞定?

最近在帮朋友把一个跨平台 Flutter 项目上架到 App Store,结果被 iOS 上架的那套流程卡得头都大了。其实这也不是第一次碰壁了——每次到“申请证书 + 打包 + 上传”的时候,开发节奏就被迫暂停,一堆额外配置压得人喘不过气。

问题其实很简单:不是每个人都有一台配置完整的 Mac 设备。很多时候我们写代码都在 Windows 或 Linux 环境里,平时跑模拟器、做调试都没事,但一旦到打包上传 App Store,那就是另一套生态。

这次我试着换了几个思路和工具组合,记录下来或许能帮到跟我一样不想买 Mac 的开发者。


方案一:租云 Mac + Xcode 手动操作(踩坑)

这是很多文章推荐的做法。用阿里云或者别的服务租个 Mac 云主机,上去装个 Xcode,远程登录后再操作证书申请、打包、上传。

实际体验下来——能用,但体验真的一般

  • 网络延迟让 Xcode 操作特别慢,连拖拽都卡
  • 每次都要重新装环境,搞定权限
  • 打包过程非常依赖图形界面,命令行体验不完整

如果你是纯命令行党,可能会抓狂。


方案二:CI/CD 工具链 + Fastlane 自动化(适合大团队)

有一次在公司项目里,我们用的是 GitLab CI + Fastlane 脚本来做自动上传。效果很好,自动申请证书、签名、打包上传一气呵成。但这个方案有几个前提条件:

  • 有稳定的 Mac 运行节点(也可以是 macOS 服务器)
  • 需要写大量配置文件,对 Fastlane 要熟悉
  • 出错时 Debug 成本不低

这个方案更适合团队,但如果你是独立开发者或者外包项目,这种方式显得成本太高


方案三:使用 Appuploader 简化流程(适合个人开发者)

后来我无意间发现了一个叫 Appuploader 的工具,试了一下感觉非常适合我这种非专业 iOS 开发者。

  • 支持 Windows、Linux 甚至 Web 版使用
  • 可以在线申请证书,自动处理开发者/发布证书和描述文件
  • 上传 IPA 文件到 App Store 不依赖 Mac
  • 图形界面操作,清晰直观,文档也详细

最关键的是——我完全没有碰 Xcode,也没有用 Mac,照样把 IPA 上传到了 App Store


除了 Appuploader,还有其他实用工具推荐

如果你也在用 Flutter 或 React Native 开发跨平台 APP,可以考虑配合以下工具组合来提升效率:

  • Visual Studio Code + Flutter 插件:轻量快速,适合跨平台开发调试
  • Codemagic:CI/CD 平台,Flutter 项目上传 App Store 体验不错,不过免费额度有限
  • Appetize.io:在线模拟器,适合展示 iOS 应用给客户预览

工具只是手段,最终目的还是少走弯路,把时间用在产品上而不是流程里。


写在最后

有时候觉得,开发者在技术栈之外,最大的挑战就是和各种平台规则打交道。App Store 上架本身不是很难,但流程复杂、设备要求高,加上每年系统更新带来的证书和描述文件规则变化,真的太容易让人崩溃。

希望这篇记录能给你一些启发。你有没有什么 iOS 上架的奇葩经历?欢迎一起交流~'''

继续阅读 »

'''开发者的 iOS 上架折腾记:没有 Mac,也能搞定?

最近在帮朋友把一个跨平台 Flutter 项目上架到 App Store,结果被 iOS 上架的那套流程卡得头都大了。其实这也不是第一次碰壁了——每次到“申请证书 + 打包 + 上传”的时候,开发节奏就被迫暂停,一堆额外配置压得人喘不过气。

问题其实很简单:不是每个人都有一台配置完整的 Mac 设备。很多时候我们写代码都在 Windows 或 Linux 环境里,平时跑模拟器、做调试都没事,但一旦到打包上传 App Store,那就是另一套生态。

这次我试着换了几个思路和工具组合,记录下来或许能帮到跟我一样不想买 Mac 的开发者。


方案一:租云 Mac + Xcode 手动操作(踩坑)

这是很多文章推荐的做法。用阿里云或者别的服务租个 Mac 云主机,上去装个 Xcode,远程登录后再操作证书申请、打包、上传。

实际体验下来——能用,但体验真的一般

  • 网络延迟让 Xcode 操作特别慢,连拖拽都卡
  • 每次都要重新装环境,搞定权限
  • 打包过程非常依赖图形界面,命令行体验不完整

如果你是纯命令行党,可能会抓狂。


方案二:CI/CD 工具链 + Fastlane 自动化(适合大团队)

有一次在公司项目里,我们用的是 GitLab CI + Fastlane 脚本来做自动上传。效果很好,自动申请证书、签名、打包上传一气呵成。但这个方案有几个前提条件:

  • 有稳定的 Mac 运行节点(也可以是 macOS 服务器)
  • 需要写大量配置文件,对 Fastlane 要熟悉
  • 出错时 Debug 成本不低

这个方案更适合团队,但如果你是独立开发者或者外包项目,这种方式显得成本太高


方案三:使用 Appuploader 简化流程(适合个人开发者)

后来我无意间发现了一个叫 Appuploader 的工具,试了一下感觉非常适合我这种非专业 iOS 开发者。

  • 支持 Windows、Linux 甚至 Web 版使用
  • 可以在线申请证书,自动处理开发者/发布证书和描述文件
  • 上传 IPA 文件到 App Store 不依赖 Mac
  • 图形界面操作,清晰直观,文档也详细

最关键的是——我完全没有碰 Xcode,也没有用 Mac,照样把 IPA 上传到了 App Store


除了 Appuploader,还有其他实用工具推荐

如果你也在用 Flutter 或 React Native 开发跨平台 APP,可以考虑配合以下工具组合来提升效率:

  • Visual Studio Code + Flutter 插件:轻量快速,适合跨平台开发调试
  • Codemagic:CI/CD 平台,Flutter 项目上传 App Store 体验不错,不过免费额度有限
  • Appetize.io:在线模拟器,适合展示 iOS 应用给客户预览

工具只是手段,最终目的还是少走弯路,把时间用在产品上而不是流程里。


写在最后

有时候觉得,开发者在技术栈之外,最大的挑战就是和各种平台规则打交道。App Store 上架本身不是很难,但流程复杂、设备要求高,加上每年系统更新带来的证书和描述文件规则变化,真的太容易让人崩溃。

希望这篇记录能给你一些启发。你有没有什么 iOS 上架的奇葩经历?欢迎一起交流~'''

收起阅读 »

iOS与HTTPS抓包调试小结

iOS

'''最近在做一个多端 SDK 网络请求兼容性的测试,期间遇到一些 HTTPS 请求抓不到、iOS 抓包失效等问题,趁机整理一下我平时抓包时用到的几个工具和技巧,也顺便记录一下对比体验。

一、传统工具的局限

最早用的是 CharlesFiddler,用它们配置代理,设置证书来抓 HTTPS 请求。PC 上用得还算顺手,但到了 iOS 就经常翻车——有些 App 根本不走系统代理,有些即使配置好证书,也因为 SSL Pinning 抓不到包。

Wireshark 是抓底层网络包的利器,但应用层的内容就没那么友好了。很多时候我只是想看一下 POST 请求发了什么数据,不需要那么重的工具。

二、几种工具组合对比

为了解决 iOS 抓包问题,我尝试了几种组合方案:

  • mitmproxy + 自定义证书:功能强大,适合脚本化场景,但配置门槛高,需要一定 Python 基础;
  • Proxyman:macOS 上用起来不错,界面也很清爽,但某些 App 抓不到包,还是逃不过 SSL Pin;
  • Sniffmaster:这是最近开始尝试用的。支持插线抓包 iOS,无需配置代理或安装证书,甚至可以解密 HTTPS 和绕过双向 SSL Pin。最关键的是,它完全不需要注册登录,下载即用。

三、实际使用中的几个场景

  1. 分析登录接口
    在调试某社交 App 登录流程时,iOS 请求失败,返回403。Charles 无法抓包,看不到完整内容。我用 Sniffmaster 插上设备,秒出数据包,定位出是 header 缺了个参数。用脚本改了请求,重试就成功了。
  2. 分析微信小程序 HTTPS 请求
    小程序默认走自己的网络栈,很多代理工具抓不到,我用 Wireshark 抓 TCP 没法还原完整请求。但 Sniffmaster 插线直连,直接还原出 HTTPS 内容,非常方便。
  3. 接口 Mock 与响应干预
    在 Sniffmaster 里可以写 JS 脚本,对请求或响应进行实时修改。例如调试支付流程时,我修改响应状态模拟成功支付,跳过了真实支付流程,方便进行后续页面调试。

四、总结

  • Charles/Fiddler:老牌稳定,但面对 SSL Pin 或复杂抓包场景无力;
  • Wireshark:适合协议分析,不适合日常应用层调试;
  • Sniffmaster:对开发者特别友好,尤其是做 App、爬虫、接口调试这类工作的人,几乎是即插即用,功能覆盖非常全面。

如果你平时需要频繁调试网络请求,特别是对 iOS、HTTPS、双向认证这类需求比较多的,不妨试试第三个,我自己用了大概一周,效率提升真的非常明显。'''

继续阅读 »

'''最近在做一个多端 SDK 网络请求兼容性的测试,期间遇到一些 HTTPS 请求抓不到、iOS 抓包失效等问题,趁机整理一下我平时抓包时用到的几个工具和技巧,也顺便记录一下对比体验。

一、传统工具的局限

最早用的是 CharlesFiddler,用它们配置代理,设置证书来抓 HTTPS 请求。PC 上用得还算顺手,但到了 iOS 就经常翻车——有些 App 根本不走系统代理,有些即使配置好证书,也因为 SSL Pinning 抓不到包。

Wireshark 是抓底层网络包的利器,但应用层的内容就没那么友好了。很多时候我只是想看一下 POST 请求发了什么数据,不需要那么重的工具。

二、几种工具组合对比

为了解决 iOS 抓包问题,我尝试了几种组合方案:

  • mitmproxy + 自定义证书:功能强大,适合脚本化场景,但配置门槛高,需要一定 Python 基础;
  • Proxyman:macOS 上用起来不错,界面也很清爽,但某些 App 抓不到包,还是逃不过 SSL Pin;
  • Sniffmaster:这是最近开始尝试用的。支持插线抓包 iOS,无需配置代理或安装证书,甚至可以解密 HTTPS 和绕过双向 SSL Pin。最关键的是,它完全不需要注册登录,下载即用。

三、实际使用中的几个场景

  1. 分析登录接口
    在调试某社交 App 登录流程时,iOS 请求失败,返回403。Charles 无法抓包,看不到完整内容。我用 Sniffmaster 插上设备,秒出数据包,定位出是 header 缺了个参数。用脚本改了请求,重试就成功了。
  2. 分析微信小程序 HTTPS 请求
    小程序默认走自己的网络栈,很多代理工具抓不到,我用 Wireshark 抓 TCP 没法还原完整请求。但 Sniffmaster 插线直连,直接还原出 HTTPS 内容,非常方便。
  3. 接口 Mock 与响应干预
    在 Sniffmaster 里可以写 JS 脚本,对请求或响应进行实时修改。例如调试支付流程时,我修改响应状态模拟成功支付,跳过了真实支付流程,方便进行后续页面调试。

四、总结

  • Charles/Fiddler:老牌稳定,但面对 SSL Pin 或复杂抓包场景无力;
  • Wireshark:适合协议分析,不适合日常应用层调试;
  • Sniffmaster:对开发者特别友好,尤其是做 App、爬虫、接口调试这类工作的人,几乎是即插即用,功能覆盖非常全面。

如果你平时需要频繁调试网络请求,特别是对 iOS、HTTPS、双向认证这类需求比较多的,不妨试试第三个,我自己用了大概一周,效率提升真的非常明显。'''

收起阅读 »

iOS 开发者防逆向的几种常见做法和工具推荐

iOS

'''写这篇文章,是因为经历了一个“被扒源代码”的真实事件。

我们上线了一个 B 端 App,功能不复杂,但涉及几个行业定制协议和组件封装。上线一周后,团队在 GitHub 上偶然发现一个“XX App 教学源码分析”仓库,打开一看,基本把我们项目的架构、命名、核心资源全分析清楚了。虽然不涉及商业机密,但那一刻真的让人后背发凉。

这才意识到:不是我们项目被盯上了,而是任何不上锁的 IPA 都是待宰羔羊。市面上 class-dump、IDA、Hopper 等工具太好用了,哪怕你写得再规范、再干净,也架不住代码暴露得太清楚。

于是我开始研究 iOS 加固方案,走过不少弯路。以下是整理出的几种常见做法和推荐工具,供参考:


1. Plist 精简和属性隐藏

首先检查 Info.plist,这往往是分析者的第一入口。

删掉没必要的字段,隐藏主类路径(Main storyboard name)、第三方 SDK 标识、Scheme 配置等是第一步。可以在 Xcode 的 Build Phase 添加脚本处理,比如自动替换某些字段为默认值或空。


2. 资源图像加密或混淆命名

很多逆向者就是靠资源路径和图片来判断 UI 架构。比如看到 login_icon.png 和 submit_bg@2x.png 就知道你写了哪些页面。

处理方式是写一个小工具,批量重命名并替换资源文件,甚至通过改变 MD5 或编码方式让它们在文件系统中“看起来不同”。


3. IPA 级别的混淆加固工具

代码混淆是重点。OC/Swift 的命名暴露是非常致命的事情,class-dump、Ghidra、IDA 都可以轻松导出类结构和方法名。

这里我试过多个工具,后来稳定用下来的是一个叫 Ipa Guard 的工具。它不需要源码,直接在 IPA 上操作,混淆函数名、类名、变量名,还可以处理图片资源和 plist,最重要的是支持 OC、Swift、Flutter、React Native、H5 几乎所有主流框架。

比如,我测试时原函数名是 -[UserManager loginWithUser:],混淆后直接变成了 -[XZ93_qL9 xq9_z29:],class-dump 扫出来完全看不懂了。

它适合做为构建流程的一部分放到自动化管道里,比如 Jenkins 打包完直接调用命令行处理,效率很高。


4. 网络请求加固:反调试 + 签名机制

如果你的 API 调用逻辑也暴露,那很可能还会被别人复用接口。

我们后来在网络层加入了:

  • App 签名验证(请求中带唯一 token)
  • 时间戳 + 签名校验
  • 简单的 AES 加密 Payload·
  • 检查是否在越狱设备或模拟器环境下运行

这些虽然不能完全防住,但对于低门槛的抓包和自动脚本工具足够有效。


5. 基本的防调试手段

比如使用 ptrace 阻止调试器附加,检测 DYLD_INSERT_LIBRARIES 环境变量是否被注入,判断是否运行在 Jailbreak 环境等,这些是比较基础的做法,App 安全 SDK 里都有实现,也可以自己通过 runtime 加一层。


我是踩过坑之后才知道:上线不等于安全结束,而是风险的开始。

App 安全不是要追求绝对防御,而是尽可能提高攻击成本。很多人不动你,是因为发现你动起来很麻烦。

我强烈建议每个开发者哪怕资源有限,也至少做一层 IPA 混淆,把最容易被读懂的部分“打乱”。像 Ipa Guard 这种不改源码、上手快的工具,就非常适合在小团队中应用。

如果你也有相关经验或踩过坑,欢迎留言补充,我们一起把这个“容易被忽视但非常必要”的安全环节做得更好。'''

继续阅读 »

'''写这篇文章,是因为经历了一个“被扒源代码”的真实事件。

我们上线了一个 B 端 App,功能不复杂,但涉及几个行业定制协议和组件封装。上线一周后,团队在 GitHub 上偶然发现一个“XX App 教学源码分析”仓库,打开一看,基本把我们项目的架构、命名、核心资源全分析清楚了。虽然不涉及商业机密,但那一刻真的让人后背发凉。

这才意识到:不是我们项目被盯上了,而是任何不上锁的 IPA 都是待宰羔羊。市面上 class-dump、IDA、Hopper 等工具太好用了,哪怕你写得再规范、再干净,也架不住代码暴露得太清楚。

于是我开始研究 iOS 加固方案,走过不少弯路。以下是整理出的几种常见做法和推荐工具,供参考:


1. Plist 精简和属性隐藏

首先检查 Info.plist,这往往是分析者的第一入口。

删掉没必要的字段,隐藏主类路径(Main storyboard name)、第三方 SDK 标识、Scheme 配置等是第一步。可以在 Xcode 的 Build Phase 添加脚本处理,比如自动替换某些字段为默认值或空。


2. 资源图像加密或混淆命名

很多逆向者就是靠资源路径和图片来判断 UI 架构。比如看到 login_icon.png 和 submit_bg@2x.png 就知道你写了哪些页面。

处理方式是写一个小工具,批量重命名并替换资源文件,甚至通过改变 MD5 或编码方式让它们在文件系统中“看起来不同”。


3. IPA 级别的混淆加固工具

代码混淆是重点。OC/Swift 的命名暴露是非常致命的事情,class-dump、Ghidra、IDA 都可以轻松导出类结构和方法名。

这里我试过多个工具,后来稳定用下来的是一个叫 Ipa Guard 的工具。它不需要源码,直接在 IPA 上操作,混淆函数名、类名、变量名,还可以处理图片资源和 plist,最重要的是支持 OC、Swift、Flutter、React Native、H5 几乎所有主流框架。

比如,我测试时原函数名是 -[UserManager loginWithUser:],混淆后直接变成了 -[XZ93_qL9 xq9_z29:],class-dump 扫出来完全看不懂了。

它适合做为构建流程的一部分放到自动化管道里,比如 Jenkins 打包完直接调用命令行处理,效率很高。


4. 网络请求加固:反调试 + 签名机制

如果你的 API 调用逻辑也暴露,那很可能还会被别人复用接口。

我们后来在网络层加入了:

  • App 签名验证(请求中带唯一 token)
  • 时间戳 + 签名校验
  • 简单的 AES 加密 Payload·
  • 检查是否在越狱设备或模拟器环境下运行

这些虽然不能完全防住,但对于低门槛的抓包和自动脚本工具足够有效。


5. 基本的防调试手段

比如使用 ptrace 阻止调试器附加,检测 DYLD_INSERT_LIBRARIES 环境变量是否被注入,判断是否运行在 Jailbreak 环境等,这些是比较基础的做法,App 安全 SDK 里都有实现,也可以自己通过 runtime 加一层。


我是踩过坑之后才知道:上线不等于安全结束,而是风险的开始。

App 安全不是要追求绝对防御,而是尽可能提高攻击成本。很多人不动你,是因为发现你动起来很麻烦。

我强烈建议每个开发者哪怕资源有限,也至少做一层 IPA 混淆,把最容易被读懂的部分“打乱”。像 Ipa Guard 这种不改源码、上手快的工具,就非常适合在小团队中应用。

如果你也有相关经验或踩过坑,欢迎留言补充,我们一起把这个“容易被忽视但非常必要”的安全环节做得更好。'''

收起阅读 »

5个真正提升我iOS开发效率的工具:来自一线项目的使用经验

iOS

'''作为一名在创业团队里做iOS开发的工程师,我深知时间和效率的价值。我们没有大厂的资源和时间成本去“慢慢调Bug”,但对产品质量和性能的要求却一样不能妥协。

这些年我陆续尝试了很多工具,有些看起来酷炫但实用性一般;也有一些一开始不起眼,但用过后就回不去了。今天分享我真实使用后留下的5个工具,全部实战验证有效,尤其适合团队小、任务紧、节奏快的移动开发者。


1. Instruments(Xcode自带)

很多新手对它望而却步,但Instruments其实是苹果生态里最核心的性能分析工具。像Leaks、Time Profiler、Allocations这些模块,虽然学习曲线略陡,但熟练掌握后,基本能解决80%的性能与内存问题。

不过它的缺点也明显:数据碎片化、保存性差、多人协作不友好。尤其是一些不易复现的问题,经常需要重复采集,工作效率大打折扣。


2. KeyMob(真机性能监控与调试)

这是我们团队近半年用下来评价非常高的一款工具。它不像传统调试工具那样复杂,连接iPhone后就能直接看到包括CPU占用、内存、帧率、磁盘IO、网络波动在内的多维指标。

实例一:线上卡顿问题复盘

有一次线上反馈App在iPhone SE2上打开“图表展示页”有严重卡顿。我们测试了无数次都无法复现。后来通过KeyMob的历史卡顿轨迹记录,发现该页面加载了一个大图片,并且在主线程做了解码操作,才导致老设备加载卡顿。优化后,该问题一次修复。

实例二:数据文件解密

在调试某个数据同步逻辑时,我们需要验证App写入的本地文件内容。KeyMob内置的文件解密与导出工具,让我们直接在Mac上提取目标文件,并解密查看内容结构,快速发现了一个字段命名错误导致的数据未写入问题。

更重要的是,它不需要越狱,UI简洁,几乎没有学习成本。每次上线前我们都会跑一次KeyMob全流程作为稳定性检查。


3. Proxyman & Charles(抓包调试)

iOS的网络抓包工具其实选择不少,但如果你关心界面体验与HTTPS友好度,Proxyman是比Charles更现代的选择。它支持SwiftUI界面调试、自定义断点模拟,还可以协同多个模拟器进行并发测试。

我们经常用它来模拟延迟、请求失败等场景,对于优化异常处理逻辑特别有用。


4. Fastlane(自动打包部署)

手动打包是最不值钱的事情。Fastlane能帮你自动化完成签名、构建、上传TestFlight、发版本邮件提醒等一整套流程。

我们给它加了一个小功能:如果某次打包失败,它会自动在Slack群里发通知,并附上Xcode的build log,省去了重复排查流程。


5. Reveal(UI层级分析)

调UI布局错位、Z-index冲突时,用断点调试简直是折磨。Reveal让你可以像玩3D模型一样查看App界面结构。特别是在处理自定义动画或Popup层叠关系时,它能精准还原真实结构,效率提高不是一点点。


写在最后

工具再多,也只是手段,真正重要的是你在实战中怎么用它们。每个项目的需求不同,但调试、测试、优化这些过程是任何一位开发者都绕不开的。找到合适自己的工具,能节省下来的不仅是时间,更是解决问题的信心和节奏感。

以上这些工具,都是我自己或团队真实在用的。希望这篇文章能为你省下一些反复摸索的时间。如果你也有实用工具,欢迎留言互相交流。'''

继续阅读 »

'''作为一名在创业团队里做iOS开发的工程师,我深知时间和效率的价值。我们没有大厂的资源和时间成本去“慢慢调Bug”,但对产品质量和性能的要求却一样不能妥协。

这些年我陆续尝试了很多工具,有些看起来酷炫但实用性一般;也有一些一开始不起眼,但用过后就回不去了。今天分享我真实使用后留下的5个工具,全部实战验证有效,尤其适合团队小、任务紧、节奏快的移动开发者。


1. Instruments(Xcode自带)

很多新手对它望而却步,但Instruments其实是苹果生态里最核心的性能分析工具。像Leaks、Time Profiler、Allocations这些模块,虽然学习曲线略陡,但熟练掌握后,基本能解决80%的性能与内存问题。

不过它的缺点也明显:数据碎片化、保存性差、多人协作不友好。尤其是一些不易复现的问题,经常需要重复采集,工作效率大打折扣。


2. KeyMob(真机性能监控与调试)

这是我们团队近半年用下来评价非常高的一款工具。它不像传统调试工具那样复杂,连接iPhone后就能直接看到包括CPU占用、内存、帧率、磁盘IO、网络波动在内的多维指标。

实例一:线上卡顿问题复盘

有一次线上反馈App在iPhone SE2上打开“图表展示页”有严重卡顿。我们测试了无数次都无法复现。后来通过KeyMob的历史卡顿轨迹记录,发现该页面加载了一个大图片,并且在主线程做了解码操作,才导致老设备加载卡顿。优化后,该问题一次修复。

实例二:数据文件解密

在调试某个数据同步逻辑时,我们需要验证App写入的本地文件内容。KeyMob内置的文件解密与导出工具,让我们直接在Mac上提取目标文件,并解密查看内容结构,快速发现了一个字段命名错误导致的数据未写入问题。

更重要的是,它不需要越狱,UI简洁,几乎没有学习成本。每次上线前我们都会跑一次KeyMob全流程作为稳定性检查。


3. Proxyman & Charles(抓包调试)

iOS的网络抓包工具其实选择不少,但如果你关心界面体验与HTTPS友好度,Proxyman是比Charles更现代的选择。它支持SwiftUI界面调试、自定义断点模拟,还可以协同多个模拟器进行并发测试。

我们经常用它来模拟延迟、请求失败等场景,对于优化异常处理逻辑特别有用。


4. Fastlane(自动打包部署)

手动打包是最不值钱的事情。Fastlane能帮你自动化完成签名、构建、上传TestFlight、发版本邮件提醒等一整套流程。

我们给它加了一个小功能:如果某次打包失败,它会自动在Slack群里发通知,并附上Xcode的build log,省去了重复排查流程。


5. Reveal(UI层级分析)

调UI布局错位、Z-index冲突时,用断点调试简直是折磨。Reveal让你可以像玩3D模型一样查看App界面结构。特别是在处理自定义动画或Popup层叠关系时,它能精准还原真实结构,效率提高不是一点点。


写在最后

工具再多,也只是手段,真正重要的是你在实战中怎么用它们。每个项目的需求不同,但调试、测试、优化这些过程是任何一位开发者都绕不开的。找到合适自己的工具,能节省下来的不仅是时间,更是解决问题的信心和节奏感。

以上这些工具,都是我自己或团队真实在用的。希望这篇文章能为你省下一些反复摸索的时间。如果你也有实用工具,欢迎留言互相交流。'''

收起阅读 »

“运行到Android App基座"操作

华为手机mate 50, 在进行“运行到Android App基座"操作时,打开USB调试后,只有在“选择USB配置”中选择“音频来源”才能成功。

华为手机mate 50, 在进行“运行到Android App基座"操作时,打开USB调试后,只有在“选择USB配置”中选择“音频来源”才能成功。

ReferenceError: uni is not defined

uni_app项目

ReferenceError: uni is not defined
at _callee2$ (utils.js? [sm]:21)
at s (regeneratorRuntime.js:1)
at Generator.<anonymous> (regeneratorRuntime.js:1)
at Generator.next (regeneratorRuntime.js:1)
at asyncGeneratorStep (asyncToGenerator.js:1)
at c (asyncToGenerator.js:1)
at asyncToGenerator.js:1
at new Promise (<anonymous>)
at Object.<anonymous> (asyncToGenerator.js:1)
at Object._setSs (utils.js? [sm]:22)(env: Windows,mp,1.06.2409140; lib: 3.8.3)

如果出现这个问题,不要把那些js文件放在static下面
类似我放的那个图,一开始utils文件夹在static目录下,拿出来就好了

继续阅读 »

ReferenceError: uni is not defined
at _callee2$ (utils.js? [sm]:21)
at s (regeneratorRuntime.js:1)
at Generator.<anonymous> (regeneratorRuntime.js:1)
at Generator.next (regeneratorRuntime.js:1)
at asyncGeneratorStep (asyncToGenerator.js:1)
at c (asyncToGenerator.js:1)
at asyncToGenerator.js:1
at new Promise (<anonymous>)
at Object.<anonymous> (asyncToGenerator.js:1)
at Object._setSs (utils.js? [sm]:22)(env: Windows,mp,1.06.2409140; lib: 3.8.3)

如果出现这个问题,不要把那些js文件放在static下面
类似我放的那个图,一开始utils文件夹在static目录下,拿出来就好了

收起阅读 »