平台说明 - iOS
部署
开发、构建、运行和调试 Qt for iOS 应用程序都可以在 macOS 上通过Qt Creator 完成。工具链由 Apple 的 Xcode 提供,在针对 iOS 的项目上运行 qmake 或 CMake 也会生成一个带有初始应用程序设置的 Xcode 项目文件(.xcodeproj)。由于Qt Creator 没有提供管理 iOS 平台所有特定设置的接口,因此有时需要直接在 Xcode 中进行调整。在将应用程序提交到 Apple App Store 发布之前,检查应用程序配置是否正确尤为重要。
应用程序捆绑
iOS 应用程序通常作为独立的应用程序捆绑包部署。应用程序捆绑包包含应用程序的可执行文件以及依赖项,如 Qt 库、插件、翻译和应用程序可能需要的其他资源。
要使用 CMake 以应用程序捆绑包的形式构建应用程序,请在可执行目标上设置 MACOSX_BUNDLE
属性,如下所示:
qt_add_executable(app) if(APPLE) set_target_properties(tst_manual_ios_assets PROPERTIES MACOSX_BUNDLE TRUE) endif()
在 qmake 中,捆绑是默认设置。请在项目文件 (.pro
) 中设置CONFIG -= app_bundle
以禁用它。
信息属性列表文件
iOS 和 macOS 上的信息属性列表文件 (Info.plist) 用于配置应用程序捆绑包。这些配置设置包括
- 应用程序显示名称和标识符
- 所需的设备功能
- 支持的用户界面方向
- 图标和启动图像
有关详情,请参阅 iOS Developer Library 中的信息属性列表文件文档。
使用 CMake 获取 Info.plist
如果目标的MACOSX_BUNDLE
属性设置为TRUE
,CMake 会生成一个默认的Info.plist
文件。遗憾的是,该文件不适合 iOS 项目。
相反,项目可以使用qt_add_executable,它会自动生成一个带有适合 iOS 项目默认值的Info.plist
文件。
要指定自定义的Info.plist
,项目可以设置MACOSX_BUNDLE_INFO_PLIST
target 属性,如下所示。这样做将禁用qt_add_executable提供的自动生成文件功能,转而使用 CMake 本机处理项目提供的Info.plist
文件。
qt_add_executable(app) if(IOS) set_target_properties(app PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/ios/Info.plist") endif()
请参阅CMake MACOSX_BUNDLE_INFO_PLIST 文档,了解 CMake 执行模板替换时可以指定哪些目标属性和变量。
使用 QMake 获取 Info.plist
运行 qmake 时,会生成一个带有适当默认值的Info.plist
文件。
建议你用自己的副本替换生成的 Info.plist,以防下次运行 qmake 时被覆盖。您可以在 .pro 文件中使用QMAKE_INFO_PLIST变量定义自定义的信息属性列表。
ios { QMAKE_INFO_PLIST = ios/Info.plist }
应用程序资产
对于无法捆绑到 Qt 资源中的文件,QMAKE_BUNDLE_DATAqmake 变量提供了一种方法来指定一组要复制到应用程序捆绑包中的文件。例如
ios { fontFiles.files = $$files(fonts/*.ttf) fontFiles.path = fonts QMAKE_BUNDLE_DATA += fontFiles }
在 CMake 中,同样的方法可以如下实现:
qt_add_executable(app) file(GLOB_RECURSE font_files CONFIGURE_DEPENDS "fonts/*.ttf") if(IOS AND font_files) target_sources(app PRIVATE ${font_files}) set_source_files_properties( ${font_files} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/fonts) endif()
对于图像资源,另一种方法是使用 Xcode 中的资产目录,可以用 qmake 按以下方式添加:
ios { QMAKE_ASSET_CATALOGS += ios/Assets.xcassets }
使用 CMake:
qt_add_executable(app) set(asset_catalog_path "ios/Assets.xcassets") target_sources(app PRIVATE "${asset_catalog_path}") set_source_files_properties( ${asset_catalog_path} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
图标
从 Xcode 13 开始,图标需要添加到资产目录的图标集中,该图标集通常称为AppIcon
。然后,Xcode 将使用正确的键和值更新Info.plist
文件,并将任何必要的图标文件直接复制到应用程序捆绑包中。
从 Xcode 14 开始,只需要一张 1024x1024 像素大小的图片。Xcode 会从中生成所有必要的图标。您也可以在资产目录中手动指定图片。
有关可指定图标的详细列表,请参阅图标文件。
文件名并不重要,重要的是实际像素大小。要支持通用 iOS 应用程序,需要以下图像:
AppIcon60x60@2x.png
:120 x 120(用于 iPhone)AppIcon76x76@2x~ipad.png
:152 x 152(用于 iPad)AppIcon167x167.png
:167x167(适用于 iPad Pro)AppIcon1024x1024.png
:1024 x 1024(适用于 App Store)
特别发行版还应在应用程序捆绑包中包含以下文件名,以便在 iTunes 中显示应用程序:
iTunesArtwork
512x512iTunesArtwork@2x
1024x1024
添加图标的最简单方法是按照 Xcode 的文档创建资产目录和集。
使用 CMake 构建项目时,还应指定以下 Xcode 属性,以确保应用程序图标由 Xcode 生成。
set_target_properties(app_target_name PROPERTIES XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon)
下面是 Xcode 14 的Assets.xcassets/AppIcon.appiconset/Contents.json
文件的示例:
{ "images" : [ { "idiom" : "universal", "platform" : "ios", "scale" : "2x", "size" : "20x20" }, { "idiom" : "universal", "platform" : "ios", "scale" : "3x", "size" : "20x20" }, { "idiom" : "universal", "platform" : "ios", "scale" : "2x", "size" : "29x29" }, { "idiom" : "universal", "platform" : "ios", "scale" : "3x", "size" : "29x29" }, { "idiom" : "universal", "platform" : "ios", "scale" : "2x", "size" : "38x38" }, { "idiom" : "universal", "platform" : "ios", "scale" : "3x", "size" : "38x38" }, { "idiom" : "universal", "platform" : "ios", "scale" : "2x", "size" : "40x40" }, { "idiom" : "universal", "platform" : "ios", "scale" : "3x", "size" : "40x40" }, { "idiom" : "universal", "platform" : "ios", "scale" : "2x", "size" : "60x60" }, { "idiom" : "universal", "platform" : "ios", "scale" : "3x", "size" : "60x60" }, { "idiom" : "universal", "platform" : "ios", "scale" : "2x", "size" : "64x64" }, { "idiom" : "universal", "platform" : "ios", "scale" : "3x", "size" : "64x64" }, { "idiom" : "universal", "platform" : "ios", "scale" : "2x", "size" : "68x68" }, { "idiom" : "universal", "platform" : "ios", "scale" : "2x", "size" : "76x76" }, { "idiom" : "universal", "platform" : "ios", "scale" : "2x", "size" : "83.5x83.5" }, { "filename" : "AppIcon1024x1024.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" } ], "info" : { "author" : "xcode", "version" : 1 } }
启动屏幕和启动图像
启动屏幕
每个 iOS 应用程序都必须提供一个启动屏幕,以便在应用程序启动时显示。启动屏幕是一个界面生成器.xib
文件,也称为故事板文件。有关详细信息,请参阅指定应用程序的启动屏幕。
iOS 9.0 引入了对启动屏幕的支持。
qmake 和 CMake 都会生成一个名为LaunchScreen.storyboard
的默认启动屏幕。
要指定自定义启动屏幕,必须将其复制到应用程序捆绑包中,并将UILaunchStoryboardName
关键字设置为Info.plist
文件中的启动屏幕名称。
自 Qt 6.4 起,Qt 通过 CMake 支持自定义启动画面,自 Qt 6.0 起,Qt 通过 qmake 支持自定义启动画面。
假定启动文件名为Launch.storyboard
,则可按如下方法将其添加到Info.plist
:
<key>UILaunchStoryboardName</key> <string>Launch</string>
要使用 qmake 将启动画面复制到应用程序捆绑包中,请在项目 .pro 文件中使用以下代码段:
ios { QMAKE_IOS_LAUNCH_SCREEN = $$PWD/Launch.storyboard }
使用 CMake:
qt_add_executable(app) if(IOS) set_target_properties(app PROPERTIES QT_IOS_LAUNCH_SCREEN "${CMAKE_CURRENT_SOURCE_DIR}/Launch.storyboard") endif()
启动图像
还可以指定启动图像(PNG 文件)来代替启动屏幕。
注意: 不建议使用启动图像,因为自 iOS 13.0 起已不再支持启动图像。请考虑改用启动屏幕。
启动图像必须复制到应用程序捆绑包中,其名称必须使用UILaunchImages
键在Info.plist
文件中设置。
必须准备以下图像:
- LaunchImage-iOS7-568h@2x.png:640 x 1136
- LaunchImage-iOS7-Landscape.png:1024 x 768
- LaunchImage-iOS7-Landscape@2x.png:2048 x 1536
- LaunchImage-iOS7-Portrait.png:768 x 1024
- LaunchImage-iOS7-Portrait@2x.png:1536 x 2048
- LaunchImage-iOS7@2x.png:640 x 960
图像可按如下方式添加到Info.plist
:
<key>UILaunchImages</key> <array> <dict> <key>UILaunchImageMinimumOSVersion</key> <string>7.0</string> <key>UILaunchImageName</key> <string>LaunchImage-iOS7</string> <key>UILaunchImageOrientation</key> <string>Portrait</string> <key>UILaunchImageSize</key> <string>{320, 568}</string> </dict> <dict> <key>UILaunchImageMinimumOSVersion</key> <string>7.0</string> <key>UILaunchImageName</key> <string>LaunchImage-iOS7</string> <key>UILaunchImageOrientation</key> <string>Portrait</string> <key>UILaunchImageSize</key> <string>{320, 480}</string> </dict> </array> <key>UILaunchImages~ipad</key> <array> <dict> <key>UILaunchImageMinimumOSVersion</key> <string>7.0</string> <key>UILaunchImageName</key> <string>LaunchImage-iOS7-Landscape</string> <key>UILaunchImageOrientation</key> <string>Landscape</string> <key>UILaunchImageSize</key> <string>{768, 1024}</string> </dict> <dict> <key>UILaunchImageMinimumOSVersion</key> <string>7.0</string> <key>UILaunchImageName</key> <string>LaunchImage-iOS7-Portrait</string> <key>UILaunchImageOrientation</key> <string>Portrait</string> <key>UILaunchImageSize</key> <string>{768, 1024}</string> </dict> <dict> <key>UILaunchImageMinimumOSVersion</key> <string>7.0</string> <key>UILaunchImageName</key> <string>LaunchImage-iOS7</string> <key>UILaunchImageOrientation</key> <string>Portrait</string> <key>UILaunchImageSize</key> <string>{320, 568}</string> </dict> <dict> <key>UILaunchImageMinimumOSVersion</key> <string>7.0</string> <key>UILaunchImageName</key> <string>LaunchImage-iOS7</string> <key>UILaunchImageOrientation</key> <string>Portrait</string> <key>UILaunchImageSize</key> <string>{320, 480}</string> </dict> </array>
要使用 qmake 将启动图像复制到应用程序捆绑包中,请在项目 .pro 文件中使用以下代码片段:
ios { app_launch_images.files = $$files($$PWD/ios/LaunchImage*.png) QMAKE_BUNDLE_DATA += app_launch_images }
使用 CMake:
qt_add_executable(app) file(GLOB_RECURSE launch_images CONFIGURE_DEPENDS "ios/LaunchImage*.png") if(IOS AND launch_images) target_sources(app PRIVATE ${launch_images}) set_source_files_properties( ${launch_images} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) endif()
注: 早期的 iOS 版本支持在Info.plist
中使用UILaunchImageFile
键指定单个启动映像,但自 iOS 10.0 起已不再支持该功能。
原生图片选择器
如果你的Info.plist
文件包含NSPhotoLibraryUsageDescription
的条目,qmake 会自动包含一个额外的插件,用于访问原生图片拾取器。
对于 CMake,请使用qt_import_plugins 手动链接原生图像拾取器:
qt_import_plugins(app INCLUDE Qt6::QIosOptionalPlugin_NSPhotoLibraryPlugin)
如果QFileDialog 中的目录设置为:
QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last();
或者将currentFolder 设为 QML 中的FileDialog :
shortcuts.pictures
然后显示本地图片选择器,以便访问用户的相册。
表达支持的 iOS 版本
苹果平台有一种表达应用程序支持的操作系统版本的内置方法,它允许旧版本的平台自动显示用户友好的错误信息,提示用户更新操作系统,而不是崩溃并显示堆栈跟踪。
表达对特定范围操作系统版本的支持所涉及的主要概念如下:
- 部署目标指定应用程序支持的 macOS 或 iOS硬性最低版本。
- SDK 版本指定应用程序支持的 macOS 或 iOS 的软性最高版本。
为 Apple 平台开发应用程序时,应始终使用开发时可用的最新版本 Xcode 和最新 SDK。在某些平台(如 iOS)上,如果不使用最新版本,实际上会被 App Store 拒绝。因此,SDK 版本应始终大于或等于部署目标。
为 Apple 平台开发应用程序时,必须设置部署目标。Xcode 工具链中的各种构建工具(包括但不限于编译器和链接器)都有一个标志,您可以用它来设置该值。通过设置部署目标值,您明确声明您的应用程序必须至少在该版本上运行,而不能在任何早期版本的操作系统上运行。然后,您就必须确保对系统 API 的使用与您所声明的一致。由于编译器知道你声明了什么,因此它可以帮助你执行声明。
SDK 版本被认为是与应用程序兼容的操作系统的最大软版本,如果应用程序是使用 SDK 构建的,那么即使在较新的操作系统版本上,它也会继续使用该 SDK 的行为,因为操作系统会检查二进制文件的加载命令,并模拟与旧版操作系统的向后兼容性。例如,如果一个应用程序是使用 macOS 10.12 SDK 构建的,那么即使在 10.13 及以上版本上,它也将继续使用 10.12 版本的行为。
不过,Mach-O 二进制文件本质上是向前兼容的。例如,使用 iOS 9 SDK 构建的应用程序可以在 iOS 10 上正常运行,但可能无法选择新版本中对某些功能所做的行为更改,直到该应用程序根据更新的 SDK 重新编译。
最低操作系统版本可以通过编译器和链接器标志向系统表达,并将其嵌入到 Mach-O 二进制文件中。此外,必须在应用程序的应用程序捆绑包中设置LSMinimumSystemVersion
密钥。该值必须等于传递给编译器和链接器的值,因为在 macOS 上,该值将允许操作系统显示用户友好的错误对话框,提示应用程序需要更新版本的操作系统,而不是崩溃对话框。LSMinimumSystemVersion
也是 App Store 用来显示所需操作系统版本的键值;编译器和链接器标志在这里没有任何作用。
在大多数情况下,Qt 应用程序都能顺利运行。例如,在 qmake 中,Qt mkspecs 会将QMAKE_IOS_DEPLOYMENT_TARGET或QMAKE_MACOSX_DEPLOYMENT_TARGET设置为 Qt 本身支持的最低版本。同样,在 Qbs 中,Qt 模块会将cpp.minimumIosVersion
,cpp.minimumMacosVersion
,cpp.minimumTvosVersion
或cpp.minimumWatchosVersion
设置为 Qt 本身支持的最小版本。
不过,在手动设置自己的目标版本时必须小心。如果您将其设置为高于 Qt 要求的值,并提供自己的Info.plist
文件,则必须在Info.plist
中添加一个与部署目标值相匹配的LSMinimumSystemVersion
条目,因为操作系统会将LSMinimumSystemVersion
值作为权威值。
如果指定的部署目标值低于 Qt 要求的值,当在比 Qt 支持的版本更老的版本上运行时,应用程序几乎肯定会在 Qt 库的某个地方崩溃。因此,请确保实际的构建系统代码反映了实际需要的最低操作系统版本。
发布到苹果应用程序商店
验证 Qt for iOS 应用程序是否已准备好发布到 App Store,可按照 "提交应用程序"中的说明进行。要提交应用程序,您可以使用 Xcode 或 Application Loader(随 Xcode 安装)。Qt Creator 不提供管理 Xcode 项目配置中所有设置的接口。
应在目标支持的 iOS 版本和设备上测试应用程序。Qt 应用程序的最低部署目标因 Qt 版本而异。有关详细信息,请参阅支持的配置。
实际发布过程包括创建发布证书和供应配置文件,创建应用程序的签名存档,并对其运行一系列验证测试。
更多信息,请参阅 iOS Developer Library 中的《应用程序发布指南》。
符号可见性警告
在链接 C++ 库时,函数和对象被称为符号。符号的可见性可以是default
或hidden
。
出于性能考虑,Qt XML 和许多其他库默认使用hidden
可见性编译其源代码,只有当要在用户项目中使用符号时,才将其标记为default
可见性。
遗憾的是,当一个库使用hidden
可见性编译,而用户项目应用程序或库使用default
可见性编译时,苹果链接器会发出警告。
如果项目开发人员想消除警告,就需要在编译项目代码时也使用hidden
可见性。
在 CMake 中,只需在CMakeLists.txt
中添加以下代码即可:
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
在 qmake 中,可在.pro
文件中添加以下代码:
CONFIG+=hide_symbols
如果项目构建了库,那么库中任何要在其他库或应用程序中使用的符号都必须明确标记为default
可见性。例如,可以用Q_DECL_EXPORT 来注释这些函数或类。
CMake 的产品归档问题
由于CMake 中的一个问题,尝试使用 iOS 应用程序创建产品存档可能会失败。
无论是在 Xcode 中使用 Product -> Archive 菜单项创建存档,还是在命令行中使用xcodebuild -archivePath
.
错误信息可能涉及未定义的符号或不存在的文件路径。
要解决这个问题,请确保在尝试创建存档之前构建Release
版本的项目。
CMake Xcode 项目创建的 xcarchive 中缺少 dSYM 包
由于 Xcode 中的一个错误和某些CMake 限制,在 Xcode 的归档任务中,CMake 生成的 Xcode 项目将无法将应用程序的dSYM
bundle 包含到xcarchive
中。
Qt XML 提供了一种作为选择项的变通方法,这样dSYM
捆绑程序就会包含在xcarchive
中,但它也是有取舍的。也就是说,以下 CMake 功能将无法正常工作:
- 任何
$<TARGET_FILE:app>
生成器表达式都可能扩展为无效路径,无法指向应用程序二进制文件 - 即使设置了
CMAKE_RUNTIME_OUTPUT_DIRECTORY
变量及其相关的RUNTIME_OUTPUT_DIRECTORY
target 属性,也会被忽略 - 其他未知问题
为减少上述问题,您可以
- 仅在打算创建
xcarchive
时启用变通方法,而不是在项目开发过程中启用 - 确保只在项目根目录中添加可执行文件和库,而不是在
add_subdirectory
调用中。
要启用变通方法,请使用以下选项配置项目:
cmake . -DQT_USE_RISKY_DSYM_ARCHIVING_WORKAROUND=ON
或在调用qt_add_executable
或qt_add_library
之前在项目中设置该变量:
set(QT_USE_RISKY_DSYM_ARCHIVING_WORKAROUND ON) ... qt_add_executable(app)
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.