Xamarin.Forms: PCL -> .Net Standard upgrade - xamarin.forms

I'm nearly done with my app. I'm using Xamarin.Forms (PCL project for the shared code). Is there any benefit of switching PCL into .Net Strandard? I have read some articles, but still not 100% sure whether are there any benefits of upgrading, e.g. security, performance or is't more like richer API mainly? Thanks for any thoughts.

There is no direct improvement in security or performance, but in time .NET Standard will replace PCLs. The PCL is not as cross-platform as Standard, so to make it truly cross-platform the switch to Standard is the smart thing to do.
Also, a lot of NuGet packages are already switching to support Standard, and you will not receive any upgrades for that code in your PCL library. So coming back to the security and performance part; if a bug is found in a NuGet package, you will not receive the update containing a fix because you're still on the 'older' PCL technology. This is a bit of a stretch, but if you want to be future-proof, the switch to .NET Standard is mandatory.
Right now we're in a bit of a pickle. You cannot reference a Standard from a PCL and vice versa (not 100% sure on all scenario's but I think you can't). So, right now you have to carefully check if all NuGets you are using, have a .NET Standard version already. If not, you're stuck on a PCL if you can't do it without the NuGet. The creator of the NuGet could supply a PCL and .NET Standard version in one NuGet, so then you can transition from one to the other. But see if that is true for all plugins you are using.
There is actually a good post on this by Adam Pedley here.

Actually, you can refer a PCL from .netstandard and vice versa, but it depends on netstandard version and PCL profile. Refer to this table to find out what is possible in your case.
To move from PCL to netstandard:
1. Replace *.csproj content with this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<PackageTargetFallback>$(PackageTargetFallback);portable45-net45+win81+wpa8</PackageTargetFallback>
<Copyright>Copyright © 2018</Copyright>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>
2. You can add PackageTargetFallback tag if you want add references to PCL libraries. Also you can edit the value you need. In the example above I use "portable45-net45+win81+wpa8" to add PCL(Profile111) in the netstandard1.1 library.
3. Use the netstandard version you need. Copy info from "AssemblyInfo.cs" to the project settings (Properties->Package) and remove it as you don't need it anymore.
4. Manually install back nuget packages from "packages.config" file and scan old *.csproj file for references to you projects. Add them as well. Then you can remove "packages.config" file as well.
I tried it on VS2017 15.7.5. I found that it's better to use netstandard1.1 and profile111 if you develop for Xamarin.Forms (Android + iOS). In this case, you can still use old .NETPortable nuget packages (even though they don't support netstandard yet).

Related

How to obfuscate a xamarin App on VS 2019

I need to protect the business logic on app and this is created with xamarin forms. I have searching information on forums and here about Babel and ConfuserEx but I don’t get it works.
Case Babel
I have installed demo SDK and I have updated the path on environment variables.
On Android Project I have added the following lines as I have seen on samples and book “Xamarin Mobile Development for Android Cookbook”
<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral, PublicKeyToken=138d17b5bd621ab7" />
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
<Babel InputFile="$(TargetPath)" OutputFile="$(TargetPath)"
VerboseLevel="5"
ObfuscateTypes="true"
ObfuscateEvents="true"
ObfuscateMethods="true"
ObfuscateProperties="true"
ObfuscateFields="true"
VirtualFunctions="true"
FlattenNamespaces="false"
UnicodeNormalization="false"
SuppressIldasm="true"
StringEncryption="xor"
ResourceEncryption="false"
ValueEncryption="false"
DynamicProxy="false"
ControlFlowObfuscation="goto=on"
ILIterations="5" />
</Target>
The compilation is good, but I see dll with ILSpy tool and I can see flow, methods, variables, etc…
Case ConfuserEx
I have installed the VS Extension of ConfuserEx and I have tried to actívate it on common Project and it is obfuscated but When I archive in order to generate the apk, it isn’t obfuscated.
I have tried to do on Android Project instead common Project, but it don’t work.
Could you give me some advice in order to obfuscate app? I want to do it with Android, iOS and UWP app.
Because by default, uwp, droid and ios is easy to do reversing engineering, no?
Because by default, uwp, droid and ios is easy to do reversing
engineering, no?
Assuming that this is the question, the answer is that you are mostly wrong.
AOT compiled assemblies are not easy to reverse engineer, and AOT is mandatory for UWP and iOS, while on Android partial AOT is enabled now by the default and full AOT can be enabled too on the VS Enterprise.
Speaking of that there is nothing that can't be reverse engineered and you can still add the obfuscation on the top of AOT compilation to make it even more tough, just there is no built-in solution (and as far as I know no free solution either) so it is yours to pick the one that you like, such recommendations are not allowed here.
I've been using Babel with my Xamarin.Android apps for the last 3 years. It works extremely well. If you are having problems contact Alberto at Babel. He provides really great support. Most problems are because of the fact that the Xamarin's build process can vary from release to release and therefore you Babel task can require modifications to accommodate those changes

