Xamarin iOS Crash - Only when Apple reviews - xamarin

I want to start off saying that I have reviewed the many posts about iOS app crashing only for Apple Review Team and I did not find a solution and also did find one with my crash log information.
This is a Xamarin.Forms project. I have a PCL with Droid and iOS projects. My Droid project works great. I have no issues there. My iOS project is where I am having issues. I can debug this without any hiccups. I have tested this on the various simulators via XCode and also multiple real devices. I constantly get my app rejected by Apple saying the app crashes when it does a certain action. I have tried numerous times to duplicate the crash but I cannot.
I have symbolicated the crash log from Apple and it can be viewed with this link. I do not see anywhere in the crash log that shows my code and what I did wrong. I think it has something to do with me doing async/await stuff but I cannot confirm this.
If it helps, I am using version 2.2.0.31 of Xamarin.
I am new to Apple crash logs and I find them very hard to decipher. Can someone please assist with helping figure out what I am doing wrong.
UPDATE
Included is the code that was requested.
iOS project -- Main.cs
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
iOS project -- AppDelegate.cs
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
App.ScreenWidth = (int)UIScreen.MainScreen.Bounds.Width;
App.ScreenHeight = (int)UIScreen.MainScreen.Bounds.Height;
UINavigationBar.Appearance.TintColor = UIColor.FromRGB(40, 51, 65);
FormsMaps.Init();
AdvancedTimerImplementation.Init();
CachedImageRenderer.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
Shared project -- App.cs
public App()
{
//do the initial setup
var nav = new NavigationService();
if (!SimpleIoc.Default.IsRegistered<INavigationServiceEx>())
SimpleIoc.Default.Register<INavigationServiceEx>(() => nav);
var apiMgr = new ApiManager();
if (!SimpleIoc.Default.IsRegistered<ApiManager>())
SimpleIoc.Default.Register<ApiManager>(() => apiMgr);
var storageMgr = new StorageManager();
if (!SimpleIoc.Default.IsRegistered<StorageManager>())
SimpleIoc.Default.Register<StorageManager>(() => storageMgr);
var externalMaps = DependencyService.Get<IExternalMaps>();
if (!SimpleIoc.Default.IsRegistered<IExternalMaps>())
SimpleIoc.Default.Register<IExternalMaps>(() => externalMaps);
var mediaService = DependencyService.Get<IMedia>();
mediaService.Initialize();
if (!SimpleIoc.Default.IsRegistered<IMedia>())
SimpleIoc.Default.Register<IMedia>(() => mediaService);
var geolocationService = DependencyService.Get<IGeolocator>();
if (!SimpleIoc.Default.IsRegistered<IGeolocator>())
SimpleIoc.Default.Register<IGeolocator>(() => geolocationService);
nav.Configure(ViewModelLocator.StartupPage, typeof(StartupView));
nav.Configure(ViewModelLocator.LoginPage, typeof(LoginView));
nav.Configure(ViewModelLocator.RegisterPage, typeof(RegisterView));
nav.Configure(ViewModelLocator.QouponsPage, typeof(QouponsView));
nav.Configure(ViewModelLocator.UserProfilePage, typeof(UserProfileView));
nav.Configure(ViewModelLocator.EditUserProfilePage, typeof(EditUserProfileView));
nav.Configure(ViewModelLocator.CompanyPage, typeof(CompanyView));
nav.Configure(ViewModelLocator.RedeemPage, typeof(RedeemView));
nav.Configure(ViewModelLocator.SettingsPage, typeof(SettingsView));
nav.Configure(ViewModelLocator.HelpPage, typeof(HelpView));
var startupView = new StartupView();
var startupPage = new NavigationPage(startupView);
startupPage.BarBackgroundColor = Color.FromHex("#FF8A07");
nav.Initialize(startupPage);
startupView.Start();
MainPage = startupPage;
}

Something in your async code threw an exception, and there doesn't seem to be an exception handler for that exception (an exception without an exception handler will crash the process).
This is from your main thread where it shows the async runtime logic throwing the exception on the main thread:
13 QneoiOS 0x000000010023039c System_Runtime_ExceptionServices_ExceptionDispatchInfo_Throw + 44
14 QneoiOS 0x000000010022eea0 System_Runtime_CompilerServices_AsyncMethodBuilderCore__ThrowAsyncm__0_object + 80
15 QneoiOS 0x0000000100b3b798 UIKit_UIKitSynchronizationContext__Postc__AnonStorey0__m__0 (UIKitSynchronizationContext.cs:24)
16 QneoiOS 0x0000000100b55fd4 Foundation_NSAsyncActionDispatcher_Apply (NSAction.cs:163)
You need more details about this exception, the crash report doesn't contain enough information to diagnose further.
My suggestion would be to add a crash-reporting solution (such as Xamarin Insights), resubmit, and then you should get information about the exception in Xamarin Insights when the crash occurs during Apple's review.

I had a similar problem. Moved to Xamarin in Microsoft Studio and it worked on devices & simulator in debug and on simulator in release mode but was crashing in testflight and review. My solution was two things: I changed the linker setting to Link SDKs rather than Link All. I revoked by release certificate and recreated that with a new distribution provisioning profile. This fixed the problem for me. Hope it helps someone else.

