ITPub博客

首页 > 移动开发 > IOS > Windows 开发 iOS App 入门,用 SwiftUI 写第一个 iOS App 装到 iPhone

Windows 开发 iOS App 入门,用 SwiftUI 写第一个 iOS App 装到 iPhone

原创 IOS 作者:jdks 时间:2026-10-31 14:19:37 0 删除 编辑

Windows 开发 iOS App 入门,用 SwiftUI 写第一个 iOS App 装到 iPhone

在 Windows 上开发 iOS App,可以用 SwiftUI 从新建工程写起,分三步做出能增删、勾选并保存数据的待办清单,装到 iPhone 断点调试,再用 TestFlight 或 Ad Hoc 发给同事,全程约一小时。

Windows 开发 iOS App 可以直接从一个空的 SwiftUI 工程起步:装好 KXBuild 和 VS Code 插件,新建工程后分三步写出能增删、勾选并保存到文件的待办清单,按 F5 装到 iPhone 上断点调试,再用 TestFlight 或 Ad Hoc 发给同事。不用装黑苹果,也不用租云 Mac,适合第一次写 iOS 应用的人,全程大约一小时。

开始前准备好三样东西。一个 Apple 开发者账号,用来生成证书和描述文件。一部 iPhone 和能传数据的线。一台装好 KXBuild 和 VS Code 插件的电脑,还没装的按安装页操作。

怎么在 Windows 上新建 SwiftUI 工程?

以下两种做法任选其一。

  • VS Code 插件。按 Ctrl+Shift+P 打开命令面板,运行 KXBuild: 新建项目,模板选「iOS 应用(SwiftUI)」,项目名填 MyTodo,Bundle ID 改成你自己的反向域名,例如 com.yourname.mytodo,再选一个存放目录。创建完成后选「在新窗口打开」。
  • 命令行。在 PowerShell 中执行下面的命令,再用 VS Code「文件 → 打开文件夹」打开 D:\projects\MyTodo。
1kxbuild project create -t app_swiftui -n MyTodo -b com.yourname.mytodo -o D:\projects

新建模板

打开后左侧 KXBuild 视图列出 MyTodo 工程和同名的 app target。工程里只有三样东西, MyTodoApp.swift 是 App 入口, ContentView.swift 是首页界面, Assets.xcassets 放图标和颜色。下面的代码全部写在 ContentView.swift 里,省去往工程里添加新文件的步骤。

Bundle ID 是 App 在 Apple 那边的唯一标识,后面生成描述文件、在 App Store Connect 建 App 都要用同一个,现在定好,之后不要再改。

第一步:怎么用 SwiftUI 写出列表界面?

先做一个只能看的列表,数据写死在代码里。把 ContentView.swift 的内容整个换成下面这段。

 1import SwiftUI 2 3struct TodoItem: Identifiable, Codable { 4    var id = UUID() 5    var title: String 6    var done = false 7} 8 9struct ContentView: View {10    @State private var items = [11        TodoItem(title: "买牛奶"),12        TodoItem(title: "给 App 换个图标"),13        TodoItem(title: "把 ipa 发给同事", done: true)14    ]1516    var body: some View {17        NavigationView {18            List(items) { item in19                HStack {20                    Image(systemName: item.done ? "checkmark.circle.fill" : "circle")21                        .foregroundColor(item.done ? .green : .secondary)22                    Text(item.title)23                        .strikethrough(item.done)24                }25            }26            .navigationTitle("待办")27        }28    }29}

TodoItem 是一条待办的数据, Identifiable 让 List 能区分每一行, Codable 留给第三步存文件用。 @State 标记的数组一变,界面就会自动刷新。

写的过程中你会发现,输入 Text(item.title). 之后会弹出 strikethrough、 font、 foregroundColor 这些修饰符, Image(systemName:) 的参数、 List 的各个初始化方法也都能补全,自己写的类型按 F12 可以跳到定义。

写错的地方会画红线,问题面板里有完整的错误信息。第一次打开 Swift 文件时代码提示要启动几秒,补全不出来时在命令面板运行 KXBuild: 重启代码提示,更多情况见[代码提示与索引]。

怎么把 App 装到 iPhone 上运行?

第一次在真机上运行要做两件事,放好证书,连好手机。以后每次只需要按 F5。

放好证书

真机运行需要 Apple Development 证书(.p12)和包含这部手机 UDID 的 Development 描述文件(.mobileprovision)。没有的话可以用 Appuploader 登录开发者账号生成,也可以从 Mac 的钥匙串导出,几种做法见[证书与签名]。手机的 UDID 在连上电脑后运行下面的命令查看,第一列就是。

1kxdevice device list

在工程根目录新建 keychain 文件夹,把两个文件放进去,再新建一个 password.properties,写一行「文件名=密码」。

