iOS
Building, testing and deploying apps for Apple iOS platforms.
With Apple decision to focus on Metal, iOS OpenGL ES support is stuck on version 3.0 (i.e., a version before compute shaders are available). Moreover, OpenGL ES is deprecated since iOS 12.
See also Platform::
Bundle creation
Unlike on macOS, where applications can also run directly from a compiled executable, on iOS you are required to create a bundle. The bundle setup is similar to macOS, see the macOS platform guide for details. Compared to macOS, the *.plist
file controls many more options (such as HiDPI/Retina support, supported display orientation, icons, splash screen...). CMake uses its own template that can be configured using various MACOSX_BUNDLE_*
variables, but the builtin file is tailored for macOS and you are much better off rolling your own template and passing abosolute path to it to CMake using the MACOSX_BUNDLE_INFO_PLIST
property:
if(CORRADE_TARGET_IOS) set_target_properties(my-application PROPERTIES MACOSX_BUNDLE ON MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/MacOSXBundleInfo.plist.in) endif()
Below are contents of the *.plist
file as is used in the SDL2 bootstrap application, requesting OpenGL ES 2.0 and advertising Retina support:
<?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>CFBundleDevelopmentRegion</key> <string>en-US</string> <key>CFBundleExecutable</key> <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> <key>CFBundleIdentifier</key> <string>cz.mosra.magnum.MyApplication</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>My Application</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>UIRequiredDeviceCapabilities</key> <array> <string>opengles-2</string> </array> <key>NSHighResolutionCapable</key> <true/> </dict> </plist>
Again, see the official Apple Property List file documentation for information about all options.
Running at native resolution
In order to run at a native resolution on iOS, you need to add a Launch Screen Storyboard. A LaunchScreen.storyboard
file can be generated from Xcode as shown in Apple documentation, you also can find a sample file here or here. Then, do the following in CMake:
target_sources(my-application PRIVATE path/to/LaunchScreen.storyboard) set_property(SOURCE path/to/LaunchScreen.storyboard PROPERTY MACOSX_PACKAGE_LOCATION "Resources/LaunchScreen.storyboard")
You may also want to add this to your *.plist
file:
<key>UILaunchStoryboardName</key> <string>LaunchScreen</string>
Xcode
CMake can't find a compiler
Right after installing Xcode for the first time, CMake might fail with a message saying
No CMAKE_CXX_COMPILER could be found.
In order to fix this, you need to run this command:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
Deploying iOS apps
Application signing
Apps have to be signed in order to run on iPhone. After generating the CMake project, you'll have no code signing set up. In the Xcode go to the General properties for given app target and enable automatic signing. First time you do this for an account, you'll need to set up a certificate. Also note that in case of free developer accounts, you have only a low limit of different bundle IDs to install & launch in a day (usually just 10). Once you reach the limit (for example when running a lot of test executables), you'll be prevented from using new ones. A possible workaround is to reuse a bundle ID from an existing app.
Certificate trusting
When deploying with a developer account for given device for a first time, you'll be prompted to verify your Developer Account. In the iPhone Settings, go to General -> Profiles & Device Management and trust your certificate there.
Deployment target
Generated Xcode projects by default require the iOS version to be matching the iPhone SDK version. If you need to make the app running on older devices, set the CMAKE_OSX_DEPLOYMENT_TARGET
to desired version:
cmake . -DCMAKE_OSX_DEPLOYMENT_TARGET=10.1 # iOS 10.1 at least
Best practices
Official Apple documentation:
Troubleshooting
- GLSL
texelFetch()
returns zero results if you have a texture with integer type and the filtering is not SamplerFilter::Nearest. Yes, it shouldn't matter, but it does.