Strange Build Behavior for Release Configuration

gtodd876gtodd876 ✭✭Member ✭✭

I have been wrestling with the build settings on Visual Studio for Mac to create a working build on iTunes Connect that doesn't crash sections of the app after I install it through Test Flight. Here's the different behavior I'm experiencing depending on the Build settings/configuration and if I'm deploying to real device or iOS Simulator:

RELEASE/
SDK: Default
Linker Behavior: Link All
Supported Architechture: x86_64
HttpClient Implementation: Managed
Checked: Use LLVM
Checked: 32bit float ops as 64bit
Checked: Strip native debugging symbols
Unchecked: Enabled incremental builds
Unchecked: Concurrent garbage collector
Unchecked: Enable device specific builds
Checked: Optimize PNG Images

  • With these settings the app works perfectly fine in RELEASE mode with the iOS Simulator.

  • For iPhone selected as my platform(physicsl device) - I used the exact same build settings as "Release/iPhoneSimulator"(the exception being, "Supported Architectures" since the only choice for iPhone is ARM64 and the only choice for iOS Simulator is x86_64)

  • The app will load fine but about half of the NavController sections I open up from the home page will crash the app. Again, the app works fine on the iOS simulator with the same release build settings.

  • If I check the "Enable device-specific builds" then redeploy to my phone, then it all works again! Yet there is a warning not to use this setting in release mode. Again, only checking (enabling) this box, will prevent my app from crashing in release mode on a physical iPhone.

  • If I do enable device-specific builds and create an bundle with those working build settings, upload to iTunes Connect and install the app on my phone through Test Flight then the same crashes will happen again.

How do you debug weird complier behavior like this in release mode. I know the app can work fine but why do I need "Enable device-specific build" turned on to make it work?

Any help would be greatly appreciated. Thank you in advance for your time.

Tagged:

Posts

  • JGoldbergerJGoldberger Xamurai USMember, Forum Administrator, Xamarin Team, University Xamurai

    @gtodd876

    The first thing I will say is that using the "Link All" option is often problematic and often requires some work on the developers part to make sure that any needed types are not stripped away by the linker. Does changing that option to "Link Framework SDKs Only" change the behavior at all? For more on the linker, see this doc: https://docs.microsoft.com/en-us/xamarin/ios/deploy-test/linker?tabs=macos

    There is one thing that you cannot change in the settings. iPhone builds are always AOT (Ahead of Time) compiled since the iOS iPhone runtime will not allow dynamic code generation so your Xam.iOS code has to be fully compiled to machine code before deploying to an iPhone. In contrast, the iPhone Simulator does allow dynamic code generation, so when building for iPhone Simulator, the Xam.iOS code is JIT (Just in Time) compiled to IL (.NET Intermediate Language), and then during runtime mono will JIT compile the IL to machine code at runtime.

    As for Device specific builds, not sure why that would affect the apps stability. The intent of Device Specific builds is to speed up deployment when debugging since the compiler will only AOT compile for the specific device you are using, saving time. For instance, if you have to compile for ARMv7 and ARM64, it will take twice as long as just compiling for ARM64. So this is not recommended for release since you likely want to support more than the specific device you are using. This is likely a bug that might need to be reported.

    So the first thing I would try is changing the linker option noted above. If that resolves the issue, great. If the app bundle size is then too large such that you want to use the "Link All" linker option, then you are going to have to do the work to make sure you are preserving all needed types from any third party libraries that you may be referencing only via reflection since the linker will strip out any code in non-Xamarin-framework assemblies that is not statically referenced in your app code. See the above linked linker document for more info on using the "Link All" option and preserving code.

    If using the "Link Framework SDKs Only" option does not help, then I might suggest opening a free xamarin support case so that someone form the MS Xamarin support team (such as myself) can help determine if there is a bug that needs to be filed or there is some other issue in your configuration that needs to be addressed. Doing this will also allow you to share code privately and securely.

  • gtodd876gtodd876 ✭✭ Member ✭✭
    edited March 4

    Extremely helpful. Thank you so much for all this detailed information!

    It was so strange that un/checking the device specific build box was making a difference in my app working or not. Rolling back my code to before I made any release builds was the only thing that fixed the issue and the settings I choose now are making sense. I have the linker set to SDKs only, disabled the device specific builds and the app works great.

    Once the app has been successfully approved the app store, I'll revisit these settings, see if I can recreate a bug, and file any issues.

    Thanks again for the help.

Sign In or Register to comment.