📜 ⬆️ ⬇️

Solving common problems when building an Xcode project generated by Unity3D

This article describes some typical problems that arise when building / running on a device / display in the App Store of the Xcode project for iOS, generated through Unity3D, as well as their causes and solutions. From personal experience, these problems occur quite often and not just me. For the most part, the article can help those who are not very familiar with native iOS development.

At the time of this writing, Unity3d version 5.1.2f and XCode 7.0.1 were used. When using Unity3D versions 5.2 and above, the problems listed later in the article will also be repeated. Some of the problems are related to innovations in iOS 9.0. Attention under the cut a lot of graphics.

Bitcode


Technology Apple, introduced with the release of iOS 9. It is part of the App Thinning technology, used to split the application package into several packages, depending on the architecture of the device. In order for the application to use Bitcode, it is necessary not only that the application itself be written with Bitcode support, but all third-party libraries must be built using Bicode.

If one of the libraries does not support Bitcode, XCode will generate an error at the linking stage, and it will look something like this:
')


In this case, the library with which the problem arose - GameCenter.

You can fix the error in two ways:

With the first option, everything is very clear. The second way is now easier. To switch off, you need to find the necessary option in the project settings and set its value to NO.



ipad multitasking


This technology is used to split the iPad screen into 2 parts, each of which has a separate application.

When developing games, this technology does not make sense, since during the game it is necessary to use the entire screen of the device for maximum user immersion. In this matter, Apple stands with us:
Consider opting out only these categories:
  • Camera-centric apps, where is your primary feature?
  • Full-device apps such as games

When testing an application and building it on a device, there are no problems with multitasking, errors do not appear. However, problems may begin when you submit a package to the App Store.



ITMS-90475 and ITMS-90474 errors occur at the very last moment when the application was sent to the store, when you already think that everything is fine. It is better to get rid of them in advance, because the assembly and dispatch of a package can take a very long time (in practice, it took up to 20 minutes).

The problem is solved quite simply, again, through the project settings:



It is necessary to tick off “Requires full screen”.

Error when using categories in objective-C


Categories are a convenient way to extend the functionality of an existing, or even one of the built-in classes in Objective-C without changing the existing class code.

When generating a project, Unity itself does not use categories. Errors related to categories can appear only in the case of using native iOS plug-ins in a project. This is due to the dynamic nature of Objective-C. The error itself creeps in at the stage of linking the application. At the compilation stage, if the source code file contains calls to functions or methods of another class, the undefined symbol is written to the object file at the place where the class is called. Then, when linking the executable file, the linker inserts an object file with the required method for the undefined symbol location. If it is built using static libraries (or iOS frameworks), the linker tries to reduce the size of the executable file, not including the entire library, but choosing the necessary parts.

Due to the dynamic nature of Objective-C, symbols are defined only for classes, and not defined for methods. For this reason, if the class that was inserted by the linker for the undefined symbol does not have the desired method, then an exception of type unrecognized selector to instance will occur at runtime.

It will look something like this:



In the example from the screenshot, the NSSting class attempted to call the MD5 method, which was not found because it was implemented in a category from a third-party library.

This is due to the fact that the supplier of the library has collected it is not quite right, so you can write a letter of support and ask to correct an annoying misunderstanding. There are cases when the library supplier does not want to correct the defect. In this case, you can correct the project settings in such a way as to avoid this error.

In more detail the problem is painted here .

You need to add an additional flag linker and rebuild the project. There are 2 flags that can help in this situation: -all-load and -ObjC. You should first try -all-load, and, if it doesn’t help, -ObjC (in practice there was a case when the rest of the native project stopped gathering when using -ObjC).

Flags are added in settings, in the Build Settings tab of the Xcode project:



Error sending request to any URL


The situation looks like this: in Unity Editor or on Android requests go without problems, the answer is correct, everything is fine. Even all is well on a device with iOS <9.0. On iOS 9.0, the answer does not come or a connection error. In this case, it will not necessarily be exception, if the draft provides for a case when the response from the server did not come or came with an error. In this case, the problem comes from App Transport Security .

The problem has 2 solutions:

Project exceptions are set in the .plist file with the project's Xcode settings. You need to know what requirements the domain does not meet in order to correctly make an exception using the values ​​specified in the documentation. You can edit the .plist file as the source code, you can add the necessary fields using the Xcode editor as you like.

An example of an exception in the form of source code (a piece of code is added to an existing Info.plist file):

<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>your_domain.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict> 

After these manipulations, the request passes without problems, and earlier versions of iOS ignore the NSAppTransportSecurity keys in the project’s .plist.

Missing arm64 architecture


The error known as itms-90533. Appears when trying to send a packet to the stop that does not contain the arm64 architecture.



Make sure that when building the project in Unity, in the Project Settings -> Player for iOS section, the IL2CPP was used as the Scripting Backend (the second mono2x option is not able to arm64).



If mono2x was used, the Xcode project needs to be exchanged.

Problem with trampolines


An error occurs at the application runtime, the application crashes and something like “Ran out of trampolines of type 0/1/2” appears in the log. This error is also specific to iOS. Trampolines is a thing that is used inside Mono. You can learn more about them here and here .

In short, trampolines are small pieces of assembly code written to perform various tasks in mono runtime. They are generated at runtime using the native macro used by the JIT compiler. You can consider trampolines as a tool to call JIT-code from runtime and vice versa. For example, JIT code can be considered generic methods using interfaces in C # for Unity.

The problems begin with the fact that iOS does not support JIT, only AOT. This is possible for several reasons: iOS does not allow the use of memory pages that are both writable and executable, Apple may prohibit JIT compilation, as a result of the application being prohibited from executing code that was not in the build at the time it was sent to the review.

In total, there are 3 types of trampolines in mono, whose alleged roles are as follows:


For iOS, trampolines are set in advance, and if your project tries to use them more than is created at the time of launch, the application will crash with a ran out of trampolines error. By default, the application creates 1024 trampoline type 0, 1024 type 1, and 128 type 2.

To solve this error, you just need to increase the number of trampolines you need for your project type by more. The number of trampolines required in a project can only be determined experimentally by gradually increasing this value. This is done using the AOT Compilation Options in Unity (Project Settings -> Player).

You can increase the number of trampolines using the following parameters:




It is worth paying attention to the fact that the project may lack several types of trampoline. In this case, the keys must be specified with ";" no spaces, otherwise the keys will be ignored.

Source: https://habr.com/ru/post/269041/


All Articles