Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xamarin Forms iOS System.PlatformNotSupportedException: Operation is not supported on this platform. #156

Closed
ChrisJAult opened this issue Jul 30, 2019 · 36 comments
Assignees
Labels
bug Something isn't working enhancement New feature or request

Comments

@ChrisJAult
Copy link

After upgrading to 4 from 3 registrations fail on iOS with System.PlatformNotSupportedException: Operation is not supported on this platform.

container.RegisterMany(new[] { typeof(CoreRegistry).GetTypeInfo().Assembly },
type => type.IsAssignableTo< IMenuProvider >(),
ifAlreadyRegistered: IfAlreadyRegistered.AppendNewImplementation);

I tried using .WithoutFastExpressionCompiler(); because JIT is not supported on iOS but the registration still threw the exception.

Version with issue: 4
Last known good version: 3
Xamarin.Forms version: 3.6.0.344457
IDE: Visual Studio 2019 Enterprise
@dadhi
Copy link
Owner

dadhi commented Jul 30, 2019

What is the exception message and stacktrace in both cases?

@ChrisJAult
Copy link
Author

The exception is {System.PlatformNotSupportedException: Operation is not supported on this platform.

This is the stack trace produced

at System.Reflection.Emit.DynamicMethod..ctor (System.String name, System.Type returnType, System.Type[] parameterTypes, System.Type owner, System.Boolean skipVisibility) [0x00006] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.14.0.110/src/Xamarin.iOS/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.notsupported.cs:64 at FastExpressionCompiler.LightExpression.ExpressionCompiler.TryCompile (FastExpressionCompiler.LightExpression.ExpressionCompiler+ClosureInfo& closureInfo, System.Type delegateType, System.Type[] paramTypes, System.Type returnType, FastExpressionCompiler.LightExpression.Expression expr, System.Collections.Generic.IReadOnlyList1[T] paramExprs, System.Boolean isNestedLambda) [0x00086] in <030e4f7b0206410ba41a3c4edd8cfe41>:0
at FastExpressionCompiler.LightExpression.ExpressionCompiler.TryCompile[TDelegate] (FastExpressionCompiler.LightExpression.Expression bodyExpr, System.Collections.Generic.IReadOnlyList1[T] paramExprs, System.Type[] paramTypes, System.Type returnType) [0x0000a] in <030e4f7b0206410ba41a3c4edd8cfe41>:0 at FastExpressionCompiler.LightExpression.ExpressionCompiler.CompileFast[T1,R] (FastExpressionCompiler.LightExpression.Expression1[TDelegate] lambdaExpr, System.Boolean ifFastFailedReturnNull) [0x00000] in <030e4f7b0206410ba41a3c4edd8cfe41>:0
at DryIoc.Portable.GetAssemblyTypesMethod () [0x000af] in <030e4f7b0206410ba41a3c4edd8cfe41>:0
at System.Lazy1[T].ViaFactory (System.Threading.LazyThreadSafetyMode mode) [0x00043] in <4b124141b7914f4d8253001e6b8a15cf>:0 at System.Lazy1[T].ExecutionAndPublication (System.LazyHelper executionAndPublication, System.Boolean useDefaultConstructor) [0x00022] in <4b124141b7914f4d8253001e6b8a15cf>:0
at System.Lazy1[T].CreateValue () [0x00074] in <4b124141b7914f4d8253001e6b8a15cf>:0 at System.Lazy1[T].get_Value () [0x0000a] in <4b124141b7914f4d8253001e6b8a15cf>:0
at DryIoc.Portable.GetAssemblyTypes (System.Reflection.Assembly a) [0x00000] in <030e4f7b0206410ba41a3c4edd8cfe41>:0
at DryIoc.Registrator.GetImplementationTypes (System.Reflection.Assembly assembly) [0x00000] in <030e4f7b0206410ba41a3c4edd8cfe41>:0
at System.Linq.Enumerable+SelectManySingleSelectorIterator2[TSource,TResult].MoveNext () [0x00051] in <7c9d4d4f135d40b59732b673b488f4c5>:0 at DryIoc.Registrator.RegisterMany (DryIoc.IRegistrator registrator, System.Collections.Generic.IEnumerable1[T] implTypes, System.Func2[T,TResult] getServiceTypes, System.Func2[T,TResult] getImplFactory, System.Func3[T1,T2,TResult] getServiceKey, System.Nullable1[T] ifAlreadyRegistered) [0x0007d] in <030e4f7b0206410ba41a3c4edd8cfe41>:0
at DryIoc.Registrator.RegisterMany (DryIoc.IRegistrator registrator, System.Collections.Generic.IEnumerable1[T] implTypes, DryIoc.IReuse reuse, DryIoc.Made made, DryIoc.Setup setup, System.Nullable1[T] ifAlreadyRegistered, System.Func2[T,TResult] serviceTypeCondition, System.Boolean nonPublicServiceTypes, System.Object serviceKey) [0x00034] in <030e4f7b0206410ba41a3c4edd8cfe41>:0 at DryIoc.Registrator.RegisterMany (DryIoc.IRegistrator registrator, System.Collections.Generic.IEnumerable1[T] implTypeAssemblies, System.Func2[T,TResult] serviceTypeCondition, DryIoc.IReuse reuse, DryIoc.Made made, DryIoc.Setup setup, System.Nullable1[T] ifAlreadyRegistered, System.Boolean nonPublicServiceTypes, System.Object serviceKey) [0x0001d] in <030e4f7b0206410ba41a3c4edd8cfe41>:0
at River.Bed.Mobile.Core.Ioc.CoreRegistry.Load (Prism.Ioc.IContainerRegistry containerRegistry) [0x00108] in E:\Repositories\River.Bed.Mobile\Mobile\River.Bed.Mobile\Core\Ioc\CoreRegistry.cs:39
at River.Bed.Mobile.App.RegisterCoreTypes (Prism.Ioc.IContainerRegistry containerRegistry) [0x00001] in E:\Repositories\River.Bed.Mobile\Mobile\River.Bed.Mobile\App.xaml.cs:137
at River.Bed.Mobile.Client.ClientApp.RegisterCoreTypes (Prism.Ioc.IContainerRegistry containerRegistry) [0x00001] in E:\Repositories\River.Bed.Mobile\Clients\RiverBlue\River.Bed.Mobile.Client\ClientApp.cs:33
at River.Bed.Mobile.App.RegisterTypes (Prism.Ioc.IContainerRegistry containerRegistry) [0x00001] in E:\Repositories\River.Bed.Mobile\Mobile\River.Bed.Mobile\App.xaml.cs:131
at Prism.PrismApplicationBase.Initialize () [0x0002f] in d:\a\1\s\Source\Xamarin\Prism.Forms\PrismApplicationBase.cs:133
at Prism.PrismApplicationBase.InitializeInternal () [0x00006] in d:\a\1\s\Source\Xamarin\Prism.Forms\PrismApplicationBase.cs:84
at Prism.PrismApplicationBase..ctor (Prism.IPlatformInitializer platformInitializer, System.Boolean setFormsDependencyResolver) [0x00038] in d:\a\1\s\Source\Xamarin\Prism.Forms\PrismApplicationBase.cs:75
at Prism.PrismApplicationBase..ctor (Prism.IPlatformInitializer platformInitializer) [0x00000] in d:\a\1\s\Source\Xamarin\Prism.Forms\PrismApplicationBase.cs:57
at Prism.DryIoc.PrismApplication..ctor (Prism.IPlatformInitializer platformInitializer) [0x00000] in d:\a\1\s\Source\Xamarin\Prism.DryIoc.Forms\PrismApplication.cs:34
at River.Bed.Mobile.App..ctor (Prism.IPlatformInitializer initializer) [0x00000] in E:\Repositories\River.Bed.Mobile\Mobile\River.Bed.Mobile\App.xaml.cs:52
at River.Bed.Mobile.Client.ClientApp..ctor (Prism.IPlatformInitializer initializer) [0x00000] in E:\Repositories\River.Bed.Mobile\Clients\RiverBlue\River.Bed.Mobile.Client\ClientApp.cs:20
at River.Bed.Mobile.Client.iOS.AppDelegate.FinishedLaunching (UIKit.UIApplication app, Foundation.NSDictionary options) [0x0009b] in E:\Repositories\River.Bed.Mobile\Clients\RiverBlue\River.Bed.Mobile.Client.iOS\AppDelegate.cs:74
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/12.14.0.110/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/12.14.0.110/src/Xamarin.iOS/UIKit/UIApplication.cs:65
at River.Bed.Mobile.Client.iOS.Application.Main (System.String[] args) [0x00001] in E:\Repositories\River.Bed.Mobile\Clients\RiverBlue\River.Bed.Mobile.Client.iOS\Main.cs:17 `

@dadhi
Copy link
Owner

dadhi commented Jul 30, 2019

Thank you,
It will be fixed with #90 / I hope to roll out it soon.

@ChrisJAult
Copy link
Author

Great, thanks :)

@dadhi
Copy link
Owner

dadhi commented Aug 21, 2019

The v4.1.0-preview-01 is out with Rules.WithUseInterpretation() option.
Try it out for iOS target.

@dadhi dadhi self-assigned this Aug 22, 2019
@dadhi dadhi added bug Something isn't working enhancement New feature or request labels Aug 22, 2019
@dadhi dadhi added this to the v4.1.0 milestone Aug 22, 2019
@xleon
Copy link

xleon commented Sep 16, 2019

I had the same issue and the latest preview version fixed it, along with Rules.WithUseInterpretation()

@dadhi
Copy link
Owner

dadhi commented Sep 16, 2019

@xleon ,

Thanks, good news.

@nukefusion
Copy link

This isn't fixed. On iOS on version 4.2 of the package, RegisterMany will just not work, even with .WithUseInterpretation and .WithoutFastExpressionCompiler.

@dadhi dadhi reopened this May 21, 2020
@dadhi
Copy link
Owner

dadhi commented May 21, 2020

@nukefusion

This isn't fixed. On iOS on version 4.2 of the package, RegisterMany will just not work, even with .WithUseInterpretation

Could provide a small reproduction sample?

@MilKAOS
Copy link

MilKAOS commented Jun 5, 2020

Because we have the same issue I made you a small test project.
The solution is based on the standard Xamarin.Forms Master-Detail template for Android+iOS.
I only added DryIoc via the DryIoc.Microsoft.DependencyInjection package (DryIoc version is 4.1.4
then) and the initialization of DryIoc with a not so meaningful registration.

The program will run on the Android emulator but not on the iOS simulator with the above mentioned error.
In our case we are currently still using a much older version of DryIoc to avoid the issue with iOS.

DryIocTest.zip

P.S. I forgot to add WithUseInterpretation() and WithoutFastExpressionCompiler() in code - but like mentioned before by nukefusion it doesn't change the issue.

@dadhi
Copy link
Owner

dadhi commented Jun 5, 2020

@MilKAOS Thanks for the sample. Will look.

@dadhi dadhi modified the milestones: v4.1.0, v4.2.1 Jun 5, 2020
@dadhi
Copy link
Owner

dadhi commented Jun 8, 2020

@MilKAOS

image

I don't have a Mac, so do we have any other workaround to debug the sample?

@dadhi
Copy link
Owner

dadhi commented Jun 8, 2020

@MilKAOS Nevermind seems like I have found the problem. The problem is GetAssemblyTypes() is being called from RegisterMany is using dynamic ILEmit compilation for all platforms. The fix is in progress...

Btw, it also means that the current workaround is avoiding RegisterMany.

@MilKAOS
Copy link

MilKAOS commented Jun 8, 2020

@dadhi Unfortunately building for iOS needs the hardware. But I am glad that you (probably) found the issue!

dadhi added a commit that referenced this issue Jun 8, 2020
@dadhi dadhi closed this as completed in afe9942 Jun 8, 2020
@dadhi
Copy link
Owner

dadhi commented Jun 8, 2020

DryIoc v4.2.1 is released with the bug-fix

@MilKAOS
Copy link

MilKAOS commented Jun 9, 2020

Just to add to the fix as tip for all who might read the issue in the future:
For our apps it works with v4.2.1 for iOS but I had additionally to use WithUseInterpretation. deactivate the FastExpressionCompiler.

@dadhi
Copy link
Owner

dadhi commented Jun 9, 2020

@MilKAOS So WithUseInterpretation was not enough? If so, it is bad, I need to look further...

@MilKAOS
Copy link

MilKAOS commented Jun 9, 2020

@dadhi Sorry, my bad. WithUseInterpretation works too and then you don't need the FastExpressionCompiler deactivation.

@dadhi
Copy link
Owner

dadhi commented Jun 9, 2020

That's cool to hear,
because WithoutFEC is a rather complex and quirky feature to support..
Interpretation on the other hand is much more general and handy thing overall. So in V5 WithoutFEC will be Obsolete, then it will be removed later.

@dadhi
Copy link
Owner

dadhi commented Jun 9, 2020

@MilKAOS I also wanted to ask is there any feature toggle either in runtime or compile-time #ifdef to find out the platform you are on?
I mean how to conditionally add .WithUseInterpretation for the iOS only?

I need this to be able to answer the questions and probably to put it somewhere in docs.

@MilKAOS
Copy link

MilKAOS commented Jun 9, 2020

Xamarin.iOS should have __IOS__ for conditional compilation but personally I never used it.
Conditional Compilation

In our apps we are using Device.RuntimePlatform from Xamarin.Forms.
RuntimePlatform

@dadhi
Copy link
Owner

dadhi commented Jun 9, 2020

Thanks!

@OmidID
Copy link

OmidID commented Nov 12, 2020

@dadhi You could have Mac as virtual machine for test
https://techsprobe.com/install-macos-big-sur-on-virtualbox-on-windows-pc/

@dadhi
Copy link
Owner

dadhi commented Nov 12, 2020

@OmidID Hi, thanks for the link.

For the issue itself - is it something not working for you yet?

@OmidID
Copy link

OmidID commented Nov 12, 2020

Yes. Same problem. On my side work only without fast compiler.
Maybe you could do some test with a virtual machine

@dadhi
Copy link
Owner

dadhi commented Nov 12, 2020

@OmidID What DryIoc version do you use?

@dadhi dadhi reopened this Nov 12, 2020
@OmidID
Copy link

OmidID commented Nov 12, 2020

@dadhi The version I use is 4.5.1
I have another crash without any log!!!! so i found to changed one of the services from transient to scope and solved.
The interesting part it was try-catch couldn't catch it !!! I try to step into and then I reached to https://github.com/dadhi/DryIoc/blob/master/src/DryIoc/Container.cs#L551 and the app close without any error or log or anything. I never saw something similar before.

@dadhi dadhi removed this from the v4.2.1 milestone Nov 12, 2020
@dadhi
Copy link
Owner

dadhi commented Nov 12, 2020

@OmidID

Did it crash with or WithoutFastExpressionCompiler?
And did you use WithUseInterpretation() or not?

@OmidID
Copy link

OmidID commented Nov 13, 2020

Yes with WithoutFastExpressionCompiler and not WithUseInterpretation

            _container = new DryIoc.Container(rules =>
                rules.WithTrackingDisposableTransients()
                     .WithoutFastExpressionCompiler());

@dadhi
Copy link
Owner

dadhi commented Nov 13, 2020

@OmidID Try to add the interpretation too, because otherwise you are using System Compile and it may not work on the platform.

@OmidID
Copy link

OmidID commented Nov 13, 2020

I imagine this is should be done for iOS only. Right? for Android do I need the same options?

@dadhi
Copy link
Owner

dadhi commented Nov 13, 2020

@OmidID
For iOS only. Try to use the default settings for Android.

I am very curious how is the FastExpressionCompiler relates to the problem, because WithUseInterperation don't assume the compilation.
The only thing I can imagine (except the bug) that the compilation used as a fallback when interpretation is failing, hmm...

I need probably to disable the fallback bacause it does not help when interpretation is the only option, and throw the relevant exception to make the problem visible.

@xleon
Copy link

xleon commented Feb 15, 2021

I'm considering to introduce DryIoC on a big Xamarin project soon.
RegisterMany would be awesome to get rid of some nasty factories we have at the moment.
Is there any more progress on this issue?

Can I help with testing any iOS related stuff?

@dadhi
Copy link
Owner

dadhi commented Feb 15, 2021

@xleon I think that generally everything works, just keep in mind to set WithUseInterpretation() rule for iOS.

This issue is open to think and decide on should the interpretation have the compilation fallback or just fail. And this a thing only if you are using custom ExpressionFactory with the exotic expression not supported by the DryIoc interpreter.

My current choice is probably let it fail, because this is likely the indication of the client setup problem. Hiding it will produce more pain than profit.

@OmidID
Copy link

OmidID commented Feb 15, 2021

@xleon FYI: we are using DryIoc in a big project. After migration, we have better performance and lower memory usage.

Using Scope over (ViewController(iOS), Activity(Android), Page(XF))

@xleon
Copy link

xleon commented Feb 16, 2021

@dadhi @OmidID I will give it a try. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants