summaryrefslogtreecommitdiffstats
path: root/tests/manual
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2022-08-08 18:33:36 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2022-08-17 01:05:45 +0200
commitcf3535fdf2e7fe52b36aaa4b94a53525fd6640f4 (patch)
tree0f3d96b7e066dea92f526d7950987453cd76bc50 /tests/manual
parent753c352af0e1316767e24bfb960fe2a596c1489c (diff)
CMake: Add manual test for various iOS asset handling
Includes: - setting a custom Info.plist - Bundling non-image assets - Bundling image assets using asset catalogs - Bundling app icons - Bundling a launch screen Projects added for both qmake and CMake. The executable uses testlib to check that non-image assets, icons and asset catalogs were successfully bundled upon deployment to a device. Task-number: QTBUG-104519 Change-Id: Iaab6112e31e1098dcd2548e18b58bed5b64e6f83 Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'tests/manual')
-rw-r--r--tests/manual/ios_assets/Assets.xcassets/AppIcon.appiconset/Contents.json98
-rw-r--r--tests/manual/ios_assets/Assets.xcassets/Contents.json6
-rw-r--r--tests/manual/ios_assets/Assets.xcassets/Face.imageset/Contents.json23
-rw-r--r--tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-16.pngbin0 -> 173 bytes
-rw-r--r--tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-32.pngbin0 -> 407 bytes
-rw-r--r--tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-48.pngbin0 -> 750 bytes
-rw-r--r--tests/manual/ios_assets/CMakeLists.txt92
-rw-r--r--tests/manual/ios_assets/CustomLaunchScreen.storyboard48
-rw-r--r--tests/manual/ios_assets/Info.ios.cmake.plist93
-rw-r--r--tests/manual/ios_assets/Info.ios.qmake.plist78
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon29x29.pngbin0 -> 340 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon29x29@2x.pngbin0 -> 992 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon29x29@2x~ipad.pngbin0 -> 992 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon29x29~ipad.pngbin0 -> 340 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon40x40@2x.pngbin0 -> 1444 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon40x40@2x~ipad.pngbin0 -> 1444 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon40x40~ipad.pngbin0 -> 585 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon50x50@2x~ipad.pngbin0 -> 1913 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon50x50~ipad.pngbin0 -> 794 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon57x57.pngbin0 -> 967 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon57x57@2x.pngbin0 -> 2200 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon60x60@2x.pngbin0 -> 2335 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon72x72@2x~ipad.pngbin0 -> 2897 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon72x72~ipad.pngbin0 -> 1301 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon76x76@2x~ipad.pngbin0 -> 3060 bytes
-rw-r--r--tests/manual/ios_assets/appicon/AppIcon76x76~ipad.pngbin0 -> 1386 bytes
-rw-r--r--tests/manual/ios_assets/foo.txt1
-rw-r--r--tests/manual/ios_assets/ios_assets.pro48
-rw-r--r--tests/manual/ios_assets/main.cpp70
-rw-r--r--tests/manual/ios_assets/utils.mm18
30 files changed, 575 insertions, 0 deletions
diff --git a/tests/manual/ios_assets/Assets.xcassets/AppIcon.appiconset/Contents.json b/tests/manual/ios_assets/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..9221b9bb1a
--- /dev/null
+++ b/tests/manual/ios_assets/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,98 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "60x60"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "60x60"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "76x76"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "76x76"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "83.5x83.5"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "scale" : "1x",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/tests/manual/ios_assets/Assets.xcassets/Contents.json b/tests/manual/ios_assets/Assets.xcassets/Contents.json
new file mode 100644
index 0000000000..73c00596a7
--- /dev/null
+++ b/tests/manual/ios_assets/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Contents.json b/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Contents.json
new file mode 100644
index 0000000000..2108ce2651
--- /dev/null
+++ b/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "Face-16.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Face-32.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Face-48.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-16.png b/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-16.png
new file mode 100644
index 0000000000..670beb4fbb
--- /dev/null
+++ b/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-16.png
Binary files differ
diff --git a/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-32.png b/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-32.png
new file mode 100644
index 0000000000..ee159b6061
--- /dev/null
+++ b/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-32.png
Binary files differ
diff --git a/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-48.png b/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-48.png
new file mode 100644
index 0000000000..f0783cd533
--- /dev/null
+++ b/tests/manual/ios_assets/Assets.xcassets/Face.imageset/Face-48.png
Binary files differ
diff --git a/tests/manual/ios_assets/CMakeLists.txt b/tests/manual/ios_assets/CMakeLists.txt
new file mode 100644
index 0000000000..911e5a0b2c
--- /dev/null
+++ b/tests/manual/ios_assets/CMakeLists.txt
@@ -0,0 +1,92 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(ios_assets LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Test)
+
+qt_add_executable(tst_manual_ios_assets
+ main.cpp
+)
+
+set_target_properties(tst_manual_ios_assets PROPERTIES
+ MACOSX_BUNDLE TRUE
+)
+target_link_libraries(tst_manual_ios_assets PRIVATE
+ Qt::Core
+ Qt::Gui
+ Qt::Test
+)
+
+# Custom Info.plist
+set_target_properties(tst_manual_ios_assets
+ PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.ios.cmake.plist")
+
+# Custom resources
+file(GLOB_RECURSE text_files CONFIGURE_DEPENDS "*.txt")
+if(text_files)
+ target_sources(tst_manual_ios_assets PRIVATE ${text_files})
+ # On iOS the 'Resources' prefix is removed by Xcode because on iOS app bundles are shallow,
+ # so the final location of the text file will be
+ # tst_manual_ios_assets.app/textFiles/foo.txt
+ # On macOS the location will be
+ # tst_manual_ios_assets.app/Contents/Resources/textFiles/foo.txt
+ set_source_files_properties(
+ ${text_files}
+ PROPERTIES MACOSX_PACKAGE_LOCATION Resources/textFiles)
+endif()
+
+# App icons
+file(GLOB_RECURSE app_icons CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/appicon/AppIcon*.png")
+if(IOS AND app_icons)
+ target_sources(tst_manual_ios_assets PRIVATE ${app_icons})
+ set_source_files_properties(
+ ${app_icons}
+ PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
+endif()
+
+# Asset catalog with images
+if(IOS)
+ enable_language(OBJCXX)
+ set(asset_catalog_path "${CMAKE_CURRENT_SOURCE_DIR}/Assets.xcassets")
+ target_sources(tst_manual_ios_assets PRIVATE "${asset_catalog_path}")
+ set_source_files_properties(
+ ${asset_catalog_path}
+ PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
+ target_sources(tst_manual_ios_assets PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/utils.mm")
+endif()
+
+# Set custom launch screen.
+# iOS has evolved and provides a few ways to handle this.
+# - UILaunchImageFile Info.plist key, introduced in iOS 3.2, supposedly deprecated in iOS 10.
+# - UILaunchImages, Info.plist keys, introduced in iOS 7, deprecated in iOS 13
+# - UILaunchStoryboardName, Info.plist key, introduced in iOS 9, not deprecated
+# - UILaunchScreen / UILaunchScreens, Info.plist dictionaries, introduced in iOS 14, not
+# deprecated
+# The first two expect images, the third one expects a storyboard / .xib file.
+# The last ones expect a dictionary of keys to configure the launch screen.
+# At the moment, UILaunchStoryboardName represents the lower bound of what Qt supports,
+# so use it here.
+# Reference info
+# https://developer.apple.com/documentation/xcode/specifying-your-apps-launch-screen/
+# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW24
+# https://developer.apple.com/documentation/uikit/uilocalnotification/1616660-alertlaunchimage?language=objc
+# https://developer.apple.com/documentation/bundleresources/information_property_list/uilaunchimages?language=objc
+# https://developer.apple.com/documentation/bundleresources/information_property_list/uilaunchstoryboardname?language=objc
+# https://developer.apple.com/documentation/bundleresources/information_property_list/uilaunchscreen?language=objc
+# https://forum.qt.io/topic/106251/use-launch-images-in-ios-project/4
+# https://codereview.qt-project.org/c/qt/qtdoc/+/100846
+if(IOS)
+ # Because we're not using the automatically generated Info.plist, it needs to be manually
+ # modified to have the UILaunchStoryboardName key.
+ set_target_properties(tst_manual_ios_assets PROPERTIES
+ QT_IOS_LAUNCH_SCREEN "${CMAKE_CURRENT_SOURCE_DIR}/CustomLaunchScreen.storyboard")
+endif()
+
+# Flip to TRUE to debug
+if(FALSE)
+ target_compile_definitions(tst_manual_ios_assets PRIVATE DEBUG_APP_DATA_LOCATION=1)
+endif()
diff --git a/tests/manual/ios_assets/CustomLaunchScreen.storyboard b/tests/manual/ios_assets/CustomLaunchScreen.storyboard
new file mode 100644
index 0000000000..889aa39d73
--- /dev/null
+++ b/tests/manual/ios_assets/CustomLaunchScreen.storyboard
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
+ <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="obG-Y5-kRd">
+ <rect key="frame" x="0.0" y="626.5" width="375" height="20.5"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Pretty launch screen" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
+ <rect key="frame" x="0.0" y="202" width="375" height="43"/>
+ <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <constraints>
+ <constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="obG-Y5-kRd" secondAttribute="centerX" id="5cz-MP-9tL"/>
+ <constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb" secondAttribute="centerX" id="Q3B-4B-g5h"/>
+ <constraint firstItem="obG-Y5-kRd" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="20" symbolic="YES" id="SfN-ll-jLj"/>
+ <constraint firstAttribute="bottom" secondItem="obG-Y5-kRd" secondAttribute="bottom" constant="20" id="Y44-ml-fuU"/>
+ <constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
+ <constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="20" symbolic="YES" id="x7j-FC-K8j"/>
+ </constraints>
+ <viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/tests/manual/ios_assets/Info.ios.cmake.plist b/tests/manual/ios_assets/Info.ios.cmake.plist
new file mode 100644
index 0000000000..ebbb6d93ef
--- /dev/null
+++ b/tests/manual/ios_assets/Info.ios.cmake.plist
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+
+ <key>CFBundleDisplayName</key>
+ <string>$(PRODUCT_NAME)</string>
+
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+
+ <key>CFBundleVersion</key>
+ <string>$(CURRENT_PROJECT_VERSION)</string>
+
+ <key>CFBundleShortVersionString</key>
+ <string>$(MARKETING_VERSION)</string>
+
+ <key>NSHumanReadableCopyright</key>
+ <string></string>
+
+ <key>CFBundleIconFile</key>
+ <string></string>
+
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+
+ <key>UILaunchStoryboardName</key>
+ <string>CustomLaunchScreen.storyboard</string>
+
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+
+ <key>CFBundleIcons</key>
+ <dict>
+ <key>CFBundlePrimaryIcon</key>
+ <dict>
+ <key>CFBundleIconFiles</key>
+ <array>
+ <string>AppIcon29x29.png</string>
+ <string>AppIcon29x29@2x.png</string>
+ <string>AppIcon40x40@2x.png</string>
+ <string>AppIcon57x57.png</string>
+ <string>AppIcon57x57@2x.png</string>
+ <string>AppIcon60x60@2x.png</string>
+ </array>
+ </dict>
+ </dict>
+ <key>CFBundleIcons~ipad</key>
+ <dict>
+ <key>CFBundlePrimaryIcon</key>
+ <dict>
+ <key>CFBundleIconFiles</key>
+ <array>
+ <string>AppIcon29x29.png</string>
+ <string>AppIcon29x29@2x.png</string>
+ <string>AppIcon40x40@2x.png</string>
+ <string>AppIcon57x57.png</string>
+ <string>AppIcon57x57@2x.png</string>
+ <string>AppIcon60x60@2x.png</string>
+ <string>AppIcon29x29~ipad.png</string>
+ <string>AppIcon29x29@2x~ipad.png</string>
+ <string>AppIcon40x40~ipad.png</string>
+ <string>AppIcon40x40@2x~ipad.png</string>
+ <string>AppIcon50x50~ipad.png</string>
+ <string>AppIcon50x50@2x~ipad.png</string>
+ <string>AppIcon72x72~ipad.png</string>
+ <string>AppIcon72x72@2x~ipad.png</string>
+ <string>AppIcon76x76~ipad.png</string>
+ <string>AppIcon76x76@2x~ipad.png</string>
+ </array>
+ </dict>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/manual/ios_assets/Info.ios.qmake.plist b/tests/manual/ios_assets/Info.ios.qmake.plist
new file mode 100644
index 0000000000..e97150e47b
--- /dev/null
+++ b/tests/manual/ios_assets/Info.ios.qmake.plist
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${QMAKE_SHORT_VERSION}</string>
+ <key>CFBundleSignature</key>
+ <string>${QMAKE_PKGINFO_TYPEINFO}</string>
+ <key>CFBundleVersion</key>
+ <string>${QMAKE_FULL_VERSION}</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>MinimumOSVersion</key>
+ <string>${IPHONEOS_DEPLOYMENT_TARGET}</string>
+ <key>UILaunchStoryboardName</key>
+ <string>CustomLaunchScreen</string>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+
+ <key>CFBundleIcons</key>
+ <dict>
+ <key>CFBundlePrimaryIcon</key>
+ <dict>
+ <key>CFBundleIconFiles</key>
+ <array>
+ <string>AppIcon29x29.png</string>
+ <string>AppIcon29x29@2x.png</string>
+ <string>AppIcon40x40@2x.png</string>
+ <string>AppIcon57x57.png</string>
+ <string>AppIcon57x57@2x.png</string>
+ <string>AppIcon60x60@2x.png</string>
+ </array>
+ </dict>
+ </dict>
+ <key>CFBundleIcons~ipad</key>
+ <dict>
+ <key>CFBundlePrimaryIcon</key>
+ <dict>
+ <key>CFBundleIconFiles</key>
+ <array>
+ <string>AppIcon29x29.png</string>
+ <string>AppIcon29x29@2x.png</string>
+ <string>AppIcon40x40@2x.png</string>
+ <string>AppIcon57x57.png</string>
+ <string>AppIcon57x57@2x.png</string>
+ <string>AppIcon60x60@2x.png</string>
+ <string>AppIcon29x29~ipad.png</string>
+ <string>AppIcon29x29@2x~ipad.png</string>
+ <string>AppIcon40x40~ipad.png</string>
+ <string>AppIcon40x40@2x~ipad.png</string>
+ <string>AppIcon50x50~ipad.png</string>
+ <string>AppIcon50x50@2x~ipad.png</string>
+ <string>AppIcon72x72~ipad.png</string>
+ <string>AppIcon72x72@2x~ipad.png</string>
+ <string>AppIcon76x76~ipad.png</string>
+ <string>AppIcon76x76@2x~ipad.png</string>
+ </array>
+ </dict>
+ </dict>
+</dict>
+</plist>
diff --git a/tests/manual/ios_assets/appicon/AppIcon29x29.png b/tests/manual/ios_assets/appicon/AppIcon29x29.png
new file mode 100644
index 0000000000..f220ad51a3
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon29x29.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon29x29@2x.png b/tests/manual/ios_assets/appicon/AppIcon29x29@2x.png
new file mode 100644
index 0000000000..69d8a9a3fb
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon29x29@2x.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon29x29@2x~ipad.png b/tests/manual/ios_assets/appicon/AppIcon29x29@2x~ipad.png
new file mode 100644
index 0000000000..69d8a9a3fb
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon29x29@2x~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon29x29~ipad.png b/tests/manual/ios_assets/appicon/AppIcon29x29~ipad.png
new file mode 100644
index 0000000000..f220ad51a3
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon29x29~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon40x40@2x.png b/tests/manual/ios_assets/appicon/AppIcon40x40@2x.png
new file mode 100644
index 0000000000..2966b0d866
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon40x40@2x.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon40x40@2x~ipad.png b/tests/manual/ios_assets/appicon/AppIcon40x40@2x~ipad.png
new file mode 100644
index 0000000000..2966b0d866
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon40x40@2x~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon40x40~ipad.png b/tests/manual/ios_assets/appicon/AppIcon40x40~ipad.png
new file mode 100644
index 0000000000..9956f67ba6
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon40x40~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon50x50@2x~ipad.png b/tests/manual/ios_assets/appicon/AppIcon50x50@2x~ipad.png
new file mode 100644
index 0000000000..570f8c9a50
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon50x50@2x~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon50x50~ipad.png b/tests/manual/ios_assets/appicon/AppIcon50x50~ipad.png
new file mode 100644
index 0000000000..9d7b8edc4f
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon50x50~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon57x57.png b/tests/manual/ios_assets/appicon/AppIcon57x57.png
new file mode 100644
index 0000000000..5d558bbb08
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon57x57.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon57x57@2x.png b/tests/manual/ios_assets/appicon/AppIcon57x57@2x.png
new file mode 100644
index 0000000000..ea14c9c0b9
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon57x57@2x.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon60x60@2x.png b/tests/manual/ios_assets/appicon/AppIcon60x60@2x.png
new file mode 100644
index 0000000000..14eb31e401
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon60x60@2x.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon72x72@2x~ipad.png b/tests/manual/ios_assets/appicon/AppIcon72x72@2x~ipad.png
new file mode 100644
index 0000000000..cb988891ff
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon72x72@2x~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon72x72~ipad.png b/tests/manual/ios_assets/appicon/AppIcon72x72~ipad.png
new file mode 100644
index 0000000000..a0072bcfa1
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon72x72~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon76x76@2x~ipad.png b/tests/manual/ios_assets/appicon/AppIcon76x76@2x~ipad.png
new file mode 100644
index 0000000000..ffa1d4729a
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon76x76@2x~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/appicon/AppIcon76x76~ipad.png b/tests/manual/ios_assets/appicon/AppIcon76x76~ipad.png
new file mode 100644
index 0000000000..15a13665f0
--- /dev/null
+++ b/tests/manual/ios_assets/appicon/AppIcon76x76~ipad.png
Binary files differ
diff --git a/tests/manual/ios_assets/foo.txt b/tests/manual/ios_assets/foo.txt
new file mode 100644
index 0000000000..ce01362503
--- /dev/null
+++ b/tests/manual/ios_assets/foo.txt
@@ -0,0 +1 @@
+hello
diff --git a/tests/manual/ios_assets/ios_assets.pro b/tests/manual/ios_assets/ios_assets.pro
new file mode 100644
index 0000000000..a6a610dcd8
--- /dev/null
+++ b/tests/manual/ios_assets/ios_assets.pro
@@ -0,0 +1,48 @@
+TEMPLATE = app
+SOURCES += main.cpp
+QT += core gui testlib
+CONFIG += app_bundle
+TARGET = tst_manual_ios_assets
+
+# Custom Info.plist
+ios {
+ QMAKE_INFO_PLIST = Info.ios.qmake.plist
+}
+
+# Custom resources
+textFiles.files = $$files(*.txt)
+# On iOS no 'Resources' prefix is needed because iOS app bundles are shallow,
+# so the final location of the text file will be
+# tst_manual_ios_assets.app/textFiles/foo.txt
+# Specifying a Resources prefix actually causes code signing error for some reason.
+# On macOS the location will be
+# tst_manual_ios_assets.app/Contents/Resources/textFiles/foo.txt
+ios {
+ textFiles.path = textFiles
+}
+macos {
+ textFiles.path = Contents/Resources/textFiles
+}
+QMAKE_BUNDLE_DATA += textFiles
+
+# App icons
+ios {
+ ios_icon.files = $$files($$PWD/appicon/AppIcon*.png)
+ QMAKE_BUNDLE_DATA += ios_icon
+}
+
+# Asset catalog with images
+ios {
+ # The asset catalog needs to have an empty AppIcon.appiconset, otherwise Xcode refuses
+ # to compile the asset catalog.
+ QMAKE_ASSET_CATALOGS += Assets.xcassets
+ SOURCES += utils.mm
+ LIBS += -framework UIKit
+}
+
+# Set custom launch screen
+ios {
+ # Underneath, this uses QMAKE_BUNDLE_DATA, prevents the default launch screen from being set
+ # and bundles the custom one.
+ QMAKE_IOS_LAUNCH_SCREEN = $$PWD/CustomLaunchScreen.storyboard
+}
diff --git a/tests/manual/ios_assets/main.cpp b/tests/manual/ios_assets/main.cpp
new file mode 100644
index 0000000000..020f3f940b
--- /dev/null
+++ b/tests/manual/ios_assets/main.cpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtCore/QStandardPaths>
+#include <QtCore/QDir>
+#include <QtTest/QtTest>
+
+#ifdef DEBUG_APP_DATA_LOCATION
+ #include <QtCore/QDebug>
+#endif
+
+class AssetsIos : public QObject
+{
+ Q_OBJECT
+private slots:
+ void bundledTextFiles();
+ void bundledAppIcons();
+ void bundledImageInAssetCatalog();
+};
+
+void AssetsIos::bundledTextFiles()
+{
+#ifdef DEBUG_APP_DATA_LOCATION
+ auto paths = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
+ qDebug() << paths;
+
+ for (const QString& path: paths) {
+ QDir oneDir = QDir(path);
+ qDebug() << "path" << path << "entries" << oneDir.entryList();
+ }
+#endif
+
+ /*
+ AppDataLocation returns the following 3 paths on iOS
+ /var/mobile/Containers/Data/Application/uuid/Library/Application Support/tst_manual_ios_assets
+ /Library/Application Support/tst_manual_ios_assets
+ /private/var/containers/Bundle/Application/<uuid>/tst_manual_ios_assets.app
+
+ The textFiles/foo.txt file only exists in the third location at
+ /private/var/containers/Bundle/Application/<uuid>/tst_manual_ios_assets.app/textFiles/foo.txt
+
+ AppDataLocation returns the following 3 paths on macOS
+ /Users/<user>/Library/Application Support/tst_manual_ios_assets
+ /Library/Application Support/tst_manual_ios_assets
+ <build-dir>/tst_manual_ios_assets.app/Contents/Resources
+
+ Once again the file only exists in the third location at
+ <build-dir>/tst_manual_ios_assets.app/Contents/Resources/textFiles/foo.txt
+ */
+ QString textFile = QStandardPaths::locate(QStandardPaths::AppDataLocation,
+ QStringLiteral("textFiles/foo.txt"));
+ QVERIFY(!textFile.isEmpty());
+}
+
+void AssetsIos::bundledAppIcons() {
+ // Confirm one of the app icons are present.
+ QString appIcon = QStandardPaths::locate(QStandardPaths::AppDataLocation,
+ QStringLiteral("AppIcon40x40@2x.png"));
+ QVERIFY(!appIcon.isEmpty());
+}
+
+bool imageExistsInAssetCatalog(QString imageName);
+
+void AssetsIos::bundledImageInAssetCatalog() {
+ // Asset catalog images can be accessed only via a name, not a path.
+ QVERIFY(imageExistsInAssetCatalog(QStringLiteral("Face")));
+}
+
+QTEST_MAIN(AssetsIos)
+#include "main.moc"
diff --git a/tests/manual/ios_assets/utils.mm b/tests/manual/ios_assets/utils.mm
new file mode 100644
index 0000000000..c3b657084e
--- /dev/null
+++ b/tests/manual/ios_assets/utils.mm
@@ -0,0 +1,18 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtCore/QString>
+
+#ifdef Q_OS_IOS
+#include <UIKit/UIKit.h>
+#endif
+
+bool imageExistsInAssetCatalog(QString imageName) {
+#ifdef Q_OS_IOS
+ UIImage* image = [UIImage imageNamed:imageName.toNSString()];
+ return image != nil;
+#else
+ // Don't fail the test when building on platforms other than iOS.
+ return true;
+#endif
+}