ITPub博客

首页 > 移动开发 > IOS > Swift Package 转 iOS App,Windows 使用 KXBuild 装到 iPhone 并打包 ipa

Swift Package 转 iOS App,Windows 使用 KXBuild 装到 iPhone 并打包 ipa

原创 IOS 作者:iOS调试笔记 时间:2026-11-02 15:45:01 0 删除 编辑

Swift Package 或 Swift Playgrounds 写的 App 本身装不进 iPhone,也打不出 ipa。本文在 Windows 上把它转成 iOS App 工程,设置 Bundle ID、图标和权限说明后真机调试,继续加依赖,最后打包上架。

Swift Package 转 iOS App 只要一步:在 Windows 上用 VS Code 插件或 kxbuild project spm2app,把可执行 target 是 App 的包生成一个 iOS App 工程,然后装到 iPhone 断点调试、打包 ipa 上架。包本身能编译,却装不进手机、也打不出 ipa,在 Mac 上也一样,所以要先转换。转换只做一次,App 工程直接编译包里的源码,之后照常改包里的代码,App 跟着一起变。

开始前准备好一部 iPhone 和数据线、Apple 开发者账号下的证书,以及装好 KXBuild 和 VS Code 插件的电脑,还没装的按[安装页]操作。

哪些 Swift Package 能转成 iOS App?

能转的是可执行 target 本身就是 App 的包,也就是可执行 target 里有 @main struct …: App 这样的 SwiftUI 入口,或者 UIKit 的 UIApplicationDelegate。其他几种情况这样处理。

  • 只提供库的包。它是给 App 用的,不转换。在 App 工程里[添加 Swift Package 依赖]即可。
  • 命令行程序。可执行 target 里没有 App 入口,iOS 上跑不了命令行程序,也不转换。
  • Swift Playgrounds 的 App 项目。目前不能直接转换,先整理成普通的包,做法见[后文]。

下面用一个最小的包演示,目录是 D:\projects\Hello。 Hello 是 App, HelloCore 是 App 用到的一个库 target。

1Hello\2├─ Package.swift3└─ Sources\4   ├─ Hello\5   │  └─ HelloApp.swift6   └─ HelloCore\7      └─ Greeting.swift
 1// swift-tools-version:5.9 2import PackageDescription 3 4let package = Package( 5    name: "Hello", 6    platforms: [.iOS(.v16)], 7    products: [ 8        .executable(name: "Hello", targets: ["Hello"]) 9    ],10    targets: [11        .executableTarget(name: "Hello", dependencies: ["HelloCore"]),12        .target(name: "HelloCore")13    ]14)
 1import SwiftUI 2import HelloCore 3 4@main 5struct HelloApp: App { 6    var body: some Scene { 7        WindowGroup { 8            Text(Greeting.text) 9        }10    }11}

在 VS Code 中「文件 → 打开文件夹」打开 Package.swift 所在目录。打开 .swift 文件就有补全和错误提示,SwiftUI、UIKit 的 API 按 iOS 补全。转换前可以先在包目录编译检查一次。

1kxbuild build .

怎么把 Swift Package 转为 App 工程?

以下两种做法任选其一。

  • VS Code 插件。命令面板运行 KXBuild: 将 Swift Package 转为 App 工程,或者点 KXBuild 视图里标着「点击生成 App 工程」的那一行。按提示填 App 名和 Bundle ID,App 名留空就用可执行 target 的名字。完成后新工程自动设为启动项目。
  • 命令行。在 Package.swift 所在目录执行下面的命令。之后在 KXBuild 视图中点一下 Hello 工程节点,把它设为[启动项目]。
1kxbuild project spm2app . -n Hello -b com.yourname.hello

Bundle ID 换成你自己的反向域名,后面生成描述文件、在 App Store Connect 建 App 都用它。转换完成后包目录下多了一个和 App 同名的子目录,里面就是 App 工程。

 1Hello\ 2├─ Package.swift 3├─ Sources\ 4│  ├─ Hello\ 5│  └─ HelloCore\ 6└─ Hello\ 7   ├─ .gitignore 8   ├─ Hello.xcodeproj 9   └─ Hello\10      └─ Assets.xcassets

App 工程里没有复制源码,它直接编译 Sources\Hello 目录,包里的其他 target 按本地包引用。所以改包里的代码就是改 App,这个子目录要和包一起提交到版本库。子目录里自带的 .gitignore 已经排除了构建产物和证书目录。