1development.p12=123456

模板自带的 .gitignore 已经排除了 keychain 目录,证书不会被提交到仓库。

连接手机

用数据线把 iPhone 接到电脑,在 KXBuild 视图的「设备」节点点一下手机,选为当前设备。第一次连接依次完成这几件事,详见[设备准备]。

  • 设备节点提示「点击配置」时点一下,安装 Apple 设备驱动,过程中会请求一次管理员权限。
  • 手机弹出「信任此电脑」时解锁并点信任。
  • 打开手机「设置 → 隐私与安全性 → 开发者模式」,手机会重启一次。这个开关在手机连过电脑之后才出现。
  • 第一次调试某个 iOS 版本会自动下载几个 GB 的符号库,大约十多分钟,只有这一次。

按 F5

按 F5,KXBuild 依次构建、签名、安装、启动 App 并附加调试器,手机上出现写死的三条待办。构建日志在「输出 → KXBuild」,编译错误在问题面板,点一下跳到对应的代码行。

启动失败时通知里会写明卡在哪一步。最常见的是描述文件里没有这部手机的 UDID,把 UDID 加进描述文件、重新下载后替换 keychain 里的旧文件即可。其他提示的处理见[运行与调试]。

第二步:怎么添加、删除和勾选待办?

现在让列表能改。顶部加一个输入框,点一行切换完成状态,左滑删除,右上角的编辑按钮可以批量删。把 ContentView 换成下面的版本, TodoItem 保持不变。

 1struct ContentView: View { 2    @State private var items: [TodoItem] = [] 3    @State private var newTitle = "" 4 5    var body: some View { 6        NavigationView { 7            List { 8                Section { 9                    HStack {10                        TextField("新的待办", text: $newTitle)11                            .onSubmit(add)12                        Button("添加", action: add)13                            .disabled(newTitle.trimmingCharacters(in: .whitespaces).isEmpty)14                    }15                }16                Section {17                    ForEach($items) { $item in18                        Button {19                            item.done.toggle()20                        } label: {21                            HStack {22                                Image(systemName: item.done ? "checkmark.circle.fill" : "circle")23                                    .foregroundColor(item.done ? .green : .secondary)24                                Text(item.title)25                                    .strikethrough(item.done)26                                    .foregroundColor(.primary)27                            }28                        }29                    }30                    .onDelete { offsets in31                        items.remove(atOffsets: offsets)32                    }33                }34            }35            .navigationTitle("待办")36            .toolbar { EditButton() }37        }38    }3940    private func add() {41        let title = newTitle.trimmingCharacters(in: .whitespaces)42        guard !title.isEmpty else { return }43        items.append(TodoItem(title: title))44        newTitle = ""45    }46}

ForEach($items) { $item in … } 拿到的是每一行的绑定, item.done.toggle() 直接改的就是数组里那一项。 onDelete 同时支持左滑删除和编辑模式下的删除。

改完代码要先停止调试(Shift+F5)再按 F5,调试工具栏上的「重启」不会重新编译。

打断点看变量

在 add() 里 items.append(...) 这一行的行号左边点一下,出现红点。回到手机上输入一条待办,点「添加」,App 停住,VS Code 切到调试视图。

debug

左侧「变量」里能看到 title 的值,「调用堆栈」里能看到这次调用是怎么进来的。按 F10 单步执行一行,F5 继续运行。下面的调试控制台可以直接输入 lldb 命令,例如输入 po title 打印当前的标题。代码里的 print 输出显示在「输出 → KXBuild Console」。

第三步:怎么把数据存到文件里?

现在关掉 App 再打开,待办就没了。用 JSON 文件把列表存到 App 的 Documents 目录,每次改动自动保存,启动时读回来。

把数据和读写逻辑放进一个 TodoStore,界面只管显示。在 ContentView.swift 里 TodoItem 的下面加上这个类。

 1final class TodoStore: ObservableObject { 2    @Published var items: [TodoItem] = [] { 3        didSet { save() } 4    } 5 6    private let fileURL = FileManager.default 7        .urls(for: .documentDirectory, in: .userDomainMask)[0] 8        .appendingPathComponent("todos.json") 910    init() {11        if let data = try? Data(contentsOf: fileURL),12           let saved = try? JSONDecoder().decode([TodoItem].self, from: data) {13            items = saved14        }15    }1617    private func save() {18        do {19            let data = try JSONEncoder().encode(items)20            try data.write(to: fileURL, options: .atomic)21        } catch {22            print("保存失败 \(error)")23        }24    }25}

然后改 ContentView 里的四处,把 @State 数组换成这个 store。

