- Swift 72.3%
- Python 20.5%
- Shell 7.2%
| 文件名 | 最新提交消息 | 最新提交日期 |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| scripts | ||
| Tests | ||
| UCAS_Sign_in_iOS | ||
| UCAS_Sign_in_iOS.xcodeproj | ||
| .gitignore | ||
| apps.json | ||
| LICENSE | ||
| README.md | ||
UCAS 签到 · Swift 原生 iOS
基于 lccipher/UCAS-Course-Sign-in 的原生移植。使用 SwiftUI + URLSession + Core Image,无第三方依赖,无需部署网页后端。支持 iOS 17 及以上。
运行
- 使用 Xcode 打开
UCAS_Sign_in_iOS.xcodeproj。 - 选择
UCAS_Sign_in_iOSScheme 和 iPhone 模拟器,按 ⌘R。 - 真机运行时,在 Signing & Capabilities 中选择自己的开发团队。
功能
- 使用SEP邮箱账号、密码和日期查询课表,按课程名或教师筛选。
- 选择课程生成二维码,或手动输入数字课程 ID / 32 位 UUID(支持连字符)。
- 二维码每 5 秒刷新,回到前台时重新生成;支持复制链接和原生分享图片,可通过分享面板保存到文件。
- 服务器时间校准,沿用参考项目的 3 秒时钟偏差缓冲。校准失败时明确提示,使用上次校准结果或设备时间。
- 查询所得课程可直接签到,开放时间为北京时间开课前 30 分钟至下课前;仅服务器明确返回成功才更新签到状态。
- 浅色、深色和跟随系统主题。
分享图片是当前二维码快照,不会自动刷新,也不承诺导出后的有效时长。该行为与参考网页为下载图片设置未来时间戳的做法不同。
结构
ContentView.swift:课程、手动生成、设置三个原生页面。Models/Course.swift:课程数据、北京时间处理、签到参数生成。Services/CredentialStore.swift:本机钥匙串中的凭据读取、更新与清除;存储失败会显示错误。Services/UCASClient.swift:登录、课表、校时、签到;使用临时 URLSession,不持久化 Cookie 或响应缓存。Views/QRCodeView.swift:本地二维码、前台刷新、原生分享、签到反馈。Tests/ProtocolChecks.swift:使用 URLProtocol 模拟学校响应,验证协议和失败分支。references/:被 Git 忽略的参考仓库。
SEP邮箱账号和密码在输入时自动保存到本机钥匙串,使用 WhenUnlockedThisDeviceOnly,不进行 iCloud 同步,下次启动自动填入。会话和课表只存在当前进程内存中,主题偏好使用 UserDefaults。点击「清除已保存的账号密码」可以删除钥匙串凭据并清除表单和课表;已经发出的网络请求可能仍会完成,但结果不会重新填入已清空的页面。
验证
./Tests/run.sh
xcodebuild -scheme UCAS_Sign_in_iOS -configuration Debug -sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
-derivedDataPath /tmp/UCAS-Swift-Build CODE_SIGNING_ALLOWED=NO build
协议测试覆盖:输入校验、特殊字符表单编码、数字/字符串响应字段、签到时间边界、登录失败、HTTP 错误、无效 JSON、空课表、异常课表结构、校时、签到成功及未完成状态。测试不调用真实学校接口。
已通过模拟器构建和启动验证。真实账号查询、真实签到及真机签名需要在实际环境中验证;学校接口可能存在网络或证书限制。应用保留系统默认 HTTPS 证书校验。
来源与许可
移植参考版本:3bb1827,项目作者 lccipher。原项目采用 GNU AGPL v3,本移植沿用该许可证,全文见 LICENSE,应用内「设置 → 开源许可证」也可查看。
导出给 LiveContainer
./scripts/export-livecontainer.sh
输出文件名会包含 APP_VERSION,例如 dist/UCAS-Sign-in-1.0.12-LiveContainer.ipa。SHA-256 校验值、metadata.json 和构建日志也在 dist/ 中,该目录不提交 Git。可以通过环境变量覆盖构建版本和输出目录:
APP_VERSION=1.0.12 BUILD_NUMBER=12 ./scripts/export-livecontainer.sh
该 IPA 是 iOS 真机 arm64 Release 构建,最低 iOS 17.0,采用本地 ad-hoc 完整性签名,不含开发者证书或设备 UDID 限制,不是 App Store / 企业分发包。将文件传到 iPhone 的「文件」App,在 LiveContainer 内点击「+」选择 IPA 导入,再按 LiveContainer 当前配置完成签名并启动。不能通过普通 iOS 安装流程直接安装此包。
LiveContainer 版本、设备系统以及签名/JIT 环境会影响运行兼容性。已验证 IPA 结构和真机可执行文件,尚未在实际 LiveContainer 内运行测试,不能保证任意版本均兼容。
Forgejo 自动发布
.forgejo/workflows/livecontainer.yml 供安装了 Xcode 的 macOS self-hosted runner 使用。向 main 推送后,它会运行协议测试、构建 arm64 Release IPA,并把 IPA 和 apps.json 发布到独立的 YY404NF/LiveContainer-Apps 仓库。在仓库 Actions secrets 中设置 FORGEJO_TOKEN(需要创建 Release 和上传附件的权限),并按实际 runner 标签调整 workflow 的 runs-on。
源地址固定为:
https://livecontainer.404nf.com/apps.json
手机只保存 livecontainer.404nf.com,域名背后再由 HKG Caddy 映射到 Forgejo 的源仓库;以后更换仓库或存储位置时不需要重新添加源。每次 push 默认生成 基础版本.运行号 形式的短版本号,例如 1.0.12,并保留最新版本和 3 个旧版本。手动运行 workflow 时可以传入 app_version 覆盖该版本。