16 Jan 2023

Solving iOS development issues

Gaida San
By Gaida San Unreal Engine Development Lead

Developing an iOS game in Unreal is possible but can be tricky. In this article, I want to give you solutions to the problems I encountered during my work with iOS. Some of them may seem obvious but you can grab them and save your time and frustration.

I assume we all have a basic knowledge of building iOS games so I will skip the step-by-step tutorial and focus on issues.

All the steps below are the same for UE4 and UE5 projects.

Issue #1: Permission denied

As you all know when we want to create a game for iOS we need an Apple certificate and provision profile. If we cannot access the certificates page or we cannot see the plus sign (+) to create a new certificate on your Apple Developer account, we probably don’t have permission for doing that. We need to contact our IT guy for help. Otherwise, we can’t do much.

For me, this was the biggest issue when I started porting my first game to iOS.

Pic 1 – Main page of the company account on the Apple Developer Portal
Pic 2 – Developer privileges are required for the iOS development

Issue #2: Private key for certificate

After creating the certificate in the Developer portal, we need to generate a private key for it on Mac. Please make sure you do this on Mac’s administrator account. It may save you some trouble later.

Please unlock the System Keychain and import the .cer file. The system should generate a private key for your certificate automatically. It will be connected to your certificate in the KeyChain.

Pic 3 – Unlocking the System keychain on Mac
Pic 4 – Importing certificate to the keychain

Now we just need to export it as a .p12 file and import it to the Unreal project on Windows.

Issue #3: Crash at Editor’s startup

When I opened Editor on the fresh project. I was welcomed by this error:

Pic 5 – Crash at Editor’s startup 

It was caused by the Preview Rendering Level set to Android by the previous developer. I didn’t set up my environment for Android development so when the Editor tried to load this Preview Level at startup, it crashed.
The fix is very easy though. We just need to go to the project’s Save/Config/Windows directory and open EditorPerProjectUserSettings.ini. In this file we need to locate PreviewFeatureLevel and PreviewShaderFormatName and reset them to the default state as follows:

PreviewFeatureLevel=3
PreviewShaderFormatName=None

This is the equivalent of changing the Preview Rendering Level inside the Editor:

Pic 6 – Changing the Preview Rendering Level in the Editor

Issue #4: Identifier not matched

When we go to the Project Settings -> Platforms -> iOS we could see the provision file has the status “Identifier Not Matched”:

Pic 7 – “Identifier not matched” warning for provision files

This is because the Bundle Identifier is not filled in yet, or it just does not match the Id we saved in the provision in the Apple Developer portal. We need to go there and make sure we typed the same App Id in Unreal.

Pic 8 – App Id saved in the provision file on the Apple Developer Portal

When everything is set up correctly, Unreal highlights in green the certificate and provision that are going to be used during the packaging process. In my case, it looks like this:

Pic 9 – The green provision file and certificate are matched with the bundle identifier

Issue #5: Packaging won’t start

When we try to package the game for iOS and Unreal opens up a page in documentation or you see errors like the following, certificate and provision are not set up properly or Unreal cannot find them. It may be also caused by a missing iTunes application so please make sure to install it on your PC. Also, make sure to download iTunes from the Apple website directly, instead of the Windows Store as Apple’s version is always up to date.

Pic 10 – Packaging errors caused by incomplete environment setup

These errors may also pop up when we try to build “For Distribution” but we didn’t import the distribution certificate and provision. 

Always make sure: if you build for distribution use the distribution certificate, If you build for development, use the development certificate.

Pic 11 – “For Distribution” will cause Unreal to use distribution certificate

Issue #6: Keyset does not exist

If we are building a C++ project, we will most likely see the following error:

System.Security.Cryptography.CryptographicException: Keyset does not exist

Pic 12 – “Keyset does not exist” error

It occurs when Unreal tries to code-sign the packaged game and it is unable to do so. This is a somewhat general error and it may appear in several different situations.

First, make sure Unreal can connect to your Mac for remote code compiling via SSH. If the remote build options are not set up, do so. If the options are set up, make sure the connection works, i.e. by pinging your Mac by IP.

Go to Project Settings -> Platforms -> iOS -> Build category -> Remote Build Options

Pic 13 – Remote build options for iOS

If the connection works and you still see the error, open Unreal Editor as an administrator.
<UE5_installation_folder>\Engine\Binaries\Win64\UnrealEngine.exe

or

<UE4_installation_folder>\Engine\Binaries\Win64\UE4Editor.exe

We need to open the Editor, open our project, and start the packaging process again.

With that, the project should package successfully. We can see that in the Unreal Output Log:

Pic 14 – Successfully packaged game

Issue #7: Failed to connect to IPC Port

When we try to install the packaged game on iPhone through the IPhonePackacger and we  see an error about connecting to IPC port, it means we don’t have iTunes installed on your PC:

Pic 15 – “Failed to connect to an IPC Port” error

We need to install iTunes and just try again.

Issue #8: Crash at game’s launch

As we probably all know, the first thing we see when launching your game for the first time is most likely a crash so let’s check how to extract a crash dump.