1    @StateObject private var store = TodoStore()   // 替换 @State private var items2    // …3    ForEach($store.items) { $item in               // 原来是 ForEach($items)4    // …5    store.items.remove(atOffsets: offsets)         // onDelete 里6    // …7    store.items.append(TodoItem(title: title))     // add() 里

@Published 的数组被修改时会触发 didSet,勾选、删除、添加都会写一次文件。在 init 里给 items 赋值不会触发 didSet,启动读文件时不会反过来又写一遍。

重新按 F5,加几条待办,在手机上把 App 从后台划掉再打开,数据还在。想确认文件确实写了,在 save() 的 let data = … 这行打个断点,勾选一条待办,停住后在调试控制台输入 po fileURL,能看到文件在 App 沙盒里的完整路径。

数据只有几个开关、一两个字符串时,用 @AppStorage("key") 存进 UserDefaults 更省事。待办这种列表数据存成文件更合适,以后想换成 Core Data 或 SwiftData 也好迁移。

App 的名字和图标在哪里改?

手机桌面上 App 的名字默认是 MyTodo。在 KXBuild 视图中右键 target 选「KXBuild: 编辑目标设置」,在 General 页把 Display Name 改成「待办」,Ctrl+S 保存。同一页还能改版本号和最低 iOS 版本,各字段的含义见[工程设置编辑器]。

图标在 KXBuild 视图的资源目录节点里打开 Assets.xcassets,给 AppIcon 放一张 1024×1024 的图,其他尺寸自动生成,见[资源目录编辑器]。改完再按一次 F5 就能在手机上看到。

怎么把 ipa 打包发给别人?

调试用的 Debug 包只能装在描述文件里列出的手机上。要发给别人装,按人数和对方是否在身边选一种方式。

用 TestFlight 发给测试员

对方不在身边、人数较多时用 TestFlight。对方在 iPhone 上装 TestFlight App,收到邀请后直接安装,不需要登记 UDID。

在 keychain 目录放入 Apple Distribution 证书和 App Store 类型的描述文件,同样在 password.properties 里加一行密码。然后以下两种做法任选其一。

  • VS Code 插件。在 KXBuild 视图的「构建配置」节点切到 Release(也可以在命令面板运行 KXBuild: 选择构建配置),再运行 KXBuild: 构建。
  • 命令行。在工程目录执行下面的命令。
1kxbuild build .\MyTodo.xcodeproj -c Release

完成后工程目录下生成 build\MyTodo.ipa。在 App Store Connect 建好这个 App,用 Appuploader 上传 ipa,处理完成后在 TestFlight 页添加测试员,详见[发布与上架]。

用 Ad Hoc 直接装到身边同事的手机

几台固定的测试机可以用 Ad Hoc。在开发者网站登记同事手机的 UDID,生成包含这些设备的 Ad Hoc 描述文件,用 Distribution 证书按上面的步骤构建 Release。如果 keychain 里同时放着 App Store 和 Ad Hoc 两个描述文件,构建时用 -D 指定要用的那个。

1kxbuild build .\MyTodo.xcodeproj -c Release -D CODE_SIGN_STYLE=Manual -D CODE_SIGN_IDENTITY="Apple Distribution" -D PROVISIONING_PROFILE_SPECIFIER="MyTodo AdHoc"

把同事的手机接到你的电脑上,执行下面的命令安装。

1kxdevice install .\build\MyTodo.ipa

到这里,一个 Windows 开发 iOS App 的完整流程就走完了:写 SwiftUI 界面、真机断点调试、本地存数据、打 Release 包分发。之后加新页面、接网络请求,都是在同一个工程里重复「改代码、按 F5」这一步。

常见问题

SwiftUI 代码能在 Windows 上编写和编译吗?

能。SwiftUI 代码在 Windows 上照常编写、补全和编译,KXBuild 把它构建成能装到 iPhone 的 App。本文的待办清单用到的 List、 NavigationView、 @State、 @StateObject 都是 SwiftUI 的标准写法,换到 Mac 上打开同一个工程也能直接编译。

调试时装的包能直接发给别人吗?

不能。Debug 包只能装在 Development 描述文件里登记过 UDID 的手机上,别人的手机装不上。要发给别人,用 Apple Distribution 证书打 Release 包,再走 TestFlight 或 Ad Hoc,证书的准备方法见[Windows 给 iOS App 签名]。

改完代码为什么手机上没变化?

调试工具栏上的「重启」不会重新编译。改完 Swift 代码先按 Shift+F5 停止调试,再按 F5,KXBuild 会重新构建、签名并安装到手机。

待办数据存在手机的什么地方?

存在 App 沙盒的 Documents 目录下的 todos.json。卸载 App 时这个目录会一起删除,数据也就没了;只是从后台划掉 App 不影响数据。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70044672/viewspace-3187279/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2025-06-16

  • 博文量
    188
  • 访问量
    187977