Calling Device.RuntimePlatform causes runtime exception
Asked Answered
C

4

8

I updated my Xamarin.Forms package to the latest (2.3.4.224) in all my projects (platform+shared) and it seems now I shouldn't use anymore Device.OS nor TargetPlatform enum as they are deprecated.

The compiler is complaining because of these lines:

if (Device.OS == TargetPlatform.iOS) 
    _API_BASE_URI = "http://XXX.XXX.XXX.XXX"; 
else
    _API_BASE_URI = "http://YYY.YYY.YYY.YYY"; 

It say's:

"Device.OS is obsolete. Use RuntimePlatform instead"

So far so good, now I want to fix that and I've been trying using:

Debug.WriteLine(Device.RuntimePlatform);

But it's throwing a runtime exception. Here's the stacktrace

04-08 14:57:34.812 I/MonoDroid( 3782): UNHANDLED EXCEPTION: 04-08 14:57:34.824 I/MonoDroid( 3782): System.TypeInitializationException: The type initializer for 'Mob.ApiCommunication' threw an exception. ---> System.MissingMethodException: Method 'Xamarin.Forms.Device.get_RuntimePlatform' not found. 04-08 14:57:34.824 I/MonoDroid( 3782): --- End of inner exception stack trace --- 04-08 14:57:34.824 I/MonoDroid( 3782): at (wrapper managed-to-native) System.Object:__icall_wrapper_mono_generic_class_init (intptr) 04-08 14:57:34.824 I/MonoDroid( 3782): at Mob.Views.Public.LoginViewModel.RestoreState (System.Collections.Generic.IDictionary`2[TKey,TValue] dictionary) [0x00001] in C:\Users...\Source...\LoginViewModel.cs:52 04-08 14:57:34.824 I/MonoDroid( 3782): at Mob.App.OnStart () [0x00001] in C:\Users...\App.xaml.cs:39 04-08 14:57:34.824 I/MonoDroid( 3782): at Xamarin.Forms.Application.SendStart () [0x00000] in C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Core\Application.cs:228 04-08 14:57:34.824 I/MonoDroid( 3782): at Xamarin.Forms.Platform.Android.FormsAppCompatActivity+d__43.MoveNext () [0x0003b] in C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\AppCompat\FormsAppCompatActivity.cs:426 04-08 14:57:34.824 I/MonoDroid( 3782): --- End of stack trace from previous location where exception was thrown --- 04-08 14:57:34.824 I/MonoDroid( 3782): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 04-08 14:57:34.824 I/MonoDroid( 3782): at System.Runtime.CompilerServices.AsyncMethodBuilderCore.m__0 (System.Object state) [0x00000] in /Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1018 04-08 14:57:34.824 I/MonoDroid( 3782): at Android.App.SyncContext+c__AnonStorey0.<>m__0 () [0x00000] in /Users/builder/data/lanes/4468/b16fb820/source/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:35 04-08 14:57:34.824 I/MonoDroid( 3782): at Java.Lang.Thread+RunnableImplementor.Run () [0x0000b] in /Users/builder/data/lanes/4468/b16fb820/source/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36 04-08 14:57:34.824 I/MonoDroid( 3782): at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00009] in /Users/builder/data/lanes/4468/b16fb820/source/monodroid/src/Mono.Android/platforms/android-25/src/generated/Java.Lang.IRunnable.cs:81 04-08 14:57:34.824 I/MonoDroid( 3782): at (wrapper dynamic-method) System.Object:88db5e57-5ac7-4ba4-a574-4ec5eaf704fd (intptr,intptr)

Am I missing something with the use of RuntimePlatform? I've looked around, but currently any documentation/sample regarding the Device class is using the deprecated members.

Comedic answered 8/4, 2017 at 13:24 Comment(6)
just to note, I currently get the same so it's not your config. Nothing in the release notes to suggest this change either. I'm going to stick with the Device.Os as it does still work as of writing thisKerakerala
The following is working for me just fine using Xamarin Forms version 2.3.4.224: bool isAndroid = Device.RuntimePlatform == Device.Android; Also here is unofficial documentation: https://github.com/xamarin/Xamarin.Forms/pull/658Exhibition
@hvaughan3: Unfortunatly it's still the same.Burt
Are you sure that your Android project is using the same version of Xamarin Forms as your shared/PCL project? Do you get the same error when you run the iOS project?Exhibition
Yes I am sure! And yes same error on both iOS and Android!Burt
@AppPack: check my answer. You might want to give it a try!Burt
C
5

I came out with a solution. What is strange is that before posting on SO, I've already done that for my Xamarin projects and it didn't have any effect. But this time, after reading this thread on Xamarin forums: https://forums.xamarin.com/discussion/92455/xamarin-forms-2-3-4-224 that's what I did:

I've closed VisualStudio, cleaned all "bin" & "obj" folders from all projects in my solution, then restarted VS and then cleaned & rebuilt solution.

Now Debug.WriteLine(Device.RuntimePlatform); returns the "Android" string as expected!,

Comedic answered 9/4, 2017 at 11:53 Comment(3)
It is always this clean project thing. why cant they automate it, unbelievableSemitropical
Nice, glad you found it. I wrote myself a powershell script to delete all obj and bin subfolders within a given directory. Have to use it quite a bit.Exhibition
I do not know why it is obsolete. So weird. Enums are better than magic strings!!!Desiredesirea
M
5

Xamarin.Forms-2.3.4.224 has changed the condition checking from:

if (Device.OS == TargetPlatform.iOS) 
{

}

To:

if (Device.RuntimePlatform.Equals("Android"))
{
    Debug.WriteLine($"Onplatform: {Device.RuntimePlatform}");
}
else if (Device.RuntimePlatform.Equals("iOS"))
{
    Debug.WriteLine($"Onplatform: {Device.RuntimePlatform}");
}
Monotony answered 12/4, 2017 at 13:18 Comment(1)
if(Device.RuntimePlatform == Device.iOS) { //iOS stuff } else if(Device.RuntimePlatform == Device.Android) { }Countrified
H
0

hvaughan3's comment on the OP is what did it for me. Make sure that not only your PCL but also your Android/iOS/etc projects have their packages updated as well. Then do a full clean and build from there following OP's accepted answer.

Helvetian answered 8/5, 2017 at 18:34 Comment(0)
S
0

I use the following without any issues

if(Device.RuntimePlatform.Equals("Android")){
  //YOUR CODE
}else if(Device.RuntimePlatform.Equals("iOS")){
  //YOUR CODE
}

Looks like the VS standard clean turn it off and on again answer is the solution though...

Schaeffer answered 30/4, 2018 at 13:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.