For accessing Unreal logs on iPhone we can use IPhonePackager. Just select “Advanced Tools” -> “Other Development Tools…” -> And “Backup documents…”. Then select the packaged file installed to the device earlier.

Pic 16 – Backing up game logs through the iPhonePackager

The Packager will save the logs to the IOS_Backups folder. It will be located in the project directory or next to the IPhonePackager.exe, depending on whether we chose the .uproject file for the Packager or not.

In some cases though, crash logs may not be included in the IOS_Backups folder. What we can do is try to find them in the iOS system crash dumps. When we go to Settings -> Privacy -> Analytics & Improvements -> Analytics Data, we can find a list of files with analytic data collected by the iOS. We can find the file named by our game title and the date of the crash. When we open it, we could see the system dump log describing our crash.

Pic 17 – Finding crash dumps saved on iPhone

Unfortunately this doesn’t give us much, because all function calls are saved as memory addresses. To find out what was called we need to convert these addresses into human-readable strings. We need to symbolicate the crash.

The easiest way to do that is through XCode, but we need to connect our device directly to the Mac. I didn’t have physical access to the Mac computer, because I worked mostly remotely, so in my case I used the symbolicatecrash tool provided by the XCode.

We can look for this tool inside the Application directory by executing the following command in Mac’s terminal:

$ find  /Applications/  -name  symbolicatecrash

We will find several versions of it but I used the one saved in the DVTFoundation framework.

Pic 18 – Path to XCode’s symbolicatecrash tool

Now we need to extract the crash from our device, upload it to Mac, then use the symbolicatecrash tool to process the crash like this:

$ export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
$/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash ~/Downloads/ArenaWarriors-115110.ips  >  ArenaWarriors_Symbolicated.txt

As a result, we have a file in which the memory addresses are converted into the actual functions calls.

Pic 19 – Symbolicated iOS crash dump

Be advised though that this approach will work only if we packaged the game for iOS on the same Mac we are symbolicating, and we enabled the generation of .dSYM file in the Project Settings.

Pic 20 – The generation of .dSYM files must be enabled for crash symbolication

Also, symbolicatecrash tool has been deprecated in XCode 13.3 and will be removed in the future. For other ways to symbolicate the crash please see the Apple documentation:
https://developer.apple.com/documentation/xcode/adding-identifiable-symbol-names-to-a-crash-report 

Issue #9: Game looks bad on iPhone

When we finally get our game up and running, we may notice that it just looks bad on the iPhone. This is because Unreal used default graphic settings for a mobile app that may not be suited to our device. We can change that through Device Profiles:

Pic 21 – Device Profiles in Unreal Engine

By default it provides a basic set of devices so if our device is not on the list, we need to enable the Device Profile Selector plugin. In my case it’s the IOS Device Profile Selector:

Pic 22 – Devic Profile Selector plugins in Unreal Engine

The settings that are worth checking are r.MobileContentScaleFactor, and the sg-quality. The first one allows us to scale the resolution of our game to fit best the device screen resolution. Most of the time you will use the value of 2 for iOS, which is the native resolution for iPhone. The scalability settings allow us to change the specific graphic settings, i.e. VFX, foliage, shadows, or textures quality.

Pic 23 – Device Profile settings for iPhone XS Max

All default values saved in the Device Profiles should be good enough but of course feel free to change them as you wish and see what happens. Just make sure to save your work by clicking the “Save as default” button (it will save your changes in the config file). It seems obvious but it took me some time to figure out why my changes are making no effect on the device.

Also, please see the Unreal’s documentation to learn more about device profiles settings:

https://docs.unrealengine.com/5.0/en-US/performance-guidelines-for-mobile-devices-in-unreal-engine
https://docs.unrealengine.com/5.0/en-US/scalability-reference-for-unreal-engine

If we are not satisfied with the results produced by Device Profiles, there is another trick we could use – Texture compression. Basically, we can tell the UE Cooker how much the original Textures should be compressed for mobile. These settings are available in the Project Settings -> Engine category -> Cooker.

Pic 24 – Texture compression settings in UE4
Pic 25 – Texture compression settings in UE5

For my UE 4.27 I changed the PVRTC Compression Quality from 1 to 2 which caused better overall quality of the Textures on mobile but at the same time, it doubled the size of the packaged game.

PVRTC is the default Texture compression format for iOS devices, but starting with the  iPhone 6, Apple also supports ASTC. That’s probably why the PVRTC is removed in the UE5. Also, Apple’s GPU is based on ARM architecture so make sure to select the ARM Texture Compressor.

Issue #10: Error ITMS-90161

Shortly: If a build is not packaged for distribution, don’t try to upload it to TestFlight. This is the error the Transporter app will give us if we try to upload a development game:

Pic 26 – “Invalid Provisioning Profile” error in the Transporter app

The error message states that we need to use the distribution provisioning profile. To do this, we need to tell Unreal that we want to package for Distribution (Pic 11).

Checking this will automatically change the Build Configuration to Shipping, but we can set it back to Development and still upload the game to Test Flight.

Gaida San
By Gaida San Unreal Engine Development Lead
SIRBart

Call The Knights!

    Table of contents