Xamarin Forms InAppBillingPlugin PurchaseAsync exeption - xamarin

I need some support regarding InAppBillingPlugin for Xamarin.Forms. First of all I did configuration according to documnetation: https://jamesmontemagno.github.io/InAppBillingPlugin/
application, Google Console (managed products) and iTunes Connect site.
Here is my application code.
private async Task TryInAppPurchace(string androidProductId, string iOSProductId="")
{
if (!CrossInAppBilling.IsSupported)
return;
//Android
var products = new string[] { androidProductId };
if(Device.RuntimePlatform == Device.iOS)
products = new string[] { iOSProductId };
var billing = CrossInAppBilling.Current;
//billing.InTestingMode = true;
try
{
var connected = await billing.ConnectAsync(ItemType.InAppPurchase);
if (!connected)
{
await Application.Current.MainPage.DisplayAlert("Connectivity Error", "Unable to connect to the internet.", "OK");
return;
}
var items = await billing.GetProductInfoAsync(ItemType.InAppPurchase, products);
var item = items.ToList().First();
//try to purchase item
var purchase = await billing.PurchaseAsync(item.ProductId, ItemType.InAppPurchase, item.ProductId);
//possibility that a null came through.
if (purchase == null)
{
await Application.Current.MainPage.DisplayAlert("Purchase Error", "You are unable to buy this product.", "OK");
return;
}
else
{
await _pageService.DisplayAlert("Purchased", "Consumable product.", "OK");
if (Device.RuntimePlatform == Device.iOS)
return;
var consumedItem = await CrossInAppBilling.Current.ConsumePurchaseAsync(purchase.ProductId, purchase.PurchaseToken);
if (consumedItem != null)
{
await Application.Current.MainPage.DisplayAlert("New Package added", "Successfully added new package", "OK");
}
}
}
catch (InAppBillingPurchaseException purchaseEx)
{
var message = string.Empty;
await Application.Current.MainPage.DisplayAlert("Exeption", purchaseEx.Message, "OK");
switch (purchaseEx.PurchaseError)
{
case PurchaseError.BillingUnavailable:
message = "BillingUnavailable";
break;
case PurchaseError.DeveloperError:
message = "DeveloperError";
break;
case PurchaseError.ItemUnavailable:
message = "ItemUnavailable";
break;
case PurchaseError.GeneralError:
message = "GeneralError";
break;
case PurchaseError.UserCancelled:
message = "UserCancelled.";
break;
case PurchaseError.AppStoreUnavailable:
message = "AppStoreUnavailable.";
break;
case PurchaseError.PaymentNotAllowed:
message = "PaymentNotAllowed.";
break;
case PurchaseError.PaymentInvalid:
message = "PaymentInvalid";
break;
case PurchaseError.InvalidProduct:
message = "InvalidProduct";
break;
case PurchaseError.ProductRequestFailed:
message = "ProductRequestFailed";
break;
case PurchaseError.RestoreFailed:
message = "RestoreFailed";
break;
case PurchaseError.ServiceUnavailable:
message = "ServiceUnavailable";
break;
}
}
catch (Exception ex)
{
//Something else has gone wrong, log it
await Application.Current.MainPage.DisplayAlert("Exeption", ex.Message, "OK");
}
finally
{
await billing.DisconnectAsync();
}
}
My problem is that I am not able to buy the same product again and I am getting exeption from Google Play:
{Plugin.InAppBilling.Abstractions.InAppBillingPurchaseException:
Unable to process purchase. at
Plugin.InAppBilling.InAppBillingImplementation+d__33.MoveNext
() [0x00116] in
C:\projects\inappbillingplugin\src\Plugin.InAppBilling.Android\InAppBillingImplementation.cs:324
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
[0x0000c] in :0 at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess
(System.Threading.Tasks.Task task) [0x0003e] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification
(System.Threading.Tasks.Task task) [0x00028] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd
(System.Threading.Tasks.Task task) [0x00008] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult ()
[0x00000] in :0 at
Plugin.InAppBilling.InAppBillingImplementation+d__32.MoveNext
() [0x00090] in
C:\projects\inappbillingplugin\src\Plugin.InAppBilling.Android\InAppBillingImplementation.cs:264
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
[0x0000c] in :0 at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess
(System.Threading.Tasks.Task task) [0x0003e] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification
(System.Threading.Tasks.Task task) [0x00028] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd
(System.Threading.Tasks.Task task) [0x00008] in
:0 at
System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult ()
[0x00000] in :0 at
DrivingCourse_app.ViewModels.AccessPageViewModel+d__18.MoveNext
() [0x0025c] in
C:\Projects\GIT-REPO\DrivingCourse_DE\DrivingCourse_app\DrivingCourse_app\DrivingCourse_app\ViewModels\AccessPageViewModel.cs:136
}
Is something wrong with my code? This code is working for every fist purchase of the product, so configuration itself and the general process works.
Any ideas?

