我受够了 Xcode 的 SPM 网络问题,写了个脚本一劳永逸

上周五下午,项目 SPM 又卡在 Resolve 上了。进度条纹丝不动,等了 20 分钟,还是那个转圈。

我做了和每次一样的操作:开全局代理 → Resolve 成功 → 发现内网 GitLab 拉不到了 → 关代理 → 下次又卡。

这个循环我重复了大半年。终于决定彻底解决它。

问题出在哪

三个坑叠在一起:

1. Xcode 不走系统代理

终端里 git clone 飞快,Xcode 里 Resolve Package 卡死。原因是 Xcode 有自己的网络栈,不读系统的 http_proxy 设置,也不走 VPN 分流规则。

2. 全局代理和内网冲突

为了让 Xcode 能访问 GitHub,你开了全局代理。然后公司内网的 GitLab、Jenkins、各种内部服务全挂了。你要么来回切,要么配复杂的分流规则。

3. Reset Package 就从头来

好不容易下载完了,手一抖点了 Reset Package Caches(或者 Xcode 自己抽风),所有依赖重新下载。你前面等的 20 分钟白等了。

解题思路

我回想了 CocoaPods 时代的做法:pod install 在终端跑,终端天然支持代理配置。下完的库就在 Pods/ 目录里,Xcode 直接引用本地文件,根本不需要网络。

SPM 能不能也这么干?

能。Xcode 的 Add Local Package 功能,就是引用一个本地目录作为 SPM 包。那我只需要:

  1. 在终端把三方库 clone 下来(终端可以走代理)
  2. Xcode 引用本地路径(不走网络)

这样 Xcode 永远不需要自己去 GitHub 拉代码。Reset Package 也无所谓,本地文件还在。

实现

整个方案就三个文件:

bash 复制代码
 Packages/
 ├── packages.json             # 依赖清单
 ├── scripts/
 │   └── fetch-packages.sh     # 下载脚本
 └── Caches/                   # 三方库源码(gitignore)

依赖清单

packages.json 格式很简单,贴近 SPM 自己的 Package.resolved:

css 复制代码
 [  { "url": "https://github.com/SnapKit/SnapKit" },  { "url": "https://github.com/iAmMccc/SmartCodable.git", "version": "4.3.7" } ]

url 必填,version 可选。不填版本就拉默认分支最新代码,填了就 checkout 到对应 tag。

执行脚本

bash 复制代码
 ./Packages/scripts/fetch-packages.sh

脚本做的事情:

  1. 读取 packages.json,从 URL 自动解析库名
  2. 没下载过的 → git clone
  3. 已存在且版本匹配 → 跳过
  4. 已存在但版本变了 → fetch + checkout

脚本自动继承终端的 http_proxy / https_proxy,所以你终端能翻墙,脚本就能翻墙。

执行结果长这样:

css 复制代码
 [下载] SnapKit
 [下载] SmartCodable 4.3.7
 ​
 完成。下载: 2 / 更新: 0 / 跳过: 0 / 失败: 0

第二次跑:

css 复制代码
 [跳过] SnapKit
 [跳过] SmartCodable 4.3.7
 ​
 完成。下载: 0 / 更新: 0 / 跳过: 2 / 失败: 0

已经有的不会重复下载。

Xcode 引用

File → Add Package Dependencies → Add Local → 选 Packages/Caches/SnapKit

每个库只需要添加一次。之后不管你 Reset 多少次,本地文件都在,Xcode 直接用。

日常工作流

场景 操作
新增依赖 packages.json 加一条 → 跑脚本 → Xcode Add Local
更新版本 version → 跑脚本 → Xcode Resolve
新同事加入 clone 项目 → 跑一次脚本 → 齐活
Reset Package 无影响,本地文件还在

一键安装

如果你想直接用,在项目根目录跑:

bash 复制代码
 curl -sL https://raw.githubusercontent.com/iAmMccc/ai-essentials/main/install-skill.sh | bash -s spm-local

会自动生成 Packages/ 目录结构、下载脚本、示例配置,并把 Packages/Caches/ 加进 .gitignore

几个细节

  • Packages/Caches/ 不提交到 Git,三方库源码不应该进仓库
  • 如果某个库是另一个库的 SPM 依赖(比如你用的 A 库依赖了 B 库),B 也要一起本地化,否则 Xcode 还是会去网上找 B
  • 脚本依赖 python3 解析 JSON,macOS 自带,不需要额外安装

本质上就一句话:让终端替 Xcode 干网络的活。终端能走代理,下载一次就缓存到本地,Xcode 只负责引用本地文件。三个问题同时解决。

相关推荐
人月神话-Lee3 小时前
两个改动,让这个iOS OCR SDK识别成功率翻了一倍
ios·ocr·ai编程·身份证识别·银行卡识别
sweet丶14 小时前
流程图解:Asset Catalog 的完整生命周期
ios
空中海2 天前
iOS 动态分析、抓包与 Frida Hook
ios·职场和发展·蓝桥杯
空中海2 天前
iOS 静态逆向、IPA 结构与 Mach-O 分析
ios·华为·harmonyos
Mr -老鬼2 天前
EasyClick 双端自动化智能体|Android&iOS 全平台 EC 脚本开发助手
android·ios·自动化·易点云测·#easyclick·#ios自动化
空中海2 天前
01. iOS 逆向基础、环境搭建与授权
macos·ios·cocoa
空中海2 天前
iOS LLDB 调试、Mach-O、Runtime 与二进制分析
macos·ios·cocoa
空中海2 天前
iOS 防护、加固复测与综合交付
macos·ios·cocoa
懋学的前端攻城狮3 天前
iOS 列表性能优化实战:从 45fps 到 60fps 的蜕变
ios·性能优化·ui kit