What is the exact difference between xamarin shared project and portable class library?
When to use shared library and when to use portable class library?
Is this possible to write native functionality in shared projects like showing alert,accessing camera and use it for both android and iOS?
Can anyone please explain me.
In shared projects each code file will be compiled for each destination (Android, iOS, Windows Phone etc). You are able to include platform specific code by using #if compiler directives.
When you want to access the camera you need to write the access code inside an #if block for all destinated platforms. This can mess up your code but it can be easier to find the different implementations.
Learn more: http://developer.xamarin.com/guides/cross-platform/application_fundamentals/shared_projects/
Protable Class Libraries (PCL) are compiled against a general .NET subset which is compatible to all platforms you want. So you can access System.Net.Http but you cannot access any platform specific code. If you want to access the camera inside the PCL code then you need to access it by a generalized interface via dependency injection. There are some pretty good frameworks helping you to archieve this goal. One of the most famous is MVVMCross (https://github.com/MvvmCross/MvvmCross/wiki). Learn more about PCL: http://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/sharing_code_options/#Portable_Class_Libraries
I personally perefer PCLs because the code is much easier to read without any compiler directives. Using MVVMCross you are able to use plenty of plugins via NuGet. So you don't need to write your own classes for camera access, showing alerts etc.
Related
How do your write Xamarin platform specific code in a .net standard library?
I want to use namespaces like Xamarin.Forms.Platform.iOS in a .Net Standard Library..
Use case: I want to develop a .net library for my apps which includes a video player for the various platforms. This video player also has to interact with other code in the .net library.
Or is the answer I need to use a shared project or portable library?
You should not include platform specific code or use namespaces like the one you mentioned in your .NET Standard Library, the reason is that .NET is just a runtime environment.
It’s not the the main runtime environment that you would use on iOS or Android. These platforms use Mono - not .NET. Check this or this to see more details for how its structured.
If you need to execute something from your .NET Standard project which is related to platform-specific behavior, use Dependency Injection or Custom Renderers.
When creating a new app in Xamarin Forms I see these two options:
Configure your Forms App
Shared Code:
Use .NET Standard
Use Shared Library
Can someone explain the difference? I looked at the help and I am still confused. I'd appreciate if someone can give me any advice on this. Not sure if it helps but this app is self contained and no code in the app will need to be shared with any other application.
In terms of what you can achieve with both, it is the same. So, in the end, it's mostly a matter of taste.
The biggest difference is that a shared project is compiled into the app itself. It is nothing more than it says on the tin: it's a shared folder that you can use in all platform projects. Using platform-specific code is done through compiler directives.
With a .NET Standard project, you will get a physical binary. It is a project of its own. You can reuse it in other .NET Standard projects, although you already mentioned you won't be using it for that. Executing platform-specific code requires a bit different approach, using the DependencyService.
Seeing that they made a choice to replace the PCL with .NET Standard but keep the shared project points out that the shared project is here to stay for a while. I tend to like the .NET Standard library more. It feels cleaner and forces you to write cleaner code. Also, .NET Standard isn't going anywhere soon and if you decide that code should be reused down the road, you have the ability to.
A good overview, together with pros and cons can be found in the Microsoft Docs: https://learn.microsoft.com/en-us/xamarin/cross-platform/app-fundamentals/code-sharing
I'm building a project that includes an MVC Web Api hosted in Azure and an iOS app. I'm trying to use Xamarin to build the app. As I understand it, I should use a portable class library in my Xamarin project to allow me to share the code between my Web Api project and the Xamarin app, as well as any future apps on other platforms like android.
So right off the bat I would want to put my models in the portable library. The app and the web api will pass those models back and forth. But the portable library doesn't have the Azure Table Storage library. It doesn't even have some very basic stuff. My models need to reference the Azure Storage Library so I can save instances to storage.
What is the best way to make this code shareable? Obviously I need to duplicate my model classes so they can exist in each location. But should those in the PCL inherit from those in the Web Api project? Vice versa? Should there be an interface that both inherit from (actually the Azure Table Storage library requires the classes to inherit from ITableEntity already...). Just looking for the best way to share these classes between the Web Api project and the PCL used by the Xamarin project.
Using a PCL - Portable Class Library is a great way to get started! There are a few quirks that you may want to understand prior to sharing your code.
The PCL Profile is a limited set of APIs available. Meaning that certain classes/assemblies might not be included. You can typically look up the class/assembly via MSDN and see if it has a PCL icon next to the class name.
If the library you are trying to use has assemblies not inside the current PCL Profile but can be found on the native platforms, you will want to use the IoC/DI pattern.
Hopefully the library you're using supports PCL. Otherwise, you will need a library that does support the PCL Profile. (You can check this by downloading the .nupkg, extracting, and looking at the libs folder). Note: You may want to check the Prerelease NuGet channel for PCL support. Sometimes you can find an open source project and remove/replace certain assemblies/code to make it Portable.
General Guidelines:
Keep your POCO classes simple in the PCL. If you have platform specific quirks you need to add to the models, make a Model layer on that platform that inherits from your simple PCL models. EX: Your Web API has a specific [Attribute] tag or interface that you need to apply to your model. You might already have a Model such as Person which is a simple POCO class in your PCL, and then you can create a PersonApiEntity model which might inherit Person and any platform-specific APIs you need to apply to it.
It seems ITableEntity/TableEntity is not supported in the PCL Profile.
https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.table.itableentity.aspx
Seeing the source at a quick glance(https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Table/ITableEntity.cs)
Just wanted to understand there are couple of code sharing strategies exist to achieve code reusable capability in Xamarin.
Which one should i use ?
Shared Project way OR Portable Class Library way ?
if you can explain with scenarios , it would be very helpful for me.
Thanks much.
Here is the Xamarin explanation.
The question is possibly duplicated but you ask specifically for scenarios.
If you ever wrote c cross platform projects, shared projects resemble the old-school way allowing you to use #if __IOS__ statements to run device platform code in your shared/common code files. A separate assembly is created for each target (say iOS or Android). They give advantages and disadvantages of each.
PCL generates one single assembly for the common code. PCL has some limited number .net features as shown here in this table. However, most of the important .net goodies are there as you can see.
Xamarin says that shared code method is easier but PCL is easier to compile a module and share or sell that with others.
When I make projects, I check what external plugins/components/ etc I want to use and make a decision based from. For example, you may want to use sqlite and there are different options for using shared and PCL projects.
I am starting to develop a scientific software that I hope I will be able to run on multiple platforms. My plan is to use OpenTK for the rendering of the scientific models and plots. As of the moment I have a prototype that runs on Windows using OpenTK 1.1 libraries from http://www.opentk.com/ (a simpler version just with OpenTK and a more complicated one with OpenTK + WindwosForms). I am trying to port that prototype to Android.
It seems that the syntax using by the Xamarin.Android OpenTK library is nearly identical to the one that I am currently using for Windows (with the only difference that OpenGL -> OpenGL ES and GameWindow -> AndroidGameView) so the porting shouldn't be an issue. However, I was hoping that I could avoid a copy-paste method and get a more permanent solution having a shared OpenTK code between the Windows and the Android version.
I have read trough the Xamarin documentation about the shared vs PCL methods for cross-platform development. However, I still struggle to figure out how to set-up a Visual Studio solution with an Android and Windows project and a shared code that will include OpenTK. Is that even possible and can someone give me an example of how to do it? I did explore an example I found for rendering a rotating cube using OpenTK for a shared Android/iOS project (http://developer.xamarin.com/content/TexturedCubeES30/) but in my case I need to use a different OpenTK library for the Windows and for the Android project.
I also found this Do the Android and iOS versions of OpenTK have the same API? discussion. It is very similar to what I would like to do but in my case I am trying to setup a project for Windows and Android (for now).
Can I use only one OpenTK library (which one?) that is being called from both the Android and the Windows project and what will be the right way to set-up both projects so they share the same OpenTK code. This is the first time I am dealing with writing a cross-platform code so I am a bit lost.
Edit: I was able to get a prototype running using Shared Xamarin project and compiler flags as proposed below. Code was indeed not very pretty at places but I got over 70% code re-usability between the two platforms so it was worth the effort. This is how I used the compiler flags in case someone is looking for the same thing (credit to SKall from the Xamarin forums):
#if __ANDROID__
using OpenTK.Graphics.ES11;
#else
using OpenTK.Graphics.OpenGL;
#endif
I used the #if syntax similarly where there were small differences between the syntax of the routines.
It does not seem like OpenTK has its logic inside of a PCL in the first place, so your plans on putting it there are going to get hard to achieve.
However, if you split out your code, such that most of it is contained in classes, which are not highly dependent on the underlying platform, you will be able to create a Class Library Project for each platform and link your files between the platform specific projects. Inside of the classes it contains you will use #if definitions to choose whether to use AndroidGameView or GameWindow and the same goes for other platform specific types. It will make the code ugly, but this is the alternative to PCL.
You could try to see how much of the OpenTK code compiles inside of a PCL and inject the platform specific stuff at runtime, but it will require considerably more work from you. However, it will make the code a lot more cleaner to look at.
To ease the file linking, you could make one of those Shared Projects and chuck in all of the logic in there.
Some more info about code sharing here: http://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/sharing_code_options/
Dependency injection: https://en.wikipedia.org/wiki/Dependency_injection