Related

await CrossFilePicker.Current.PickFile() not working for pdf files

I am using await CrossFilePicker.Current.PickFile() for file picking in xamarin forms but it is not working for pdf files, I am getting the exception below:
Exception :
at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0008e] in <24e422c426e0468ca1fd74b59870ff08>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeNonvirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0001f] in <24e422c426e0468ca1fd74b59870ff08>:0
at Android.Content.ContentResolver.Query (Android.Net.Uri uri, System.String[] projection, System.String selection, System.String[] selectionArgs, System.String sortOrder) [0x000a0] in /Users/builder/azdo/_work/278/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-28/mcw/Android.Content.ContentResolver.cs:1096
at Plugin.FilePicker.IOUtil.GetDataColumn (Android.Content.Context context, Android.Net.Uri uri, System.String selection, System.String[] selectionArgs) [0x00013] in D:\a\1\s\src\Plugin.FilePicker\Android\IOUtil.android.cs:154
at Plugin.FilePicker.IOUtil.GetPath (Android.Content.Context context, Android.Net.Uri uri) [0x0017d] in D:\a\1\s\src\Plugin.FilePicker\Android\IOUtil.android.cs:111
at Plugin.FilePicker.FilePickerActivity.OnActivityResult (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data) [0x00054] in D:\a\1\s\src\Plugin.FilePicker\Android\FilePickerActivity.android.cs:168
How can I resolve this?
As Jason said, you could use the Xamarin.Essentials. The code below to pick pdf files for your reference.
async Task<FileResult> PickAndShow(PickOptions options)
{
try
{
var result = await FilePicker.PickAsync(options);
if (result != null)
{
Text = $"File Name: {result.FileName}";
if (result.FileName.EndsWith("pdf", StringComparison.OrdinalIgnoreCase))
{
//do something you want
}
}
return result;
}
catch (Exception ex)
{
// The user canceled or something went wrong
}
return null;
}

While Request for location permission, app is crashing in iOS only. in xamarin

