iOS 原生开发从 Xcode 开始。下面从一个空白项目出发,做出可以在模拟器和 iPhone 上运行的应用。
iOS 原生 App 是安装在 iPhone 或 iPad 上的应用。它可以使用相机、照片、定位、通知、健康、Wallet、NFC、Face ID 和本地数据,也能继续扩展到 Apple Watch、Mac、Widget、Live Activity 和 CarPlay。
企业会用它做移动银行、门店服务、销售工具、现场巡检、医疗健康和员工应用。选择原生 iOS 往往不是为了“看起来更像苹果”,而是需要稳定接入 Apple 的系统能力、无障碍、隐私权限和设备管理。
Swift、SwiftUI 和 Xcode 是什么
第一次接触 iOS 开发,最容易把这三个名字混在一起:
Swift 是编写业务逻辑的语言;
SwiftUI 是用 Swift 描述界面的工具;
Xcode 是创建项目、运行模拟器、连接真机、签名和上传 App 的开发软件。
SwiftUI 可以同时服务 iPhone、iPad、Mac、Apple Watch 和 Vision Pro,但“可以共享界面代码”不等于所有设备会自动得到合适的体验。手机、平板和桌面的窗口、导航和输入方式不同,仍然要分别检查。
真实产品里的 SwiftUI
Apple Developer 的团队文章很适合看真实产品怎样采用 SwiftUI,而不是只看教学 Demo。
Tiimo 是一款面向神经多样性人群的计划工具,提供 iPhone、iPad 和 Apple Watch 版本。团队没有为了追新技术一次重写全部应用,而是结合产品路线逐步迁移,让无障碍、动画和多设备支持更容易维护。
Copilot Money 是另一个完全不同的产品:它会整理账户、交易和现金流。这个应用最初使用 Swift 和 UIKit,后来把新的 Cash Flow 功能用 SwiftUI 与 Swift Charts 做出来,并让 iOS 和 macOS 版本共享更多实现。
什么时候适合做 iOS 原生 App
如果产品主要服务 iPhone 用户,需要深度使用 Apple 平台能力,或者对隐私、无障碍、性能和长期维护要求较高,SwiftUI 原生方案很合适。已有 UIKit 项目也可以逐页加入 SwiftUI,不必一开始就重写。
如果只是简单表单、活动页或内容查询,手机网页和 PWA 可能已经足够;如果必须同时覆盖 iOS 与 Android,而且两端功能几乎完全一致,可以先比较 Flutter、React Native 或双端原生的长期成本。无论选哪一种,都不能跳过真实设备测试。
要做的应用:冰箱大厨
接下来做一个原生 iPhone 应用:冰箱大厨 FridgeChef。
用户输入现有食材,应用生成一份菜谱,并把确认过的结果保存在本机。教程从 Xcode 空项目开始,依次完成模拟器运行、AI 修改、后端接口、本地存储、真机测试和 App Store 发布准备。
- 准备设备和工具
iOS 应用需要一台能运行当前 Xcode 的 Mac。真机测试还需要 iPhone 和 Apple ID;只有模拟器测试时,可以暂时不接手机。
从 Mac App Store 安装 Xcode,第一次启动时等待开发组件安装完成。
如果后面要连接 iPhone,在手机“隐私与安全”里开启开发者模式。菜单位置可能随 iOS 版本变化,以手机当前提示为准。
- 创建并运行空白项目
在 Xcode 欢迎页选择 Create New Project。
模板选择 iOS App,界面使用 SwiftUI,语言使用 Swift。
项目名填写 FridgeChef,Organization Identifier 使用自己的反向域名。需要本地历史记录时,可以选择 SwiftData;如果模板提供的选项不同,也可以稍后再增加。
选择保存位置并创建项目。
先不要改代码。顶部选择一台 iPhone 模拟器,点击 Run。
空白应用能启动,才说明 Xcode、SDK、签名和模拟器已经连通。
空白 SwiftUI 项目运行失败,错误是【粘贴错误】。请只修复环境或签名问题,不增加功能。
- 做出第一版界面
用 Trae 或 Cursor 打开 Xcode 项目目录:
请把当前 SwiftUI 首页改成冰箱大厨。首页显示食材输入框、生成菜谱按钮和历史记录空状态,先使用演示数据。
回到 Xcode 重新运行。第一轮只看输入框、按钮和空状态,不接网络。
如果布局不适合小屏幕:
请让首页在小屏幕和大字体下也能完整滚动,保持现有配色,不增加新功能。
- 增加演示菜谱
请让生成按钮先返回一份固定菜谱,包含名称、食材和步骤。生成中禁用按钮,失败状态也要有重新尝试入口。
验证:
没输入食材时不能提交。
点击后先显示处理中。
完成后显示菜名、食材和步骤。
连续点击不会产生多份重复结果。
返回首页后还能看到刚才的菜谱。
- 接入真实后端
正式应用不能把组织共享 API Key 写进 iOS 客户端。App 安装包可以被分析,写在 Swift 文件、配置文件或 Keychain 中的共享模型密钥都不能算服务器秘密。
正确做法是:iOS App 登录自己的业务后端,后端再调用模型服务。
请把演示菜谱替换为业务后端接口。App 只发送食材并接收结构化菜谱,不保存模型密钥;增加超时、取消和错误提示。
接口返回内容要经过校验。字段缺失或格式不正确时,页面显示可理解的错误,不能直接崩溃。
可以用后端测试地址先验证,但不要把内部地址和 Token 提交到公开仓库。
- 保存历史记录
网络链路稳定以后,再保存用户确认过的菜谱。
在 Xcode 中创建 SwiftData 模型或当前项目使用的本地数据模型。
请把用户确认的菜谱保存到本机,并在首页按时间倒序显示。删除前需要确认,空数据库显示空状态。
按顺序测试:
保存一份菜谱。
关闭应用再打开。
确认历史记录仍然存在。
删除时先取消,记录不能消失。
再次删除并确认,记录才被移除。
- 准备 App 图标
图标应为自己创作或确认有权使用的素材。生成 1024×1024 原图后,拖入 Assets 中对应的 App Icon 资源。
重新运行,确认模拟器桌面和应用切换器里都显示新图标。
- 做一次完整模拟器验收
至少检查:
空输入、正常输入和超长输入;
后端超时、断网和返回格式错误;
生成中取消;
保存、重启、删除;
深色模式;
系统大字体;
小屏幕模拟器。
出错时复制 Xcode 中最相关的一段:
我执行【操作】后出现【现象】。Xcode 错误是【内容】。请只修复这一项,并告诉我怎样复测。
日志里不要写完整菜谱输入、用户 Token、联系方式或服务器密钥。
- 在真机运行
用数据线连接 iPhone,首次连接时在手机上选择信任。
回到 Xcode,在顶部设备列表选择自己的 iPhone,确认 Signing & Capabilities 中选择了正确团队,再点击 Run。
个人 Apple ID 可以用于开发调试,但签名有效期和能力有限。系统要求信任开发者时,根据手机当前提示操作。
真机重点测试键盘、网络切换、后台恢复、深色模式、动态字体和真实触摸区域。
- 发布前准备
准备上架时,需要加入 Apple Developer Program,在 App Store Connect 创建 App 条目,并通过 Xcode 上传归档构建。
账号费用、SDK 要求、隐私清单和审核规则会变化,提交时以 Apple 当前后台和官方文档为准。
发布前至少准备:
稳定的 Bundle ID 和版本号;
App 图标、真实截图和说明;
隐私政策、数据收集说明和账号删除流程;
后端生产环境和故障监控;
Release 真机测试;
图片、字体和内容的授权证明。
- 在自己的 iPhone 上吃完最后一顿“测试餐”
模拟器里的页面都正常以后,把冰箱大厨装到真实 iPhone,再完整走一遍:输入食材、等待菜谱、保存结果、关闭应用后重新打开。顺手切换深色模式和大字体,再断一次网络,看看按钮、提示和历史记录是不是仍然说得清楚。
如果这几步都能完成,你做出的就不再只是一张 SwiftUI 界面。它已经有了前端、后端、本机记录和真机运行这条完整链路。准备上架时,最后守住两件事:模型密钥只能留在后端,商店里的截图、隐私说明和实际功能必须对得上。