Related

Xamarin WebView sometimes doesn't show in UWP

I have a WebView that shows the terms and conditions when the user starts the app. That WebView contains a few links. Currently, I have the terms and conditions as a html file that I store in resources.
In the code-behind I fill the WebView via:
public partial class Agb : ContentPage
{
public Agb()
{
InitializeComponent();
BindingContext = new ViewModel.AgbViewModel();
Web.Source = new HtmlWebViewSource
{
Html = Properties.Resources.Agb
};
Web.Navigating += WebViewNavigating;
}
XML:
<WebView
x:Name="Web"
VerticalOptions="FillAndExpand"
Margin="50,0"/>
Most of the time this works well. On UWP this WebView sometimes fails to show. It always shows on my own computer but randomly fails in production.
Is there anything I can do to get the WebView to work reliably?
Option 1:
I've made a pull request to fix this bug in Xamarin.Forms, so simply update Xamarin.Forms to a version, where it will be merged.
However, while the fix is not yet there and while the fix may not be available for earlier versions of Xamarin.Forms before 4.4.0, here's how to fix it in your project:
Option 2
Add the WebViewRenderer_fix.cs file to your project. This file is based on v4.4.0, but if you see build errors, you may need to apply the fix yourself to earlier version of this file.
And don't forget to register it as a custom renderer for your WebView
[assembly: ExportRenderer(typeof(WebView), typeof(WebViewRenderer_fix))]

Xamarin.Forms targeting macOS

I am using Visual Studio for Mac 7.6.6 to create a Xamarin.Forms app targeting macOS (to be shared with something running on Windows). I create a new Project and select
Multiplatform App | Blank Forms App. Click Next
Configure your Blank Forms App. There are target platforms: Android and iOS.
(There is nothing for macOS). Since I have not installed the build toolkits for either iOS and android, both of these checkboxes are disabled. Therefore the Next button on this wizard page is disabled.
How do I proceed? I assume there is no way to use the New Project wizard for this.
I came across an old post for starting with a Xamarin Cocoa app and using NuGet to put the Xamarin Forms functionality but don't understand the code
LoadApplication(new App()); // <-- don't know what App is
I suspect the VS Mac and Xamarin.Forms are out of sync being on the bleeding edge. Has anyone gotten this to work?
I would suggest following SushiHangover's suggestion since that is simpler which is what you have done already:
Add a new CocoaApp project to your solution.
Install Xamarin.Forms NuGet package into your CocoaApp.
Reference the shared project or .NET Standard project from your CocoaApp project.
Edit info.plist and remove the source entry (NSMainStoryboardFile).
Change the AppDelegate to derive from Xamarin.Forms.Platform.MacOS.FormsApplicationDelegate.
Update Main.cs to initialize the AppDelegate
In the AppDelegate's DidFinishLaunching add the code to initialize Xamarin.Forms.
Create a new NSWindow which should be returned from the MainWindow property in the AppDelegate.
Main.cs:
static class MainClass
{
static void Main(string[] args)
{
NSApplication.Init();
NSApplication.SharedApplication.Delegate = new AppDelegate();
NSApplication.Main(args);
}
}
AppDelegate.cs:
[Register("AppDelegate")]
public class AppDelegate : Xamarin.Forms.Platform.MacOS.FormsApplicationDelegate
{
NSWindow window;
public AppDelegate()
{
var style = NSWindowStyle.Closable | NSWindowStyle.Resizable | NSWindowStyle.Titled;
var rect = new CoreGraphics.CGRect(200, 1000, 1024, 768);
window = new NSWindow(rect, style, NSBackingStore.Buffered, false);
window.Title = "Xamarin.Forms on Mac!";
window.TitleVisibility = NSWindowTitleVisibility.Hidden;
}
public override NSWindow MainWindow
{
get { return window; }
}
public override void DidFinishLaunching(NSNotification notification)
{
Xamarin.Forms.Forms.Init();
LoadApplication(new App());
base.DidFinishLaunching(notification);
}
public override void WillTerminate(NSNotification notification)
{
// Insert code here to tear down your application
}
}
However Visual Studio for Mac does include a Mac project with the Xamarin.Forms project templates. However it does not expose this in the New Project dialog currently. You can create a Mac Forms project from this template but it is a bit more work than what SushiHangover suggested and you have used.
Install the Xamarin.Forms project template into the .NET Core project templates
dotnet new --install "/Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/AddIns/Xamarin.Forms.Addin/Templates/Xamarin.Templates.Multiplatform.0.0.1.nupkg"
Create a new Forms project including the Mac project (you may want to review and set other template parameters - the following creates a blank Forms app with Android, iOS, Mac, UWP and a Shared project).
dotnet new forms-app --CreateMacProject -k blank
Create a new blank solution (Other - Miscellaneous - Blank Solution) in the parent directory of the projects you just created.
Add all those projects created to the solution.
Then you can build and run the Mac project which includes Xamarin.Forms.
Note you may want to remove the Xamarin.Forms project template from the .NET Core project templates which you can do by running the following:
dotnet new --debug:reinit
In addition to the approved answer, which is incomplete with recent updates, now you have to do one more step.
Link the delagate in the Mac project main class
main.cs:
static class MainClass
{
static void Main(string[] args)
{
NSApplication.Init();
NSApplication.SharedApplication.Delegate = new AppDelegate();
NSApplication.Main(args);
}
}
nota. My edit was refused and I'm not allowed to add comments. So I added a complementary answer to help those looking for help now.

xamarin android uitest theme style conflicts

Recently I asked a question over trying to get my theme recognized within the android test project: Unit testing a Xamarin Forms Android specific code project
I'm not running into a conflict that shows up within xunit / nunit as the testing strategy. I feel like it's because the FormsAppCompatActivity with an older activity type, but I'm new to Xamarin and am unsure on how to approach this.
I get a lot of these type of errors:
Attribute "layout_anchorGravity" already defined with incompatible format.
The full list of the similar Attribute errors is:
fabSize
tabMode
expandedTitleGravity
layout_scollFlags
layout_collapseMode
collapsedTitleGravity
tabGravity
showDividers
displayOptions
showAsActions
actionBarSize
finally I have the addition error:
Found tag styles where item is expected
//Within the Android Forms project, I have this inheritance:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity {
// typical code
}
//within the Android UITest project
public class MainActivity : Xunit.Runners.UI.RunnerActivity {
// tests can be inside the main assembly
AddTestAssembly(Assembly.GetExecutingAssembly());
AddExecutionAssembly(typeof(ExtensibilityPointFactory).Assembly);
// or in any reference assemblies
//AddTestAssembly(typeof(PortableTests).Assembly);
// or in any assembly that you load (since JIT is available)
#if false
// you can use the default or set your own custom writer (e.g. save to web site and tweet it ;-)
Writer = new TcpTextWriter ("10.0.1.2", 16384);
// start running the test suites as soon as the application is loaded
AutoStart = true;
// crash the application (to ensure it's ended) and return to springboard
TerminateAfterExecution = true;
#endif
// you cannot add more assemblies once calling base
base.OnCreate(bundle);
}