I am trying to request for location permission.when call goes to requestPermissionAsync, Whole app is crashing, I have Attached my code below please go throw it.
var hasPermission = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (hasPermission == PermissionStatus.Unknown)
{
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
hasPermission = results[Permission.Location];
}
if (hasPermission == PermissionStatus.Denied)
{
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
hasPermission = results[Permission.Location];
if (hasPermission == PermissionStatus.Denied)
{
string zipCode = await cache.GetObject<string>(AppConstants.USER_LOCATION_ZIPCODE_KEY);
settingsService.AddItem(AppConstants.USER_LOCATION_ZIPCODE_KEY, zipCode);
settingsService.AddItem(AppConstants.USER_LOCATION_LAT_KEY, "");
settingsService.AddItem(AppConstants.USER_LOCATION_LON_KEY, "");
}
else if (hasPermission == PermissionStatus.Granted)
{
var locator = CrossGeolocator.Current;
Plugin.Geolocator.Abstractions.Position currentPosition = await locator.GetPositionAsync(new TimeSpan(0, 0, 0, 10, 0));
var addressList = await locator.GetAddressesForPositionAsync(currentPosition, null);
foreach (var item in addressList)
{
settingsService.AddItem(AppConstants.USER_LOCATION_ZIPCODE_KEY, item.PostalCode);
settingsService.AddItem(AppConstants.USER_LOCATION_LAT_KEY, item.Latitude.ToString());
settingsService.AddItem(AppConstants.USER_LOCATION_LON_KEY, item.Longitude.ToString());
break;
}
}
}
please help me and Thanks in Advance.
StackTrace:
System.Threading.Tasks.TaskCanceledException: A task was canceled.
at System.Net.Http.NSUrlSessionHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x001d4] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.8.3.0/src/Xamarin.iOS/Foundation/NSUrlSessionHandler.cs:459
at System.Net.Http.HttpClient.SendAsyncWorker (System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) [0x0009e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs:281
at Qualbe1DMobileApp.Repository.GenericRepository+<>c__DisplayClass3_1`2[T,TR].<PostAsync>b__2 () [0x0003f] in /Users/admin/Desktop/1DentalMobile/1DM_Development/Qualbe1DMobileApp/Qualbe1DMobileApp/Qualbe1DMobileApp/Repository/GenericRepository.cs:147
at Polly.Policy+<>c__DisplayClass181_0`1[TResult].<ExecuteAsyncInternal>b__0 (Polly.Context ctx, System.Threading.CancellationToken ct) [0x0003d] in C:\projects\polly\src\Polly.Shared\Policy.Async.cs:63
at Polly.RetrySyntaxAsync+<>c__DisplayClass25_1.<WaitAndRetryAsync>b__1 (Polly.Context ctx, System.Threading.CancellationToken ct) [0x0003d] in C:\projects\polly\src\Polly.Shared\Retry\RetrySyntaxAsync.cs:545
at Polly.Retry.RetryEngine.ImplementationAsync[TResult] (System.Func`3[T1,T2,TResult] action, Polly.Context context, System.Threading.CancellationToken cancellationToken, System.Collections.Generic.IEnumerable`1[T] shouldRetryExceptionPredicates, System.Collections.Generic.IEnumerable`1[T] shouldRetryResultPredicates, System.Func`1[TResult] policyStateFactory, System.Boolean continueOnCapturedContext) [0x00077] in C:\projects\polly\src\Polly.Shared\Retry\RetryEngineAsync.cs:29
at Polly.Retry.RetryEngine.ImplementationAsync[TResult] (System.Func`3[T1,T2,TResult] action, Polly.Context context, System.Threading.CancellationToken cancellationToken, System.Collections.Generic.IEnumerable`1[T] shouldRetryExceptionPredicates, System.Collections.Generic.IEnumerable`1[T] shouldRetryResultPredicates, System.Func`1[TResult] policyStateFactory, System.Boolean continueOnCapturedContext) [0x0025d] in C:\projects\polly\src\Polly.Shared\Retry\RetryEngineAsync.cs:50
at Polly.Policy.ExecuteAsyncInternal[TResult] (System.Func`3[T1,T2,TResult] action, Polly.Context context, System.Threading.CancellationToken cancellationToken, System.Boolean continueOnCapturedContext) [0x000b2] in C:\projects\polly\src\Polly.Shared\Policy.Async.cs:61
at Polly.Policy.ExecuteAsync[TResult] (System.Func`3[T1,T2,TResult] action, Polly.Context context, System.Threading.CancellationToken cancellationToken, System.Boolean continueOnCapturedContext) [0x00073] in C:\projects\polly\src\Polly.Shared\Policy.Async.ExecuteOverloads.cs:261
at Qualbe1DMobileApp.Repository.GenericRepository.PostAsync[T,TR] (System.String uri, T data, System.String funcKey, System.String authToken, System.String appId, System.String appKey) [0x004a6] in /Users/admin/Desktop/1DentalMobile/1DM_Development/Qualbe1DMobileApp/Qualbe1DMobileApp/Qualbe1DMobileApp/Repository/GenericRepository.cs:177
at Qualbe1DMobileApp.Services.Data.MemberService.GetMemberInfo (System.Int64 memberid) [0x00081] in /Users/admin/Desktop/1DentalMobile/1DM_Development/Qualbe1DMobileApp/Qualbe1DMobileApp/Qualbe1DMobileApp/Services/Data/MemberService.cs:34
at Qualbe1DMobileApp.ViewModels.AccountLandPageViewModel.ShowOptions () [0x00117] in /Users/admin/Desktop/1DentalMobile/1DM_Development/Qualbe1DMobileApp/Qualbe1DMobileApp/Qualbe1DMobileApp/ViewModels/AccountLandPageViewModel.cs:48
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.8.3.0/src/Xamarin.iOS/Foundation/NSAction.cs:178
at at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.8.3.0/src/Xamarin.iOS/UIKit/UIApplication.cs:86
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0000e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.8.3.0/src/Xamarin.iOS/UIKit/UIApplication.cs:65
at Qualbe1DMobileApp.iOS.Application.Main (System.String[] args) [0x00001] in /Users/admin/Desktop/1DentalMobile/1DM_Development/Qualbe1DMobileApp/Qualbe1DMobileApp/Qualbe1DMobileApp.iOS/Main.cs:17
If you look at your Stack Trace your code fails because of a Task you are starting and is cancelled:
at Qualbe1DMobileApp.Repository.GenericRepository.PostAsync[T,TR] (System.String uri, T data, System.String funcKey, System.String authToken, System.String appId, System.String appKey) [0x004a6] in /Users/admin/Desktop/1DentalMobile/1DM_Development/Qualbe1DMobileApp/Qualbe1DMobileApp/Qualbe1DMobileApp/Repository/GenericRepository.cs:177
at Qualbe1DMobileApp.Services.Data.MemberService.GetMemberInfo (System.Int64 memberid) [0x00081] in /Users/admin/Desktop/1DentalMobile/1DM_Development/Qualbe1DMobileApp/Qualbe1DMobileApp/Qualbe1DMobileApp/Services/Data/MemberService.cs:34
at Qualbe1DMobileApp.ViewModels.AccountLandPageViewModel.ShowOptions () [0x00117] in /Users/admin/Desktop/1DentalMobile/1DM_Development/Qualbe1DMobileApp/Qualbe1DMobileApp/Qualbe1DMobileApp/ViewModels/AccountLandPageViewModel.cs:48
So either MemberService line 32 or AccountLandPageViewModel line 48 should catch and handle this exception.
Thanks All, Actually i am calling some API's before asking location permission. so before response from API it comes to location permission that's why app is crashing now work fine.Thanks for you valuable time.

async WebRequest troubles

I am trying to create some regression tests that make async calls to our API. I have been getting a null reference error consistently no matter what I try. I have tried several different ways of calling the request to no avail. I'm at my wit's end. I can put a breakpoint in the code to check the URL and run that URL in Postman and it returns data as expected. I am passing a few headers but nothing out of the ordinary.
Below is the stack trace and my code. Can anyone see what I am missing?
Thanks
<GetApiResponse>d__17`1.MoveNext() in C:\Users\foo\Documents\test.api\Common\Base.cs:line 199
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Test.API.ResultsTest.<ResultsAPI_SortByLowToHigh>d__1.MoveNext() in C:\Users\voo\Documents\test.api\ResultsTest.cs:line 74
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Result Message:
Test method Test.API.ResultsAPI_SortByLowToHigh threw exception:
System.NullReferenceException: Object reference not set to an instance of an object.
try
{
var webRequest = WebRequest.Create(url);
webRequest.Method = "GET";
webRequest.ContentType = "application/json";
webRequest.Headers.Add("ApiVersion", "1");
webRequest.Headers.Add("Country-Code", "US");
webRequest.Headers.Add("Currency-Code", "USD");
Task<WebResponse> responseTask = webRequest.GetResponseAsync();
using (var webResponse = await responseTask)
{
using (var sres = webResponse.GetResponseStream())
{
var ms = new MemoryStream();
if (sres != null) await sres.CopyToAsync((ms));
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
JsonResponse = sr.ReadToEnd();
}
}
}
if (!string.IsNullOrEmpty(JsonResponse))
{
response = JsonConvert.DeserializeObject<ServiceResponse>(JsonResponse);
}
else
{
throw new Exception(typeof(ServiceResponse).Name + " API returned null Response");
}
return response;
}
catch (WebException e)
{
ErrorMsg.AppendLine(e.Message);
throw;
}

Realms.SynchronizationContextEventLoop error in realm

when we are trying update realm db multiple times its throwing following error
NHANDLED EXCEPTION:
System.ObjectDisposedException: Safe handle has been closed
at (wrapper managed-to-native) System.Object:wrapper_native_0xda0c96a0 (intptr)
at Realms.SynchronizationContextEventLoopSignal+EventLoop+<Post>c__AnonStorey0.<>m__0 (System.Object _) [0x00012] in <550621f4184f47c0bdfce087c391c293>:0
at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <d855bac285f44dda8a0d8510b679b1e2>:0
at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <d855bac285f44dda8a0d8510b679b1e2>:0
at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <d855bac285f44dda8a0d8510b679b1e2>:0
at (wrapper dynamic-method) System.Object:f9edc18f-c720-423d-8576-23c20d8f6a89 (intptr,intptr)
we have tried to keep our code inside try and catch but its still throwing runtime error and application gets crashed
Code , here EventType is a normal class ( not derived from RealmObject ) but Response class is a RealmObject and it has opportunitiesList declared as
public IList<Opportunity> opportunitiesList { get; } and its derived from RealmObject
private void updateGetData(EventType e)
{
try
{
Realm realm = Realm.GetInstance();
realm.WriteAsync(tempRealm =>
{
if (Settings.IsSingleOpportunityUpdated == false)
{
tempRealm.Add(e.response, true);
}
else if (Settings.IsSingleOpportunityUpdated)
{
if (e.response != null && e.response.opportunitiesList.Count > 0)
{
long opportunityId = e.response.opportunitiesList[0].opportunityId;
var opportunity = tempRealm.All<Opportunity>().FirstOrDefault(d => d.opportunityId == opportunityId);
e.response.opportunitiesList[0].isOpportunitySync = 0;
e.response.opportunitiesList[0].isSync = SyncStatus.SYNCED;
e.response.opportunitiesList[0].mOpportunityId = opportunity.mOpportunityId;
Debug.WriteLine("Opportunity Id after getOpportunity " + opportunity.opportunityId + " " + opportunityId + " " + e.response.opportunitiesList[0].isSync);
tempRealm.Add(e.response.opportunitiesList[0], true);
}
else
{
Debug.WriteLine("RealmDB opportunity response is empty " + Settings.IsSingleOpportunityUpdated);
}
}
});
}
catch(Exception exception)
{
Debug.WriteLine("RealmDB " + exception.StackTrace);
}
}

NullReference when ShowViewModel is called for MvxTabBarViewController

I created a MvxTabBarViewController and when I'm trying open that using ShowViewModel method, a NullReferenceException occurs. The ViewModel property is always null and the exception occurs if I try instanciate that.
There is my MvxTabViewController
[Register("ProjectDetailsView")]
public class ProjectDetailsView : MvxTabBarViewController<ProjectDetailsViewModel>
{
private JVMenuPopoverViewController _menuController;
public override void ViewDidLoad()
{
base.ViewDidLoad();
if (ViewModel == null)
{
ViewModel = new ProjectDetailsViewModel();
}
CriaAbas();
CriaMenu();
}
private void CriaMenu()
{
var itensMenu = new List<JVMenuItem>();
var selectFavoriteProjectsItem = new JVMenuActionItem
{
Title = "Select Favorite Projects",
Command = () =>
{
var favoriteProjectsView = this.CreateViewControllerFor<FavoriteProjectsViewModel>() as UIViewController;
NavigationController.PushViewController(favoriteProjectsView, true);
}
};
itensMenu.Add(selectFavoriteProjectsItem);
var logoutItem = new JVMenuActionItem()
{
Title = "Logout",
Command = ViewModel.LogoutCommand.Execute
};
itensMenu.Add(logoutItem);
_menuController = new JVMenuPopoverViewController(itensMenu);
var menuButton = new UIBarButtonItem();
menuButton.Clicked += (sender, args) =>
{
_menuController.ShowMenuFromController(this);
};
menuButton.Image = UIImage.FromBundle("images/ic_menu_white_36pt.png");
NavigationItem.RightBarButtonItem = menuButton;
}
private void CriaAbas()
{
var abas = new List<UIViewController>();
var controller = new UINavigationController();
var informationView = this.CreateViewControllerFor(ViewModel.ProjectInformationViewModel) as UIViewController;
informationView.TabBarItem = new UITabBarItem("Information", UIImage.FromBundle("images/ic_info_outline.png"), 0);
informationView.Title = "Information";
controller.PushViewController(informationView, false);
abas.Add(informationView);
controller = new UINavigationController();
var milestonesView = this.CreateViewControllerFor(ViewModel.ProjectMilestonesViewModel) as UIViewController;
milestonesView.TabBarItem = new UITabBarItem("Milestones", UIImage.FromBundle("images/ic_assistant_photo_48pt.png"), 0);
milestonesView.Title = "Milestones";
controller.PushViewController(milestonesView, false);
abas.Add(milestonesView);
ViewControllers = abas.ToArray();
SelectedViewController = ViewControllers[0];
}
}
I'm trying to open this view calling ShowViewModel();
What I'm doing wrong?
there is a part of my stack trace:
mvx: Diagnostic: 72,18 Showing ViewModel ProjectDetailsViewModel
iOSNavigation: Diagnostic: 72,18 Navigate requested
Unhandled Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object
at MvvmCross.iOS.Views.MvxTabBarViewController.set_DataContext (System.Object value) [0x00001] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:38
at MvvmCross.iOS.Views.MvxTabBarViewController.set_ViewModel (IMvxViewModel value) [0x00001] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:44
at MvvmCross.iOS.Views.MvxTabBarViewController`1[TViewModel].set_ViewModel (MvvmCross.iOS.Views.TViewModel value) [0x00001] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:68
at PROSPERI_EPMFast.iOS.Views.ProjectDetailsView.ViewDidLoad () [0x00016] in C:\Projetos Vinicius\PROSPERI_EPMFast\PROSPERI_EPMFast.iOS\Views\ProjectDetailsView.cs:22
at (wrapper managed-to-native) ObjCRuntime.Messaging:IntPtr_objc_msgSendSuper (intptr,intptr)
at UIKit.UITabBarController..ctor () [0x0003b] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/src/build/ios/native/UIKit/UITabBarController.g.cs:54
at MvvmCross.Platform.iOS.Views.MvxEventSourceTabBarController..ctor () [0x00000] in C:\vcs\git\MvvmCross\MvvmCross\Platform\iOS\Views\MvxEventSourceTabBarController.cs:20
at MvvmCross.iOS.Views.MvxTabBarViewController..ctor () [0x00000] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:20
at MvvmCross.iOS.Views.MvxTabBarViewController`1[TViewModel]..ctor () [0x00000] in C:\vcs\git\MvvmCross\MvvmCross\iOS\iOS\Views\MvxTabBarViewController.cs:56
at PROSPERI_EPMFast.iOS.Views.ProjectDetailsView..ctor () <0x1b486900 + 0x0002b> in <filename unknown>:0
at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:644
For the sake of completion: https://stackoverflow.com/a/30283563/6143949
I'm guessing here the problem here will be specific to the way that
TabBarViewController is constructed.
ViewDidLoad is a virtual method and it is called the first time the
View is accessed.
In the case of TabBarViewController this happens during the iOS base
View constructor - i.e. it occurs before the class itself has had its
constructor called.
The only way around this I've found is to add a check against the
situation in ViewDidLoad, and to make a second call to ViewDidLoad
during the class constructor.
You can see this in action N-25 -
https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/976ede3aafd3a7c6e06717ee48a9a45f08eedcd0/N-25-Tabbed/Tabbed.Touch/Views/FirstView.cs#L17
Something like:
public class MainView : MvxTabBarViewController
{
private bool _constructed;
public MainView()
{
_constructed = true;
// need this additional call to ViewDidLoad because UIkit creates the view before the C# hierarchy has been constructed
ViewDidLoad();
}
public override void ViewDidLoad()
{
if (!_constructed)
return;
base.ViewDidLoad();
var vm = (MainViewModel)this.ViewModel;
if (vm == null)
return;
}
}
Solution provided by Stuart (https://stackoverflow.com/users/373321/stuart)

Resources