示例里 App 用到了 HelloCore,而包里没有暴露它的库产品,App 工程引用不到。这时转换会在 Package.swift 的 products 里补一行,插件会弹出提示,命令行输出的 manifestChanges 里也会列出来。 转换完成后检查并提交 Package.swift 的这处改动。

1    products: [2        .executable(name: "Hello", targets: ["Hello"]),3        .library(4            name: "HelloCore",5            targets: [ "HelloCore" ]6        ),7    ],

手边还没有证书时,可以先不签名编译一次,确认工程没问题。

1kxbuild build .\Hello\Hello.xcodeproj -D CODE_SIGNING_ALLOWED=NO

包里有多个 App

命令行用 --executable 指定要转的那个,每个 App 各转一次,工程分别建在各自的子目录里。

1kxbuild project spm2app . -n HelloPro -b com.yourname.hellopro --executable HelloPro

提示 choose another place with -o

可执行 target 的源码目录就是包根目录(Package.swift 里写了 path: "."),工程建在包里会被当成 App 源码一起编译。用 -o 把工程放到包目录外,例如 -o ..。

Swift Playgrounds 的 App 项目怎么转?

Swift Playgrounds 建的 App 项目是一个 .swiftpm 目录,Package.swift 里有 import AppleProductTypes,用 .iOSApplication 描述 App。这种包目前不能直接转换,运行转换会提示暂不支持。做法是另建一个普通的包,把源码复制过去再转换,原来的 .swiftpm 不动,在 iPad 上照常打开。

下面以 D:\projects\PGApp.swiftpm 为例。先把其中的 .swift 文件连同子文件夹复制到新包的 Sources\PGApp 目录,Package.swift 除外。

1robocopy D:\projects\PGApp.swiftpm D:\projects\PGApp\Sources\PGApp *.swift /S /XF Package.swift

再在 D:\projects\PGApp 下新建 Package.swift,写入下面的内容,最低 iOS 版本照原项目的 platforms 填。

 1// swift-tools-version: 5.9 2import PackageDescription 3 4let package = Package( 5    name: "PGApp", 6    platforms: [.iOS(.v16)], 7    targets: [ 8        .executableTarget(name: "PGApp") 9    ]10)

然后按上一节转换。原项目 .iOSApplication 里写的 Bundle ID 用 -b 带上,版本号、显示名称、图标在下一节的编辑器里改。原项目有 Assets.xcassets 的,把里面的图片集和颜色集复制到新 App 工程的 Assets.xcassets 中。

1cd D:\projects\PGApp2kxbuild project spm2app . -b com.yourname.pgapp

怎么改 App 名称、图标和权限说明?

名称与版本号

在 KXBuild 视图中右键 Hello target 选「KXBuild: 编辑目标设置」,General 页可以改 Display Name、Bundle Identifier、版本号和最低 iOS 版本,Ctrl+S 保存。各字段见[工程设置编辑器]。

工程编辑器

图标

图标在 App 工程的 Hello\Hello\Assets.xcassets 里。在 KXBuild 视图中点工程节点下的资源目录打开它,把 AppIcon 的占位图换成一张 1024×1024 的 PNG,见[资源目录编辑器]。

权限说明

转换出的工程没有 Info.plist 文件,构建时自动生成。用到相机、相册、定位这类权限时,把说明文字写成 INFOPLIST_KEY_ 开头的构建设置,构建后会出现在 App 的 Info.plist 里。以相机为例,以下两种做法任选其一。

  • VS Code 插件。在工程设置编辑器切到 Build Settings 页,在值单元格上右键选「添加用户自定义设置」,名称填 INFOPLIST_KEY_NSCameraUsageDescription,值填给用户看的说明,Ctrl+S 保存。
  • 命令行。在包目录执行下面的命令。
1kxbuild project add-setting -k INFOPLIST_KEY_NSCameraUsageDescription -v "用于扫描二维码" -t Hello -P .\Hello\Hello.xcodeproj

怎么装到 iPhone 上调试?

真机运行需要 Apple Development 证书(.p12)和包含这部手机 UDID 的 Development 描述文件。在 App 工程目录 Hello\Hello 下新建 keychain 文件夹,把两个文件放进去,再新建 password.properties,写一行「文件名=密码」。想让所有工程共用的,放到 KXBuild 安装目录下的 keychain 文件夹。证书的获取方式见 [Windows 给 iOS App 签名]。

