I've been 2 years with Xamarin Environment and mostly I used Xamarin.Forms. But yet, I have no idea what Xamarin Cross Platform is? Can anyone provide some structural differences?
When we talk about Xamarin there are two approaches in development of native apps:
Traditional Xamarin approach
Xamarin.Forms
There is a good quote from Xamarin web site
Share code everywhere. Use the same language, APIs and data structures
to share an average of 75% of app code across all mobile development
platforms. Build user interfaces with Xamarin.Forms and share nearly
100%.
Important note is that these numbers can vary from project to project so this is some assumption for general usage of Xamarin.
And as you can see from the image below about "differences" between these two approaches. Traditional Xamarin approach (Xamarin.iOS and Xamarin.Android) they’re both built on top of Mono, an open-source version of the .NET Framework. To develop those apps you use C# and there is an opportunity to share up to 75% of the codebase as you can see on the image bellow and from a quote from Xamarin.
Using Xamarin Traditional approach you can use a C# as a programming language to write your models, call web services, etc. So you are writing that code logic once and using/share it across the Xamarin.Android and Xamarin.iOS projects, and in those separate projects you are writing code that is specific for that platform and you have access to their APIs.
Also, there is a quote from Xamarin about the traditional approach:
Anything you can do in Objective-C, Swift, or Java can be done in C#
with Xamarin using Visual Studio.
And project structure with Xamarin traditional looks like this:
Shared code project: Codebase that is common and reusable for your other projects.
Xamarin.Android: Project for your Android app where you are writing code using Android-specific APIs, writing your UI code, etc.
Xamarin.iOS: Project for your iOS app where you are writing code
using iOS specific APIs, writing your UI code, etc.
More info about Xamarin traditional here.
Now about Xamarin.Forms, the best definition is quoted from the Xamarin website:
Xamarin.Forms is a framework that allows developers to rapidly create
cross-platform user interfaces. It provides it's own abstraction for
the user interface that will be rendered using native controls on iOS,
Android, Windows, or Windows Phone. This means that applications can
share a large portion of their user interface code and still retain
the native look and feel of the target platform.
As you can conclude from the text above, Xamarin.Forms is a framework that allows you to write your UI using C# or with XAML with the opportunity to use MVVM... With Xamarin.Forms you can write your codebase and your UI which will be shared across the platforms.
Note: this is a very simple project structure, of course, you can add more project for different layers
Shared code project: Holds your common code base and also because you are using Xamarin.Forms you can write code for your UI
Xamarin.iOS and Xamarin.Android: Code for that specific platform, and some advanced topics such as Custom renderers and Dependency services.
Of course, there is some of the limitations if you are using Xamarin.Forms for example out of the box you can only use UI controls that are common across all platforms. You can read my blog post about Xamarin.Forms pros and cons here.
More info about Xamarin.Forms here.
I hope that this answer is not confusing for you and as a conclusion in one or two sentences... Using Xamarin Traditional you can share your code logic between platform-specific projects, and using Xamarin.Forms you can share code logic and also code for UI across your projects.
Note: For shared project and code sharing strategy you can use "Shared Project" and "PCL" this is a topic for another question... so in this answer, I was simplifying this and use shared project term for that type of project in Xamarin app solution.
UPDATE, Summer of 2020:
.NET Maui is announced in May of 2020, the question about the difference between MAUI and Xamarin.Forms could be found in the StackOverflow thread here: What is MAUI? and what are differences between MAUI and Xamarin
If you're talking about the Xamarin.iOS and Xamarin.Android (Xamarin Native), I'd say the main difference is that in Xamarin Forms, you share NOT ONLY the business logic, but also the UI. In Xamarin forms, you'll use basic components on all platforms (Button, Label, etc). That's the reason why it's called Xamarin.Forms, because it's suitable for basic forms.
But for Xamarin Native, you'll create a UI per platform (One for iOS, one for Android). You can do much more with Xamarin Native, because you'll use native components.
Hope it helps!
Xamarin has two ways of building mobile applications, Xamarin.Forms and Xamarin.Native.
Both ways let you write code cross platform.
Cross platform is just a concept. It means the code you write once can run in multiple platforms. Xamarin is cross platform (mainly Xamarin.Forms) because it allows you to write code that runs on multiple (across) platforms.
I think Xamarin Cross Platform refers to the technology that compiles shared code (your PCL or Shared Project) such that it can be used by the different platforms such as Xamarin.Android or Xamarin.IOS before finally being compiled to the native platforms.
So I'd say in a way Xamarin.Forms is one of the tools you use to build cross platform compatible code that can then be put together using the Xamarin Cross Platform Technology, makes sense?
Related
I've recently started learning about Xamarin so please bear with me. I'm not sure if this is an obvious question
Creating a cross-platform mobile app in VS2017 will create 3 projects: Xamarin.Forms, iOS, Android.
So in my Xamarin.Forms project I was able to add a map to my Form, and now I can see the map in my Android emulator. That works great. I havent't touched the other two projects.
Now I have to add some functionality that's native of each platform, so I would need to go, for example, to the Android project to add the widgets, logic, etc.
Is C# used in these native projects or do I need to learn a new language?
I'm asking because Android Studio uses java and iOS uses Objective C, so I'm not sure if I need to learn these languages for cha
If you check the Microsoft website for Xamarin.Forms it answers your question then and there;
Xamarin.Forms expose a complete cross-platform UI toolkit for .NET developers. Build fully-native Android, iOS, and Universal Windows Platform apps using C# in Visual Studio.
But even F# is available as an option.
As far as your platform-specific question goes there is a whole separate guide that teaches you how and when you need platform specific code which can be found here
Is C# used in these native projects or do I need to learn a new language?
I'm asking because Android Studio uses java and iOS uses Objective C, so I'm not sure if I need to learn these languages.
Yes, that is the whole point for the Xamarin native and Xamarin.Forms framework that pure C#/F# developers can become mobile application developers without learning a new language.So existing .Net teams can execute mobile projects.
But in some cases, you might have to convert native Java and Objective-C code to C# so it's always better if you have a basic level of understanding in them.
I will suggest you read the Code Sharing Strategies available in Xamarin Forms before deciding which method do you wanna follow: I personally and the Community prefers using The .Net Standard methodology to share the code you can choose for yourself.
Good luck with your future endeavours and feel free to revert in case of further queries.
Yes, all Xamarin projects use C# (or F#). You do not need to use java or Obj-C/Swift, although there are ways to incorporate native libraries written in those languages into Xamarin projects.
Xamarin has a entire section of docs on how to incorporate platform specific behavior into a Xamarin Forms app.
I'm creating an app in which, the login will be handled using auth0. But due to the available Auth0 NuGet packages, I had to create separate login pages for android and iOS. So in the app.xaml.cs class, I now have to reference Login_iOS for case Device.iOS: MainPage = new Login_iOS(); but I am met with an error, as xamarin cannot find the class Login_iOS. I'm pretty sure that this is because I haven't referenced it correctly, and I can't seem to find a way to reference it correctly. The screenshots below should help me explain my situation.
Using an IoC (Inversion of Control) is one way to go as pointed out by Shawn, but understand that IoC is a name for one method of calling into platform specific code from a platform agnostic library project like a .NET Standard project. You have to decide on what IoC library to use, or whether to use IoC functionality that is built into some cross-platform frameworks like MvvmCross or even Xamarin.Forms Dependency Service (which is not a true IoC container but more of a service locator, but it does work to allow you to call platform specific code from a .NET Standard or PCL library project, which is ultimately what you want to do).
That said, there is another option for your core Xamarin.Forms code and that is to use a Shared Library project type. .NET Standard is by far the more common and the option that is suggested when you follow the getting started docs for Xamarin.Forms (and Xamarin.Forms != Xamarin see (1) below) You can select this when you create your Xamarin.Forms solution:
With a Shared library project type for your core Xamarin.Forms code, you will have access to everything that is referenced in your platform specific projects so you will access to everything that you have access to in the Xamarin.iOS and Xamarin.Android projects directly. No IoC or Dependency services are necessary.
There has always been much debate on whether using a Shared Library project or a .NET Standard project is the best way to go. There are pros and cons to each. In a nutshell using a .NET Standard project forces you to use IoC to call platform specific code from the library project, and use custom renderers to access platform specific properties of UI controls, whereas a Shared Library project give you full access to all the classes and libraries that are available to the platform specific project, making Dependency Injection unnecessary... BUT when using a Shared project, since you can have both Xamarin.Android specific and Xamarin.iOS specific code in the same Shared project, you need to use compiler directives (#if and #endif) so that iOS specific code is only compiled when building the iOS project and Android specific code is only compiled when compiling the Android project. Not doing so can cause compile and/or runtime issues. Here is a simple piece of code to show you how to use the compiler directives to isolate iOS and Android specific code. This simple sample will create a button that when tapped will present an Alert. How to present an Alert is different between iOS and Android so we need to isolate those bits of code in the button click event handler so the correct code runs on the correct platform.
First define the compiler symbols in the Project Options. Right click on the Android project and select Project Options and select Compiler on the left. Then in the Define Symbols field, add ANDROID;, e.g.:
Then do the same for the iOS project (but entering IOS obviously):
It is worth noting that this is a configuration dependent setting, so you need to add these symbols for all of the configurations that you will use to build your projects.
Next create the button in MainPage.xaml:
<Button Text="Show me an alert!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Clicked="Handle_Clicked" />
Then in the MainPage.xaml.cs code behind file:
void Handle_Clicked(object sender, System.EventArgs e)
{
#if ANDROID
Toast.MakeText(MainActivity.Context, "I'm an Android Toast!", ToastLength.Long).Show();
#endif
#if IOS
var alert = new UIAlertView("I'm an iOS Alert!", "I'm deprecated. but using here because I do not have easy access to my view controller at this time", null, "OK", null);
alert.Show();
#endif
}
You will also need the compiler directives around the using statements:
#if ANDROID
using Android.Widget;
using SharedSample.Droid;
#endif
#if IOS
using UIKit;
#endif
So hopefully now you better understand how to make cross platform apps and some of the challenges around sharing code and using platform specific code. All that said, you still will not be able to add a native iOS page (or native Android page) to your Xamarin.Forms MainPage property since the iOS page is NOT a Xamarin.Form page (MainPage can only accept a subclass of a Xamarin.Forms Page), but this should show you how to call platform specific code from your shared code.
Oh, now I see in your screenshots that you added your Xamarin.Forms XAML page to the iOS project???? No, that is not the way around your issue. I would seriously suggest you sign up for Xamarin University. You need more than just code snippets, you need to better understand cross-platform development and my not-so-brief primer here is not nearly enough to get you going from what I can see.
BUt you know what, I think there is a OAuth library for Xamarin Forms, so maybe you can make that work as it should do all the platform specific stuff for you.
Nuget page: https://www.nuget.org/packages/Xamarin.Auth/
Github page: https://github.com/xamarin/Xamarin.Auth
Docs: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/oauth
Good luck!
(1) Xamarin was a company that was purchased by Microsoft. Xamarin made SDKs that allowed making apps for iOS, Mac, and Android using C# and the .NET framework. Xamarin.iOS SDK is used for making iOS apps, Xamarin.Mac for Mac apps, and Xamarin.Android for Android apps. All use Mono which is an open source port of .NET (since .NET only ran on Windows and other Microsoft platforms at the time... though there is now .NET Core that is cross-platform... but that is another topic).
Later Xamarin introduced Xamarin.Forms which is a cross-platform UI (User Interface) library that allows creating the UI in common code and/or XAML. Prior to Xamarin.Forms, the UI for each platform had to be created in the platform specific projects, i.e. the UI for iOS would be in Xamarin.iOS project, UI for Android would be in Xamarin.Android project, etc., but all could call into back end code (i.e. web requests, models, etc.) that resides in one shared library project, allowing about 80% of the total code to be shared between the different platform app projects. With Xamarin.Forms, for a simple app, 100% code sharing is possible. Xamarin.Forms does still use Xamarin.iOS and Xamarin.Android projects, as well as UWP projects on Windows, to kick off the UI, but Xamarin.Forms uses renderers to render the Xamarin.Forms UI Controls into platform specific controls, i.e. a Button in Xam.Forms renders to a UIButton on iOS and an Android Button on Android. However Xamarin.Forms only gives you access to core common properties of the native controls, so if you need to access specific native properties or features, you have to use a custom renderer (to modify UI controls on the native platform and have access to native control's properties) and/or dependency service (to run platform specific code from the core Xam.Forms library project).
Your base project cannot reference the platform specific project. If you could do that, you would be back in the boat of using platform specific libraries on the wrong platform.
Instead, you need to create a class or interface in your base project that each of your platform specific projects can extend. This way, you can pass that base class between projects without needing to know about any of the platform specific libraries that are being used.
I would recommend an IoC (Inversion of Control) pattern for this situation. It abstracts the reference handling for you and simplifies the registration of your various services. Take a look at this article which is solving the exact same type of situation.
I hope this helps!
My understanding is the compiler directives in a Share Access Project (SAP) make use of platform specific code.
For SAP Xamarin has,
Application projects can include platform-specific references that the
shared code can utilize (such as using Community.CsharpSqlite.WP7 in
the Tasky sample for Windows Phone).
https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/sharing_code_options/#Shared_Projects
I didn't see anything on this page for PCL about not writing platform specific code. If I include the Xamarin Android library in the PCL, is that not specific code that would be in a SAP?
Does it mean that I could tweak or have some feature on Android and Windows Phone that I couldn't on iOS (maybe iOS didn't support it?)
EDIT: What does it look like to access the camera, for example, from PCL via DI, vs accessing the camera in a SAP (platform doesn't matter; Android is fine.)
To be clear, I follow the MVVM pattern, and I want to structure my project such that I can share my model code between a UWP app and a standard WPF app. The code I want to share has no UI. I don't relish the thought of finding new tools to replace the ones that I've been using for years that take care of certain tasks like logging, connecting to a document oriented database, etc.
I attempted to start writing a UWP wrapper around some code I already have and reference the model project directly. Visual Studio refused to let that happen, showing me an error message that says "Unable to add a reference to project 'ACK.Model'". The same thing happened when I attempted to put the model in a Universal Library and reference it from a WPF app. I'm not trying to share WPF code. Just the model layer that has no reference to UI libraries.
This is a scary proposition, because it means that if I want to do anything substantial I have to choose to either jump 100% to UWP or stay 100% WPF. NewtonSoft.JSON might have a universal distribution (ASP.NET MVC), but what about ElasticSearch.NET, and other tools needed to make important apps?
I found where the "Portable Class Library" project type was hiding. PCLs will allow me to share my code across WPF and Universal apps as that was one of the options. This solves the simple case of the Model part of my code, but I (still) can't use some of the libraries I want. There are still a large number of libraries that I need that do not have PCL available.
About a year later, with the advent of Visual Studio 2017 there is a more complete solution. If you target your libraries to .Net Standard then the library is compatible with both .Net Core apps and the monolithic .Net targeted app. The support for standard .Net libraries and APIs is fairly complete, as is the support for modern C# language features.
The general advice now is this:
Target .Net Standard for all libraries
Target the appropriate platform for your actual application. (UWP or WPF).
NOTE: if your library has to interact with C libraries or applications, you have to take extra care to make sure you load the correct version.
It appears that there is a solution, but it has to be adopted by the whole tool chain you want to use. When Microsoft introduced Windows Store apps in Windows 8, they also introduced a Portable Class Library (PCL). The purpose of the PCL is to share code between different parts of your application.
When you create a PCL in Visual Studio 2015, you can specify the types of APIs you want it to be accessible from:
Universal Apps
Mono
.Net Core 5
.Net 4.6
This of course, limits the APIs available to you but most of the ones you want to use are OK as long as it's not UI related. There are other limitations as well:
Your project can only be edited in Visual Studio 2015 or greater
You don't have access to special directories from the Environment variable (i.e. user Documents directory, etc.)
You can't link to a library designed for only one of your target platforms (i.e. libgit2sharp, etc.)
There's no way to browse the API for this subset--MSDN needs to get on the stick. MSDN has updated much of the API documentation, but it's still difficult to figure out what applies to your PCL
However, you can link any library designed for a single target platform to your PCL. It's not ideal, but it's better than nothing.
The ASP.NET MVC stack has been ported to using PCLs, so you can use NewtonSoft.JSON directly as well as any other of those libraries used by that application. However, there are several libraries that have not been ported.
This arrangement forces you to think about how you want to integrate better. The .Net Core 5 seems to be stable, but support is in it's infancy. The current generation of Universal Apps as of VS 2015 update 1 uses .Net Core 5 directly.
There are several features from Nuget that are not currently supported even though work is under way:
MS Build extensions (major changes to MSBuild and the project.json structure)
Install/uninstall scripts (related to the removal of the concept of install)
Content (related to install/uninstall, but work is in progress on this)
Content transforms (related to lack of install/uninstall)
I wish I had a more complete answer. But this is as far as I got once I discovered the PCL and how it evolved for the current infrastructure.
I'm in the process of creating a game creation toolkit that incorporates version control right off the bat. I want to be able to deploy a game as a Windows 10 app, or as a standard WPF app, but due to the libraries I'm using to integrate version control I need to create the editor as a standard WPF app. I had to be a bit creative in building the shared code and importing the correct libraries.
First, my project hierarchy:
Project.Model (Portable Class Library)
Project.Model.Versioning (standard C# library)
Mvvm.Toolkit (Portable Class Library)
Editor (Standard WPF application)
I want the core PCL to be able to load a project and deserialize the JSON encoded objects. The PCL did have access to System.IO, but surprisingly it is not the same as the one defined in the standard C# library. Here's how I had to fix things:
After adding the package reference to NewtonSoft.JSON, I had to change the target framework in the packages.config file:
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="portable-net452+win81" />
All projects dependent on my Project.Model class had to install the `system.io.filesystem' package from nuget so that the System.IO.FileInfo etc. objects were the same.
While this is definitely not a panacea, it's also not a dead end. I'm sure there are more gotchas, but this will at least help with some of the problems.
a .NET Standard library could be used to share a Model-View-ViewModel architecture between a WPF project and a UWP project.
https://www.syncfusion.com/ebooks/xamarin-forms-succinctly/sharing-code-among-platforms
https://devblogs.microsoft.com/dotnet/announcing-uwp-support-for-net-standard-2-0/
I heard about Mono project but only in regards to winforms. Will it work with WPF?
WPF under Mono does not exist.
At this point, no group in the Mono project has plans to implement Windows Presentation Foundation APIs as part of the project.
The mono team propose using Silverlight/Moonlight instead:
Silverlight implement a subset of the WPF APIs and is available on Windows, MacOS X and through our own open source effort Moonlight it is available on Linux and other Unix systems.
There is a library called Silverform SDK that aims to provide cross-platform WPF and Silverlight implementation.
The library is implemented in managed code and currently works with OpenTK and Unity3D as render backends. Major functionality, such as binding, layout, main controls and primitives, has already been implemented (check Unity web player demos here). Initially it has been focused on Unity3d render, while support for standalone Mono applications will be added as a separate build in the future.
Disclaimer: I am one of the developers of the library.