Xamarin.Forms application throws NullReferenceException only in iOS

I'm creating a Xamarin.Forms Portable application that runs fine in Android but always crashes in iOS.
I get this error:
System.NullReferenceException: Object reference not set to an instance of an object at App.ListJson+<GetPodcasts>d__2.MoveNext () [0x0004e]
It occurs at this piece of code, on the second line:
var httpClient = new HttpClient();
var json = await httpClient.GetStringAsync(REDACTEDSTRING).ConfigureAwait(false);
I've tried fiddling with the HttpClient implementation settings for the iOS project but still get the same error.
The answer found here solved my problem.
To reiterate it here:
Installing the Microsoft.Net.Http NuGet package into the base project will fix the issue.

Changes in MvvmCross bindings

Hi Xamarin/MvvmCross devs,
This is just a question out of curiosity. In one of the apps I'm developing some behaviour changed. Specifically on iOS when binding the UISwitch "On" value to a boolean in the ViewModel. The getter on the property fires when the binding is applied as well as the setter when the switch is flipped, but the UI does not reflect it. Forcing me to go from just
var set = this.CreateBindingSet<SettingsView, SettingsViewModel>();
set.Bind(PushNotificationSwitch).For(s => s.On)
.To(vm => vm.ReceivePushNotifications);
set.Apply();
To having to also add the following below that (to get the UI of the switch to reflect the value)
var settingsViewModel = ((SettingsViewModel)ViewModel);
PushNotificationSwitch.On = settingsViewModel.ReceivePushNotifications;
I left the binding, as well as the new code to reflect UI state, because in addition to the UI just reflecting the correct state, I also want it to change the state in my settingsService when the user changes it.
I recently upgraded through Xamarin Studio on Mac and my iOS Xam version is Version: 10.0.0.6. Unfortunately I didn't check what version I upgraded from, but I always upgrade as soon as I see there's one available, so it should be the previous stable version.
My questions are:
Has any of you experienced similar issues where bindings changed in this way?
Since the Android binding still works fine, do you think it's an issue in MvvmCross, or iOS Xamarin Changes
Any speculations as to what could be causing this? And other parts that you think this might affect, so I won't have to go scour for bugs if none exists. Commands, text and custom control bindings are working fine (as far as I've tested)
If this question would be better suited somewhere else please let me know, I'm just curious about this behaviour.
Thanks
As we worked out in the comments of the OP the event of the switch was linked out. Hence, the binding did nothing.
Easiest way to remedy this is to add the following code to your LinkerPleaseInclude.cs file, which MvvmCross provides in the Startup NuGet and through the templates available for Visual Studio and Xamarin Studio:
public void Include(UISwitch sw)
{
sw.On = !sw.On;
sw.ValueChanged += (sender, args) =>
{
sw.On = false;
};
}
This will tell the Linker that there is a direct usage of both the ValueChanged event and the On property, since the LinkerPleaseInclude class uses the Preserve attribute.

Resources