1development.p12=123456

用数据线接上 iPhone,在 KXBuild 视图的「设备」节点选中它。第一次连接要安装设备驱动、在手机上点信任并打开开发者模式,见[设备准备]。

确认启动项目是 Hello,在 Sources\Hello 的代码里打断点,按 F5。KXBuild 构建、签名、安装、启动 App 并停在断点上, HelloCore 这类库 target 里的代码同样能断点。改完代码先 Shift+F5 停止再按 F5。变量查看、调试控制台和崩溃定位见 [在 Windows 上真机调试 iOS App]。

转换后怎么改代码和加依赖?

转换只做一次,之后照常在包里开发。按改动的类型处理。

  • 改代码、在 Sources\Hello 里新建或删除 .swift 文件。直接构建或按 F5,App 工程跟着这个目录走,不用做别的。
  • 改包里库 target 的代码。同样直接构建。
  • 给 App 的可执行 target 新增依赖。Package.swift 里改完之后,App 工程也要加上同一个依赖,否则构建报 no such module。

新增的依赖是包里的另一个 target 时,先在 Package.swift 的 products 里给它加一个库产品,例如 .library(name: "HelloExtra", targets: ["HelloExtra"])。然后以下两种做法任选其一。

  • VS Code 插件。命令面板运行 KXBuild: 添加 Swift Package 依赖…,选择包目录 D:\projects\Hello 作为本地包,产品选 HelloExtra。
  • 命令行。在包目录执行下面的命令。
1kxbuild project add-package -P .\Hello\Hello.xcodeproj --path . --product HelloExtra

新增的依赖是远程包时,App 工程加同一个包和产品,版本规则和 Package.swift 里写的保持一致。以下两种做法任选其一。

  • VS Code 插件。命令面板运行 KXBuild: 添加 Swift Package 依赖…,输入包的 Git 地址,选版本规则和产品。
  • 命令行。在包目录执行下面的命令,以 Alamofire 为例。
1kxbuild project add-package -P .\Hello\Hello.xcodeproj --url https://github.com/Alamofire/Alamofire.git --from 5.9.0 --product Alamofire

怎么打包 Swift Package ipa 上架?

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

  • VS Code 插件。在 KXBuild 视图的「构建配置」节点切到 Release,命令面板运行 KXBuild: 构建。
  • 命令行。在包目录执行下面的命令。
1kxbuild build .\Hello\Hello.xcodeproj -c Release

完成后生成 Hello\build\Hello.ipa,Swift Package 转 iOS App 到上架的准备就齐了。在 App Store Connect 建 App、上传 ipa、填写资料和提交审核的完整流程见[在 Windows 上上架 App Store]。

常见问题

提示 only provides libraries 怎么办?

这种包不用转换,把它作为本地包加到 App 工程里即可。它只有库产品、没有 App,先新建一个 App 工程再添加,见 [Swift 技术栈]。

提示 has no app to convert 是什么原因?

原因是可执行 target 里找不到 App 入口,它是命令行程序。确认入口文件里有 @main 标记的 App 结构体,或者 UIApplicationDelegate。

转换输出里的 warnings 要处理吗?

要处理,可执行 target 在 Package.swift 里写的几样设置不会带到 App 工程,输出里会逐条列出。

  • resources。资源会拷进 App,但 App 里没有 Bundle.module,读取资源的代码改用 Bundle.main。
  • swiftSettings、linkerSettings 等编译设置。在工程设置编辑器的 Build Settings 页里重新设置。
  • 构建插件。不会在 App 工程里运行。

链接报 …vpfi 未定义怎么解决?

设置环境变量 KXBUILD_SWIFT_WHOLE_MODULE=all 改为整模块编译,重开 VS Code 后再构建即可。Debug 构建在链接阶段报 undefined symbol: …vpfi,是开源 Swift 编译器的已知问题: @State private var count = 0 这类带初始值的属性,所在结构体的 init 写在另一个文件里就会出现。App 的代码在包里,属于本地包,默认按文件编译,所以会碰到。

1setx KXBUILD_SWIFT_WHOLE_MODULE all

能不能重新转换一次?

可以加 --force 在原目录重新生成,但整个 App 工程会重建,之前在工程设置里改过的内容和换过的图标都会还原。只是加了依赖的,按[上文]添加即可,不必重新转换。

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

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

注册时间:2025-06-17

  • 博文量
    176
  • 访问量
    187854