Xamarin.iOS project: CS1703: Multiple assemblies with equivalent identity have been imported

I've got a cross platform (iOS and Android) Xamarin solution using .NET Standard 2.0. The solution is being built by Visual Studio 2017 (I've tried both the current and preview versions). The Forms and Android projects build fine. However, the iOS fails to build, with the following error:
1>CSC : error CS1703: Multiple assemblies with equivalent identity have been imported: 'C:\Users\newuser.nuget\packages\system.reflection.emit\4.3.0\ref\netstandard1.1\System.Reflection.Emit.dll' and 'C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\Xamarin.iOS\v1.0\Facades\System.Reflection.Emit.dll'. Remove one of the duplicate references.
I've tried many work arounds as described here:
oren.codes
www.hanselman.com
github.com/NuGet
Unfortunately none of these suggestions work. I have also tried to add the System.Reflection.Emit nuget package directly to the Forms and/or to the iOS projects directly. This doesn't work either. Note that originally, the The System.Reflection.Emit package wasn't referenced directly by anything in the solution. It is being pulled in by the following nuget packages which are being explicitly referenced:
Acr.DeviceInfo (5.0.5)
akavache (6.0.0-alpha0038)
AutoMapper (6.2.2)
Microsoft.Identity.Client (1.1.1-preview0040)
Newtonsoft.Json (10.0.3)
Finally, I have tried the update-package -reinstall command in the package console to reinstall all packages for the iOS project. This doesn't work either.
-- update
Just to make this clear, neither the Xamarin Forms or the Xamarin iOS project directly reference System.Reflection.Emit. That package is being pulled in as a dependency of other nuget packages, just from packages that are installed into the Xamarin Forms project. I have confirmed all of the dependencies that are referenced by Nuget, are using the same version. See these screenshots:
It seems to me that the problem (as the error says) is that there is an old version of System.Reflection.Emit that was installed by Visual Studio. However, I can't find a way of ignoring it and using the version of System.Reflection.Emit instead. As I've said above, I have tried to use a project.json file in the Xamarin.iOS project, and manually ignoring, but this doesn't work.
Does anyone else have any ideas?
As an aside, I notice that this bug is still open for Xamarin.
Xamarin Bugs
Managed to get this resolved thanks to an answer by #DirkWilhem on Xamarin Forums site.
Basically, add this to your Xamarin iOS project's .csproj file, with the other PackageReference nodes:
<PackageReference Include="System.Reflection.Emit">
<Version>4.3.0</Version>
<ExcludeAssets>all</ExcludeAssets>
</PackageReference>
Of course you need to make sure the nuget package has been added to the iOS package first.
Xamarin Forums discussion
After spending hours trying to resolve this myself I may have found a solution. Although it does feel wrong, it has got me past the issue.
Moving/Deleting the Xamarin.iOS version of System.Reflection.Emit.dll has solved the build problem for me and enabled me to deploy and run my app on a device. I don’t know what side effects it might have so will need more testing but I thought I’d share what’s worked for me so you can test it as well.
I was running on macOS Visual Studio 2017 but switched over to Windows to try and fix and first fixed on there then tried same approach on macOS and it worked as well.
On windows, go into the following directory and move the System.Reflection.Emit.dll somewhere else (you could just straight up delete it but I wanted to keep a copy I case this has some undesired effects down the track):
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\Xamarin.iOS\v1.0\Facades
On mac the following directory has it:
/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono/Xamarin.iOS/Facades
Like I say, it feels wrong but for now it’s got me past an issue that’s had me blocked for a couple of days so willing to just move on and hope there’s no side effects. I’d be interested to know your experience with it and if you come across anything else for the future too.
I’ll post this same comment on the Xamarin forums post (https://forums.xamarin.com/discussion/120814/xamarin-ios-project-cs1703-multiple-assemblies-with-equivalent-identity-have-been-imported) as well for future reference.
I had the same issue around a custom Nuget packages that we created and consumed in a separate project. We got around this issue by removing the automatic Nuget building checkbox in the "options" for the project. This does add the extra step of "Create Nuget Package" but one we pushed it to our Nuget repo and consumed it in our project, the errors vanished.
The problem showed up when we updated the sub-projects from PCLs to .netstandards (2.0).

Is Prism 6.3.0 tied to an older version of Unity (I can't seem to upgrade)

I've got a WPF App using the latest version of Prism for WPF (6.3.0) and Unity. Just a few modules. It works great.
When I manage NuGet packages for my solution, it tells me that there is a new version of Unity (5.4.0) available. Unfortunately, if I try to update to that version, I can no longer build.
It's pretty clear to see why: Upgrading unity via this method removes all references to it (Unity) from my project. Specifically the following 3 references completely disappear from all my projects without any replacement:
Microsoft.Practices.Unity
Microsoft.Practices.Unity.Configuration
Microsoft.Practices.Unity.RegistrationByConvention
(The Prism references remain, of course)
Error messages tell me that IUnityContainer is defined in an unreferenced assembly (Microsoft.Practices.Unity. 4.0.0.0). Given that it removed those assemblies, this all makes sense.
If I then try to go looking to add Unity back in, the Add Project Reference dialog cannot even find Microsoft.Practices.Unity when I search for it.
Now this isn't that big of a deal. I didn't need to upgrade. and it's easy for me to revert back. But I want to understand why this is failing for future reference.
Does this mean that Prism is tied to the older version of Unity and I just shouldn't upgrade?
Does this mean that types have moved to different namespaces and I need to make some other fix?
Some other reason?
Among the Unity 5 updates included a change of namespaces which as you noticed was a major breaking change. There are no plans for Prism 6 to support Unity 5, however the current Prism 7 previews (which is available for WPF) have updated both the Common Service Locator and Unity.
https://www.nuget.org/packages/Prism.Unity/7.0.0.336-pre

Satellite dll:s from Nuget not working when compiling with .NET Native tool chain

I have a Xamarin Forms PCL Project consuming a nuget package. The nuget package contains translated texts in satellite dll:s (xyz.resources.dll).
The translated texts shows up correctly in Android and iOS. They do also work for UWP when compiled with ".NET Native Tool Chain = false". However, if I DO check the ".NET Native Tool Chain" checkbox, the text is NOT translated. Only the resource from the "base-language" gets loaded.
I guess the .NET Native compilation somhow skips the satellite dll:s when trying to reduce the size of it's output.
Does anyone have a solution for this?
Problem solved (even if it might be considered a bug).
I have two nuget packages and one xamarin forms solution.
Nuget pkg A = only Resources (translations)
Nuget pkg B = PCL:s and stuff
Nuget Pkg B refers Nuget Pkg A in order to use some texts.
My xamarin solution refers both Nuget pkg A and B. Since my UWP Project in the xamarin solution needs a referens to pkg B, it somehow gets confused by B:s Connection to A.
If, however, I break the Connection between nuget pkg A and B it all works fine. (I know, messy answer, but if someone has a similiar problem, let me know, and I'll try to explain it in a better way...)

How to compile realm-cocoa with source code

Our company's svn cannot allow single file larger than 40mb, realm framework needs 140mb+,so how can I build realm-cocoa with source code on github?
You could instead use the dynamic framework, which is a lot smaller (28,5 MB), through being already linked, but you won't be able to support iOS 7 in that way.
Alternatively I would recommend using a dependency manager like CocoaPods, which helps you with the setup and integration. But as a Core Member of this project, I'm obviously biased in that regard.
If that shouldn't be available for you, then you could theoretically use SVN externals to checkout the realm-cocoa repo (GitHub supports SVN transports), add the Realm.xcodeproj to your Xcode project, set the iOS framework target as dependency target of your app target and link to Realm.framework. But please not that this is not an officially supported way of integration.

Resources