Xamarin

Xamarin

Xamarin is an open source app platform from Microsoft for building modern & performant iOS and Android apps with C# and .NET.

Flutter vs React Native vs Xamarin for Cross Platform Development

Cross-platform app development framCross-platform app development frameworks such of Flutter, React Native, and Xamarin are well-known and popular.

It might be difficult for users to pick the best platform out of all of them.

In this post, we will compare Flutter, React Native, and Xamarin to help you decide which platform to utilise for your next cross-platform app development project.

https://multiqos.com/flutter-vs-react-native-vs-xamarin-whats-best-in-2022/

#flutter #reactnative #xamarin #fluttervsreactnative #fluttervsxamrin #reactnativevsflutter #reactnativevsxamrin #xamarinvsflutter #xamarinvsreactnative #appdevelopment #appdeveloper

Flutter vs React Native vs Xamarin for Cross Platform Development
坂本  健一

坂本 健一

1651145763

Flurlテスト可能なHttpClientを簡単に使用

Flurlは、.net用の最新のポータブルなテスト可能な流暢な流暢なHttpclientライブラリです。商用利用もオープンソースです。.net、.netコア、Xamarine、UWPなどのさまざまなプラットフォームをサポートします。

URLを呼び出して.netで応答を取得する方法はたくさんありますが、そのうちのいくつかは、

  1. .Net独自のHttpClientを使用する
  2. RestSharpの使用
  3. Flurlの使用

この記事では、コードを比較することにより、これら3つのライブラリをどのように使用できるかを見ていきます。

まず、HttpCleintとRestSharps RestClientを見てから、flurlについて詳しく見ていきましょう。

バンガロールの天気を取得するために単純なオープンウェザーAPIを呼び出して、使用法を比較するサンプルコードを作成しました。完全なコードはここから入手できます。


サンプルが機能しない場合、APIキーがすでにブロックされている場合は、APIキーを置き換える必要があります。

HttpClient

private const string BaseUrl = "https://community-open-weather-map.p.rapidapi.com";
private const string ResourcePath = "/forecast/daily?q=bengaluru%2CIN&lat=35&lon=139&cnt=10&units=metric%20or%20imperial";
private const string XRapidapiHost = "X-RapidAPI-Host";
private const string XRapidapiKey = "X-RapidAPI-Key";
private const string XRapidapiHostValue = "community-open-weather-map.p.rapidapi.com";
var client = new HttpClient();
var request = new HttpRequestMessage {
    Method = HttpMethod.Get,
        RequestUri = new Uri(BaseUrl + ResourcePath),
        Headers = {
            {
                XRapidapiHost,
                XRapidapiHostValue
            },
            {
                XRapidapiKey,
                XRapidapiKeyValue
            },
        },
};
using(var response = client.Send(request)) {
    response.EnsureSuccessStatusCode();
    var body = response.Content.ReadAsStringAsync().Result;
    Console.WriteLine(body);
}

C#

ここでわかるように、ヘッダーを使用して単純なURLを呼び出すには、上記の複雑なコードが必要です。また、クライアントをテストするには、複雑なラッパーを作成する必要があります。ただし、それでも、コードに外部ライブラリの依存関係が必要なく、URL呼び出しがほとんど行われない場合は、これを選択することをお勧めします。

もう1つの人気のあるクライアントは、ポータブルで非同期であり、シリアル化と逆シリアル化をサポートし、さまざまな認証方法もサポートします。

private const string BaseUrl = "https://community-open-weather-map.p.rapidapi.com";
private const string ResourcePath =
    "/forecast/daily?q=bengaluru%2CIN&lat=35&lon=139&cnt=10&units=metric%20or%20imperial";
private const string XRapidapiHost = "X-RapidAPI-Host";
private const string XRapidapiKey = "X-RapidAPI-Key";
private const string XRapidapiHostValue = "community-open-weather-map.p.rapidapi.com";
var client = new RestClient(BaseUrl);
var request = new RestRequest(ResourcePath);
request.AddHeader(XRapidapiHost, XRapidapiHostValue);
request.AddHeader(XRapidapiKey, XRapidapiKeyValue);
var response = client.ExecuteGetAsync<string>(request).Result;
Console.WriteLine();
Console.Write(response.Content);

C#

ご覧のとおり、呼び出しは大幅に簡素化され、結果の逆シリアル化もサポートされています。このrestclientをテストするには、それをラップしてコードに渡すか、MockHttpMessageHandlerを使用する必要があります。

Fluent Urlの短縮形であるFlurlは、.NET用の最新の流暢で非同期のテスト可能なポータブルURLビルダーおよびHTTPクライアントライブラリです。FlurlはNuGetで利用でき、商用利用は無料です。.NET Framework、.NET Core、Xamarin、UWPなどのさまざまなプラットフォームで実行されます

private const string BaseUrl = "https://community-open-weather-map.p.rapidapi.com";
private const string ResourcePath =
    "/forecast/daily?q=bengaluru%2CIN&lat=35&lon=139&cnt=10&units=metric%20or%20imperial";
private const string XRapidapiHost = "X-RapidAPI-Host";
private const string XRapidapiKey = "X-RapidAPI-Key";
private const string XRapidapiHostValue = "community-open-weather-map.p.rapidapi.com";
Console.WriteLine((BaseUrl + ResourcePath).WithHeader(XRapidapiHost, XRapidapiHostValue)
    .WithHeader(XRapidapiKey, XRapidapiKeyValue).GetStringAsync().Result);

C#

ご覧のとおり、すべてのコードは、天気APIを呼び出して結果を出力するために、サンプルから1行のコードに簡略化されています。要求を構成するための流暢な形式をサポートし、応答の逆シリアル化もサポートします。したがって、URL呼び出しは1行に削減されます。

多くの場合、URL呼び出しは以下のように1行に短縮されます

var poco = await "http://api.foo.com".GetJsonAsync<T>();
string text = await "http://site.com/readme.txt".GetStringAsync();
byte[] bytes = await "http://site.com/image.jpg".GetBytesAsync();
Stream stream = await "http://site.com/music.mp3".GetStreamAsync();

C#

妥当性

Flurl.Httpは、分離されたアレンジ-アクト-アサートスタイルのテストを非常に簡単にする一連のテスト機能を提供します。

private HttpTest _httpTest;
[SetUp]
public void CreateHttpTest() {
    _httpTest = new HttpTest();
}
[TearDown]
public void DisposeHttpTest() {
    _httpTest.Dispose();
}
[Test]
public void Test_Some_Http_Calling_Method() {
    // Flurl is in test mode
}
httpTest
    .RespondWith("some response body")
    .RespondWithJson(someObject)
    .RespondWith("error!", 500);
sut.DoThingThatMakesSeveralHttpCalls();

C#

舞台裏では、各RespondWith*がスレッドセーフキューに偽の応答を追加します。

httpTest
    .ForCallsTo("*.api.com*", "*.test-api.com*") // multiple allowed, wildcard supported
    .WithVerb("put", "PATCH") // or HttpMethod.Put, HttpMethod.Patch
    .WithQueryParam("x", "a*") // value optional, wildcard supported
    .WithQueryParams(new { y = 2, z = 3 })
    .WithAnyQueryParam("a", "b", "c")
    .WithoutQueryParam("d")
    .WithHeader("h1", "f*o") // value optional, wildcard supported
    .WithoutHeader("h2")
    .WithRequestBody("*something*") // wildcard supported
    .WithRequestJson(new { a = "*", b = "hi" }) // wildcard supported in sting values
    .With(call => true) // check anything on the FlurlCall
    .Without(call => false) // check anything on the FlurlCall
    .RespondWith("all conditions met!", 200);

C#

テストが作成され、特定の応答がキューに入れられたら、テスト対象を呼び出すだけです。SUBがFlurlを使用してHTTP呼び出しを行うと、実際の呼び出しは効果的にブロックされ、代わりに次の偽の応答がキューから取り出されて返されます。ただし、キューに1つの応答のみが残っている場合(提供されている場合は、それ以降の基準に一致)、その応答は「スティッキー」になります。つまり、キューから取り出されないため、後続のすべての呼び出しで返されます。これを機能させるために、Flurlオブジェクトをモックまたはスタブする必要はありません。HttpTestは、論理非同期呼び出しコンテキストを使用して、SUBを介してシグナルを送信し、Flurlに呼び出しを偽造するよう通知します。

また、アサーションもサポートしています。

httpTest.ShouldHaveCalled("http://some-api.com/*")
    .WithQueryParam("x", "1*")
    .WithVerb(HttpMethod.Post)
    .WithContentType("application/json")
    .WithoutHeader("my-header-*")
    .WithRequestBody("{\"a\":*,\"b\":*}")
    .Times(3);

C#

結論

Flurlは最新の流暢なベースのHTTPクライアントであり、簡単にテストできます。さらに重要なことは、商用およびオープンソースを無料で使用できることです。これにより、最新の.netプログラミングの非常に魅力的な候補になります。

ソース:https ://www.c-sharpcorner.com/article/easily-use-flurl-testable-httpclient/

#http  #flurl #dotnet #xamarin 

Flurlテスト可能なHttpClientを簡単に使用
Samuel Tucker

Samuel Tucker

1651030453

Mobile Development Tutorial: Native vs Cross-Platform

Native vs Cross-Platform

Lately mobile developers have had to answer this question the most: Shall we go native or use a cross-platform framework? And if so, which one?
Sebastiano Poggi, team lead at Jetbrains, and Carl-Gustaf Harroch, founder/managing director at Novoda, explore current best practices around modern mobile development highlighting the impact of team collaboration and matching technologies across platforms.

TIMECODES
00:00 Intro
00:44 Native vs cross-platform
04:14 How organizational dysfunction impacts app platform choices
08:38 Does full-stack include mobile?
19:15 Matching technologies across mobile and web
22:37 Team collaboration across platforms
27:54 Measuring cross-platform success
31:50 What is cross-platform development?
40:26 Hot trends in mobile development
44:35 Outro

Read the full transcription of this interview here:
https://gotopia.tech/articles/expert-talk-native-vs-cross-platform-mobile-apps

#mobiledevelopment #xamarin #reactnative #dart #flutter #swift #kotlin 

Mobile Development Tutorial: Native vs Cross-Platform

Los Efectos Destacados Disponibles En Xamarin Community Toolkit

En esta publicación, veremos los efectos destacados disponibles en Xamarin Community Toolkit y cómo usarlos. Esta publicación es parte de Xamarin Community Toolkit - Tutorial Series , visite la publicación para obtener información sobre Xamarin Community Toolkit. El kit de herramientas de la comunidad de Xamarin es una colección de elementos reutilizables para el desarrollo móvil con Xamarin.Forms, que incluye animaciones, comportamientos, convertidores, efectos y ayudantes. Simplifica y demuestra las tareas comunes de los desarrolladores al crear aplicaciones para iOS, Android, macOS, WPF y Universal Windows Platform (UWP) con Xamarin.Forms. 

Parte de codificación

Pasos

  1. Paso 1: creación de nuevos proyectos de Xamarin.Forms.
  2. Paso 2: configurar el kit de herramientas de la comunidad de Xamarin en Xamarin.Forms .Net Standard Project.
  3. Paso 3: Implementación de efectos usando Xamarin Community Toolkit.

Paso 1: creación de nuevos proyectos de Xamarin.Forms

Cree un nuevo proyecto seleccionando Nuevo proyecto à Seleccione Xamarin Cross Platform App y haga clic en Aceptar.

Nota: la versión de Xamarin.Forms debe ser superior a 5.0.

Luego, seleccione las plataformas Android e iOS como se muestra a continuación con la estrategia de uso compartido de código como PCL o .Net Standard y haga clic en Aceptar.

Paso 2: Configuración del escáner en Xamarin.Forms .Net Standard Project

En este paso, veremos cómo configurar el complemento.

  • Abra Nuget Manager en Visual Studio Solution haciendo clic derecho en la solución y seleccione "Administrar paquetes Nuget".
     

  • Luego seleccione "Xamarin Community Toolkit" y verifique todos los proyectos en la solución, instale el

    complemento

Paso 3: Implementación de efectos usando Xamarin Community Toolkit.

En este paso, veremos cómo implementar los efectos destacados que se ofrecen en Xamarin Community Toolkit. Aquí, hemos explicado la implementación de Safe Area Effect, Shadow Effect, Life Cycle Effect y StatusBar Effect.

  • Abra su archivo de diseño XAML y agregue el siguiente espacio de nombres para utilizar las vistas en la pantalla.
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"

C#

efecto de área segura

  • SafeAreaEffect es un efecto que se puede agregar a cualquier elemento a través de una propiedad adjunta para indicar si ese elemento debe tener en cuenta las áreas seguras actuales o no.
  • Esta es un área de la pantalla que es segura para todos los dispositivos que usan iOS 11 y superior.

Específicamente, ayudará a asegurarse de que las esquinas redondeadas del dispositivo, el indicador de inicio o la carcasa del sensor en un iPhone X no recorten el contenido. El efecto solo se dirige a iOS, lo que significa que en otras plataformas no hace nada.

Propiedades

<StackLayout xct:SafeAreaEffect.SafeArea="True" BackgroundColor="White"> </StackLayout>

C#

Area segura

Indica qué áreas seguras se deben tener en cuenta para este elemento

Antes de aplicar el efecto

Después de aplicar el efecto

efecto de sombra

Se usa para tener un efecto de sombra para las vistas de Xamarin Forms y tenemos cinco propiedades que deben entenderse para usar este efecto.

Propiedades

  1. Color: Es el color que tendrá la sombra.
  2. Opacidad: Con esta propiedad puedes controlar la opacidad que quieres en la sombra.
  3. Radio: Es responsable de manejar el desenfoque en la sombra.
  4. OffsetX/OffsetY: Nos permite definir el desplazamiento que tendrá la sombra, por lo tanto OffsetX se encarga de especificar la distancia del desplazamiento horizontal, mientras que OffsetY del desplazamiento vertical.

En este ejemplo, actualicé el efecto de sombra para el control de imagen como en el siguiente bloque de código

<Image
	x:Name="img"
	HeightRequest="150"
	Margin="10"
	xct:ShadowEffect.Color="Green"
	xct:ShadowEffect.OffsetY="15"
	Source="https://shorturl.at/qsvJ1">
</Image>

C#

Efecto del ciclo de vida

LifecycleEffect le permite determinar cuándo la plataforma asigna su renderizador a VisualElement. Se puede identificar mediante los controladores de eventos LifeCycleEffect.

<Image
	x:Name="img"
	HeightRequest="150"
	Margin="10"
	Source="https://shorturl.at/qsvJ1">
	<Image.Effects>
		<xct:LifecycleEffect Loaded="LifeCycleEffect_Loaded" Unloaded="LifeCycleEffect_Unloaded" />
	</Image.Effects>
</Image>

C#

private void LifeCycleEffect_Loaded(object sender, EventArgs e)
{
	Console.WriteLine("Image loaded...");
}

private void LifeCycleEffect_Unloaded(object sender, EventArgs e)
{
	Console.WriteLine("Image Unloaded...");
}

C#

Efecto de la barra de estado

  • Este efecto se usa para controlar el color de la barra de estado en la aplicación Xamarin Forms durante el tiempo de compilación o el tiempo de ejecución o los clics de botones similares. Es un código de una sola línea para ser útil para controlar.

En este ejemplo, crearemos un recurso de color en el archivo App.xaml como se muestra a continuación. Se actualizará más adelante de forma dinámica.

<Color x:Key="StatusBarColor">Firebrick</Color>

C#

Luego agregue la siguiente línea en el elemento raíz de su página XAML como DynamicResource

xct:StatusBarEffect.Color="{DynamicResource StatusBarColor}"

C#

Luego agregue los 3 botones como en la pantalla de muestra y actualice el color de su recurso dinámico al hacer clic en el botón como se muestra a continuación.

private void ButtonClicked(object sender, EventArgs e)
{
	Application.Current.Resources["StatusBarColor"] = ((Button)sender).TextColor;
}

C#

Código completo

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkit.EffectsSamplePage"
             xct:StatusBarEffect.Color="{DynamicResource StatusBarColor}">
    <ContentPage.Content>
        <StackLayout xct:SafeAreaEffect.SafeArea="True"
                     BackgroundColor="White">

            <Frame BackgroundColor="#2196F3"
                   Padding="24"
                   CornerRadius="0">
                <Label Text="Xamarin Forms Effects using XCT"
                       HorizontalTextAlignment="Center"
                       TextColor="White"
                       FontSize="36"/>
            </Frame>

            <Image
                x:Name="img"
                HeightRequest="150"
                Margin="10"
                xct:ShadowEffect.Color="Green"
                xct:ShadowEffect.OffsetY="15"
                Source="https://shorturl.at/qsvJ1">
                <Image.Effects>
                    <xct:LifecycleEffect Loaded="LifeCycleEffect_Loaded" Unloaded="LifeCycleEffect_Unloaded" />
                </Image.Effects>
            </Image>
            <Grid Padding="10">
                <Button Clicked="ButtonClicked" Text="Red" TextColor="Red" BorderColor="Red" BorderWidth="2" Grid.Column="0"/>
                <Button Clicked="ButtonClicked" Text="Green" TextColor="Green" BorderColor="Green" BorderWidth="2" Grid.Column="1"/>
                <Button Clicked="ButtonClicked" Text="Blue" TextColor="Blue" BorderColor="Blue" BorderWidth="2" Grid.Column="2"/>
            </Grid>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

C#

El XCT también ofrece otros tipos de efectos. Visite el siguiente enlace para obtener más ejemplos. https://github.com/xamarin/XamarinCommunityToolkit/tree/main/samples/XCT.Sample/Pages/Effects

Descargar Código

Puedes descargar el código desde GitHub. Si tienes dudas, no dudes en publicar un comentario. Si te gusta este artículo y te resulta útil, haz clic en Me gusta, comparte el artículo y destaca el repositorio en GitHub.

 Fuente: https://www.c-sharpcorner.com/article/xamarin-community-toolkit-effects/

#xamarin #community #toolkit #effective 

Los Efectos Destacados Disponibles En Xamarin Community Toolkit
高橋  花子

高橋 花子

1650410160

XamarinCommunityToolkitで利用可能な注目のエフェクト

この投稿では、XamarinCommunityToolkitで利用できる機能とその使用方法について説明します。この投稿はXamarinCommunityToolkit-Tutorial Seriesの一部です。投稿にアクセスして、XamarinCommunityToolkitについて知ってください。Xamarin Community Toolkitは、アニメーション、動作、コンバーター、エフェクト、ヘルパーなど、Xamarin.Formsを使用したモバイル開発用の再利用可能な要素のコレクションです。Xamarin.Formsを使用してiOS、Android、macOS、WPF、およびユニバーサルWindowsプラットフォーム(UWP)アプリを構築する際の一般的な開発者タスクを簡素化し、デモンストレーションします。 

コーディング部

手順

  1. ステップ1:新しいXamarin.Formsプロジェクトを作成します。
  2. ステップ2:Xamarin.Forms .NetStandardProjectでXamarinCommunityToolkitをセットアップします。
  3. ステップ3:XamarinCommunityToolkitを使用したエフェクトの実装。

ステップ1:新しいXamarin.Formsプロジェクトを作成する

[新しいプロジェクト]を選択して新しいプロジェクトを作成する[XamarinCrossPlatform App]を選択し、[OK]をクリックします。

注: Xamarin.Formsのバージョンは5.0より大きくする必要があります。

次に、以下に示すように、PCLまたは.Net Standardとしてコード共有戦略を使用してAndroidおよびiOSプラットフォームを選択し、[OK]をクリックします。

手順2:Xamarin.Forms .NetStandardProjectでスキャナーを設定する

このステップでは、プラグインのセットアップ方法を説明します。

  • ソリューションを右クリックして[Nugetパッケージの管理]を選択し、VisualStudioソリューションでNugetManagerを開きます。
     

  • 次に、「Xamarin Community Toolkit」を選択し、ソリューション内のすべてのプロジェクトを確認して、

    プラグイン

ステップ3:XamarinCommunityToolkitを使用したエフェクトの実装。

このステップでは、XamarinCommunityToolkitで提供される注目のエフェクトを実装する方法を説明します。ここでは、セーフエリア効果、シャドウ効果、ライフサイクル効果、ステータスバー効果の実装について説明しました。

  • XAMLデザインファイルを開き、次の名前空間を追加して、画面上のビューを利用します。
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"

C#

SafeAreaEffect

  • SafeAreaEffectは、アタッチされたプロパティを介して任意の要素に追加できる効果であり、その要素が現在の安全領域を考慮に入れる必要があるかどうかを示します。
  • これは、iOS11以降を使用するすべてのデバイスにとって安全な画面の領域です。

具体的には、コンテンツが丸みを帯びたデバイスの角、ホームインジケーター、またはiPhone Xのセンサーハウジングによってクリップされないようにするのに役立ちます。この効果はiOSのみを対象とします。つまり、他のプラットフォームでは何もしません。

プロパティ

<StackLayout xct:SafeAreaEffect.SafeArea="True" BackgroundColor="White"> </StackLayout>

C#

安全地帯

この要素で考慮すべき安全な領域を示します

効果を適用する前に

効果を適用した後

ShadowEffect

これは、Xamarinフォームビューのシャドウ効果を持たせるために使用されます。この効果を使用するには、理解する必要のある5つのプロパティがあります。

プロパティ

  1. 色:それは影が持つ色です。
  2. 不透明度:このプロパティを使用すると、シャドウで必要な不透明度を制御できます。
  3. 半径:影のぼやけを処理する責任があります。
  4. OffsetX / OffsetY:シャドウが持つ変位を定義できるため、OffsetXは水平方向の変位の距離を指定し、OffsetYは垂直方向の変位を指定します。

この例では、次のコードブロックのように、画像コントロールのシャドウ効果を更新しました。

<Image
	x:Name="img"
	HeightRequest="150"
	Margin="10"
	xct:ShadowEffect.Color="Green"
	xct:ShadowEffect.OffsetY="15"
	Source="https://shorturl.at/qsvJ1">
</Image>

C#

ライフサイクル効果

LifecycleEffectを使用すると、VisualElementのレンダラーがプラットフォームによって割り当てられるタイミングを決定できます。これは、LifeCycleEffectイベントハンドラーを使用して識別できます。

<Image
	x:Name="img"
	HeightRequest="150"
	Margin="10"
	Source="https://shorturl.at/qsvJ1">
	<Image.Effects>
		<xct:LifecycleEffect Loaded="LifeCycleEffect_Loaded" Unloaded="LifeCycleEffect_Unloaded" />
	</Image.Effects>
</Image>

C#

private void LifeCycleEffect_Loaded(object sender, EventArgs e)
{
	Console.WriteLine("Image loaded...");
}

private void LifeCycleEffect_Unloaded(object sender, EventArgs e)
{
	Console.WriteLine("Image Unloaded...");
}

C#

ステータスバー効果

  • このエフェクトは、コンパイル時や実行時などのボタンクリック時にXamarinFormsアプリケーションのステータスバーの色を制御するために使用されます。制御に役立つのは1行のコードです。

この例では、以下のようにApp.xamlファイルにカラーリソースを作成します。後で動的に更新されます。

<Color x:Key="StatusBarColor">Firebrick</Color>

C#

次に、XAMLページのルート要素にDynamicResourceとして次の行を追加します

xct:StatusBarEffect.Color="{DynamicResource StatusBarColor}"

C#

次に、サンプル画面のように3つのボタンを追加し、以下のようにボタンクリックで動的リソースの色を更新します。

private void ButtonClicked(object sender, EventArgs e)
{
	Application.Current.Resources["StatusBarColor"] = ((Button)sender).TextColor;
}

C#

完全なコード

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkit.EffectsSamplePage"
             xct:StatusBarEffect.Color="{DynamicResource StatusBarColor}">
    <ContentPage.Content>
        <StackLayout xct:SafeAreaEffect.SafeArea="True"
                     BackgroundColor="White">

            <Frame BackgroundColor="#2196F3"
                   Padding="24"
                   CornerRadius="0">
                <Label Text="Xamarin Forms Effects using XCT"
                       HorizontalTextAlignment="Center"
                       TextColor="White"
                       FontSize="36"/>
            </Frame>

            <Image
                x:Name="img"
                HeightRequest="150"
                Margin="10"
                xct:ShadowEffect.Color="Green"
                xct:ShadowEffect.OffsetY="15"
                Source="https://shorturl.at/qsvJ1">
                <Image.Effects>
                    <xct:LifecycleEffect Loaded="LifeCycleEffect_Loaded" Unloaded="LifeCycleEffect_Unloaded" />
                </Image.Effects>
            </Image>
            <Grid Padding="10">
                <Button Clicked="ButtonClicked" Text="Red" TextColor="Red" BorderColor="Red" BorderWidth="2" Grid.Column="0"/>
                <Button Clicked="ButtonClicked" Text="Green" TextColor="Green" BorderColor="Green" BorderWidth="2" Grid.Column="1"/>
                <Button Clicked="ButtonClicked" Text="Blue" TextColor="Blue" BorderColor="Blue" BorderWidth="2" Grid.Column="2"/>
            </Grid>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

C#

他のタイプのエフェクトも提供するXCT。その他のサンプルについては、以下のリンクにアクセスしてください。https://github.com/xamarin/XamarinCommunityToolkit/tree/main/samples/XCT.Sample/Pages/Effects

コードをダウンロード

コードはGitHubからダウンロードできます。疑問がある場合は、コメントを投稿してください。この記事が気に入って、役立つ場合は、GitHubで記事を共有し、リポジトリにスターを付けてください。

 ソース:https ://www.c-sharpcorner.com/article/xamarin-community-toolkit-effects/

#xamarin #community #toolkit #effective 

XamarinCommunityToolkitで利用可能な注目のエフェクト

Xamarin Y React - Dos Marcos De Desarrollo Multiplataforma Populares

En esta guía, nos enfocaremos en dos marcos de desarrollo multiplataforma populares: Xamarin y React Native. Evaluaremos cada uno de acuerdo con criterios como el rendimiento, la popularidad y el apoyo de la comunidad, y describiremos las ventajas y desventajas asociadas con el uso de Xamarin y React Native.

¿Qué es el desarrollo multiplataforma?

El desarrollo de aplicaciones móviles multiplataforma es el proceso de creación de aplicaciones móviles para múltiples plataformas, como iOS y Android, con una sola pila de tecnología.

Esto significa que, en lugar de crear varias versiones de su aplicación, cada una escrita en el idioma nativo dedicado para cada plataforma, puede escribir su código una vez e implementarlo en varias plataformas a la vez.

Ventajas del desarrollo multiplataforma

El desarrollo multiplataforma y el desarrollo nativo tienen sus ventajas y desventajas. En esta sección, revisaremos los pros y los contras asociados con los marcos de trabajo de desarrollo móvil multiplataforma, como Xamarin y React Native.

  • Escriba una vez, implemente en todas partes : la ventaja más significativa del desarrollo multiplataforma es tener una base de código única que puede exportar a múltiples sistemas operativos.
  • Uniformidad entre aplicaciones : tener una única base de código compartida le permite mantener la misma apariencia, sensación y experiencia en todas las plataformas. Todas las actualizaciones y correcciones también se reflejan automáticamente en todas partes
  • Ahorro de recursos : en lugar de tener equipos separados con diferentes conjuntos de habilidades trabajando en múltiples versiones nativas de su aplicación, solo necesita un equipo trabajando en una base de código compartida. Esto le permite aprovechar equipos más pequeños y un tiempo de desarrollo más rápido para ahorrar tiempo y dinero.
  • Alcance de la audiencia : tener su aplicación publicada en múltiples plataformas le permite aumentar su alcance de mercado sin ningún esfuerzo adicional, lo que en consecuencia aumenta sus posibilidades de obtener más descargas y usuarios.

Desventajas del desarrollo multiplataforma

A continuación se presentan algunos de los inconvenientes asociados con el desarrollo multiplataforma.

  • Problemas de rendimiento : si bien los marcos multiplataforma funcionan para proporcionar aplicaciones lo más cercanas posible a las aplicaciones nativas, aún no se integran a la perfección con las plataformas respectivas y tienen una comunicación inconsistente entre los componentes nativos y no nativos, lo que reduce la velocidad de la aplicación. y rendimiento degradante
  • Incoherencia con las plataformas : las herramientas de desarrollo multiplataforma no tienen todas las funciones que ofrece cada plataforma diferente, por lo que es posible que deba emplear algunas soluciones alternativas. Estos marcos también pueden tardar algún tiempo en actualizarse con las funciones y actualizaciones más recientes lanzadas por las plataformas.
  • Funciones limitadas : hay muchas funciones e integraciones nativas disponibles en cada plataforma que no están disponibles en las aplicaciones multiplataforma, lo que limita la experiencia de usuario que puede brindar

Herramientas de desarrollo de aplicaciones móviles multiplataforma

Hay muchas herramientas y marcos de desarrollo de aplicaciones móviles multiplataforma disponibles, que incluyen:

Echaremos un vistazo a dos de las plataformas de desarrollo móvil más populares en 2021: Xamarin y React Native.

¿Qué es Xamarin?

Xamarin es un marco de desarrollo de aplicaciones móviles multiplataforma de código abierto que se fundó en 2011

¿Para qué se utiliza Xamarin?

Xamarin es especialmente útil para compartir código y lógica empresarial entre plataformas, así como para escribir aplicaciones multiplataforma en C# con Visual Studio. Según los documentos oficiales , Xamarin le permite compartir aproximadamente el 90 por ciento de su aplicación entre plataformas. Eso significa que puede lograr una apariencia nativa, sin mencionar el rendimiento nativo, en cada plataforma sin escribir en varios idiomas.

Puede escribir aplicaciones de Xamarin en una PC o Mac y compilarlas en paquetes nativos, aspirar como archivos .apk y archivos .ipa para dispositivos Android e iOS, respectivamente.

Xamarin se usa para escribir aplicaciones que sirven a una amplia variedad de industrias , que incluyen energía, medios, atención médica, transporte y más.

Las aplicaciones creadas con Xamarin incluyen:

  • Calaveras del Shogun
  • Juegos supergigantes
  • historia
  • Perspicazmente
  • Directo fresco
  • El Banco Mundial
  • solo dando
  • Olo
  • Thermo Fisher Scientific
  • APX

¿Por qué usar Xamarin?

A continuación se muestran algunos beneficios asociados con el desarrollo de aplicaciones móviles multiplataforma de Xamarin.

  • Rendimiento : las aplicaciones de Xamarin son conocidas por tener niveles de rendimiento casi nativos.
  • Ecosistema de desarrollo completo : C#, .Net y Microsoft Visual Studio con Xamarin son todo lo que necesita para crear aplicaciones móviles con Xamarin, lo que lo convierte en uno de los marcos de desarrollo de aplicaciones móviles multiplataforma más completos que existen.
  • Experiencia de usuario perfecta : Xamarin.Forms le permite aprovechar los elementos de la interfaz estándar al proporcionar una biblioteca de plantillas para que pueda reutilizar su código en diferentes plataformas. También puede usar Xamarin.iOS y Xamarin.Android para la personalización manual, si es necesario.
  • Gratis : Para equipos pequeños

Desventajas de usar Xamarin

Ahora analicemos algunos de los inconvenientes asociados con la escritura de aplicaciones móviles multiplataforma en Xamarin.

  • Retraso en las actualizaciones : cada vez que se implementan nuevas características o actualizaciones de la plataforma, generalmente hay un retraso hasta que estos cambios se reflejan en las herramientas de Xamarin, lo que puede causar problemas con su aplicación.
  • Tamaño de aplicación grande : las aplicaciones de Xamarin pueden agregar alrededor de 5 megabytes para lanzamientos y 20 megabytes para compilaciones de depuración, lo que las hace más grandes que las aplicaciones nativas. Esto se debe principalmente a las bibliotecas que se utilizan para traducir las llamadas de C# en llamadas nativas.
  • Gráficos pesados : Xamarin es excelente para aplicaciones con una interfaz de usuario simple. Sin embargo, la creación de aplicaciones complejas o juegos móviles con Xamarin podría no ser lo mejor, ya que tendrá que dedicar mucho tiempo a escribir código específico de la plataforma, lo que anula el propósito de usarlo.
  • Código específico de la plataforma : es posible que deba volver a escribir algunas partes de la interfaz de usuario en su aplicación en código nativo. Eso significa que necesitarás algunos conocimientos en lenguajes de programación nativos como Kotlin o Java para Android, y Swift u Objective-C para iOS.

Herramientas de desarrollo Xamarin

La siguiente es una lista parcial de herramientas y bibliotecas diseñadas para mejorar la experiencia del desarrollador de Xamarin.

¿Qué es React Native?

React Native es un marco de desarrollo de aplicaciones móviles multiplataforma de código abierto creado por Facebook en 2015. Está diseñado para permitir a los desarrolladores usar JavaScript y React junto con las capacidades de la plataforma nativa para crear aplicaciones móviles.

¿Por qué usar React Native?

A continuación se presentan algunos de los beneficios de usar React Native para crear aplicaciones móviles multiplataforma.

  • Interfaz de usuario : implementa componentes de interfaz de usuario nativos, lo que permite que las aplicaciones se vean como aplicaciones nativas y, por lo tanto, proporciona una interfaz de usuario de alta calidad
  • Componentes listos para usar : ofrece una amplia biblioteca de componentes de interfaz de usuario, lo que permite un tiempo de desarrollo más rápido.
  • Acceso a funcionalidades nativas : como cámara, acelerómetro, etc.
  • Código específico de la plataforma : le permite optimizar aún más sus aplicaciones nativas separadas mediante el uso de código nativo
  • Recarga en caliente : permite a los desarrolladores aplicar cambios a las aplicaciones de inmediato sin tener que volver a compilar las aplicaciones.
  • Confiabilidad : Desarrollado y respaldado por Facebook
  • Gratis : plataforma de código abierto

Las aplicaciones de alto perfil creadas con React Native incluyen:

  • Facebook
  • Análisis de Facebook
  • Administrador de anuncios de Facebook
  • Instagram
  • Uber come
  • tesla
  • skype
  • Pinterest
  • Pulso de SoundCloud
  • walmart
  • Bloomberg
  • Discordia
  • Myntra
  • Giroscopio
  • Picar
  • Moda
  • artístico
  • F8

Desventajas de usar React Native

A pesar de todas sus ventajas, hay un pequeño puñado de inconvenientes que debe considerar antes de decidir escribir su próxima aplicación móvil en React Native.

  • Navegación : la navegación integrada en React Native no es fluida y no es comparable a la navegación nativa
  • Interfaz de usuario compleja : React Native tiene dificultades para crear animaciones y transiciones complejas

Herramientas de desarrollo React Native

A continuación se muestra una lista parcial de herramientas y bibliotecas diseñadas para mejorar la experiencia del desarrollador de Xamarin.

¿Es Xamarin mejor que React Native?

Ahora que tiene una buena idea de para qué se usan Xamarin y React Native, las ventajas y desventajas asociadas con el uso de cada uno, y qué empresas de alto perfil usan estos marcos para crear aplicaciones móviles para sus clientes, finalmente es hora de comparar Xamarin vs. Reacciona Nativo.

Evaluaremos Xamarin frente a React Native de acuerdo con los siguientes criterios:

Rendimiento

Uno de los factores más importantes que debe considerar al elegir un marco de desarrollo multiplataforma es el rendimiento de la aplicación.

Si bien React Native y Xamarin brindan rendimientos de aplicaciones casi nativos, algunos argumentan que el rendimiento de Flutter es mejor porque el código Dart se compila en una biblioteca C, lo que significa que está cerca del código nativo.

Esto mejora la velocidad de comunicación y proporciona un mejor rendimiento.

Sin embargo, es difícil comparar el rendimiento, ya que depende de muchos factores y variables, incluidos el dispositivo, el código, la aplicación y las funciones que se utilizan.

Popularidad

Con más de 1,6 millones de desarrolladores en 120 países, Xamarin ha desarrollado una gran base de usuarios a lo largo de los años. Sin embargo, esto se debe en gran parte al hecho de que es uno de los marcos más antiguos que existen.

Desde su lanzamiento, React Native ha ganado popularidad de forma lenta pero segura, superando a Xamarin en 2017.

 

Según la " Encuesta de desarrolladores de 2020 " de Stack Overflow , React Native es más "amado" que Xamarin, con un 57,9 % de los desarrolladores que expresaron interés en continuar desarrollando con React Native, frente al 45,4 % de Xamarin.

Lenguajes de desarrollo

El lenguaje de desarrollo de herramientas multiplataforma es otro factor crucial a considerar al tomar su decisión.

Xamarin usa lenguajes .Net, como C# y F#, que son lenguajes comunes y se pueden usar para escribir código de plataforma nativa. React Native usa JavaScript, que no se inventó para él, pero aun así hace un gran trabajo con las aplicaciones de React Native.

Es posible que encuentre algunos problemas o encuentre algunas soluciones alternativas necesarias, ya que JavaScript se desarrolló originalmente para la web.

Como resultado, es posible que algunas API no funcionen, mientras que otras pueden tener que ser redireccionadas por React Native.

Según el índice de la comunidad de programación de TIOBE , C# es el quinto lenguaje de programación más popular en todo el mundo a partir de febrero de 2021, seguido de JavaScript en el séptimo lugar.

Esto hace que tanto Xamarin como React Native sean opciones sólidas cuando se trata de lenguajes de desarrollo; ambos trabajan con un lenguaje familiar que puede ayudarlo a aumentar su productividad y evitar que tenga que soportar una curva de aprendizaje pronunciada.

Componentes

React Native ofrece algunos componentes preconstruidos y parcialmente adaptables, como botones y entradas de texto. Sin embargo, la mayoría de estos componentes no son realmente adaptables. Si necesita algo un poco más avanzado, tendrá que construirlo usted mismo recomponiendo estos componentes integrados.

Xamarin.Forms ofrece un kit de herramientas de interfaz de usuario multiplataforma completo que consta de componentes de interfaz de usuario nativos para ambas plataformas, que se compilan en componentes de interfaz de usuario específicos de la plataforma.

También puede usar Xamarin.iOS o Xamarin.Android para personalizar la interfaz de usuario de la aplicación y mejorar el rendimiento.

reutilización de código

La reutilización del código es lo que lleva a los desarrolladores a los marcos multiplataforma, entonces, ¿cuánto del código escrito con cada marco es realmente reutilizable?

React Native le permite escribir el código una vez y enviarlo a cualquier lugar, pero también abarca las diferencias de plataforma. Esto significa que, de vez en cuando, debe averiguar en qué plataforma está ejecutando y cargar un componente o conjunto de componentes diferente según la plataforma que esté ejecutando. Aún así, una parte considerable del código base aún se puede reutilizar.

Xamarin se enorgullece de permitir que los desarrolladores reutilicen hasta el 96 % de su código C# aprovechando el lenguaje. Xamarin también ofrece componentes de formularios, lo que lo hace mejor para la reutilización de código que React Native y Flutter, que comparten un promedio del 60 al 90 por ciento de los códigos.

Precios

Si bien tanto Xamarin como React Native son plataformas gratuitas de código abierto, Xamarin solo es gratuito para particulares y pequeñas empresas. Para las grandes empresas, las licencias para un solo usuario comienzan en $499 y alcanzan hasta $2999 por una suscripción anual de Visual Studio Enterprise.

Si bien esto podría no ser un problema para las grandes empresas, los costos aún pueden acumularse, lo que podría hacer que las empresas más grandes opten por React Native.

Soporte y ecosistema

Al elegir un marco, también debe considerar el apoyo de la comunidad, especialmente si es nuevo en él. Esto incluye foros, documentación, tutoriales, etc.

React Native tiene una buena cantidad de soporte por ahí. También puede encontrar fácilmente una gran cantidad de material de aprendizaje o desarrolladores en foros o sitios de control de calidad como Stack Overflow para solicitar asistencia cuando necesite ayuda.

Para Xamarin, el soporte es bastante limitado. Sin embargo, Microsoft ofrece algunos cursos gratuitos de Xamarin  y rutas de aprendizaje para ayudarlo a comenzar.

Conclusión

Al elegir una herramienta de desarrollo multiplataforma, no existe una opción única para todos. Tanto Xamarin como React Native han demostrado ser exitosos en la creación de excelentes aplicaciones móviles. Sus necesidades y preferencias específicas determinan qué marco es mejor para usted.

Por ejemplo, si ya tiene algún conocimiento previo de JavaScript, entonces podría ser conveniente optar por React Native. Al final del día, todo depende de lo que estés construyendo y de lo que esperes lograr. Cualquier marco tendrá sus inconvenientes, pero uno en el que las ventajas superen con creces esos contratiempos probablemente sea la mejor opción para usted.

Fuente: https://blog.logrocket.com/xamarin-vs-react-native/ 

#xamarin #react 

Xamarin Y React - Dos Marcos De Desarrollo Multiplataforma Populares
伊藤  直子

伊藤 直子

1649329200

XamarinとReact - 2つの人気のあるクロスプラットフォーム開発フレームワーク

このガイドでは、XamarinとReactNativeという2つの一般的なクロスプラットフォーム開発フレームワークにズームインします。パフォーマンス、人気、コミュニティサポートなどの基準に従ってそれぞれを評価し、XamarinとReactNativeの両方の使用に関連する長所と短所について説明します。

クロスプラットフォーム開発とは何ですか?

クロスプラットフォームのモバイルアプリ開発は、iOSやAndroidなどの複数のプラットフォーム向けのモバイルアプリケーションを単一のテクノロジースタックで構築するプロセスです。

つまり、プラットフォームごとに専用の母国語を使用して記述されたアプリの複数のバージョンを作成する代わりに、コードを1回記述して、一度に複数のプラットフォームにデプロイできます。

クロスプラットフォーム開発の利点

クロスプラットフォーム開発とネイティブ開発には、それぞれ長所と短所があります。このセクションでは、XamarinやReactNativeなどのクロスプラットフォームモバイル開発フレームワークに関連する長所と短所を確認します。

  • 一度書けばどこにでもデプロイ:クロスプラットフォーム開発の最大の利点は、複数のオペレーティングシステムにエクスポートできる単一のコードベースを持つことです。
  • アプリ間での統一性:単一の共有コードベースを使用すると、すべてのプラットフォームで同じルック、フィール、エクスペリエンスを維持できます。すべての更新と修正も自動的にどこにでも反映されます
  • リソースの節約:異なるスキルセットを持つ別々のチームがアプリの複数のネイティブバージョンで作業する代わりに、共有コードベースで作業するチームは1つだけです。これにより、小規模なチームと迅速な開発時間を活用して、時間とお金を節約できます。
  • オーディエンスリーチ:アプリを複数のプラットフォームで公開することで、追加の労力をかけずに市場リーチを拡大できるため、ダウンロード数とユーザー数を増やす可能性が高まります。

クロスプラットフォーム開発のデメリット

以下は、クロスプラットフォーム開発に関連するいくつかの短所です。

  • パフォーマンスの問題:クロスプラットフォームフレームワークは、ネイティブアプリに可能な限り近いアプリを提供するように機能しますが、それでもそれぞれのプラットフォームとシームレスに統合されず、ネイティブコンポーネントと非ネイティブコンポーネント間の通信に一貫性がないため、アプリの速度が低下しますパフォーマンスの低下
  • プラットフォームとの不整合:クロスプラットフォーム開発ツールは、それぞれの異なるプラットフォームによって提供されるすべての機能を備えているわけではないため、いくつかの回避策を採用する必要がある場合があります。また、これらのフレームワークがプラットフォームによってリリースされた最新の機能やアップデートを最新のものにするのに時間がかかる場合があります
  • 制限された機能:クロスプラットフォームアプリでは利用できない、各プラットフォームで利用できるネイティブのみの機能と統合が多数あり、提供できるユーザーエクスペリエンスが制限されます

クロスプラットフォームのモバイルアプリ開発ツール

以下を含む、利用可能な多くのクロスプラットフォームモバイルアプリ開発ツールとフレームワークがあります。

2021年に最も人気のある2つのモバイル開発プラットフォームであるXamarinとReactNativeを見ていきます。

Xamarinとは何ですか?

Xamarinは、2011年に設立されたオープンソースのクロスプラットフォームモバイルアプリ開発フレームワークです。

Xamarinは何に使用されますか?

Xamarinは、プラットフォーム間でコードとビジネスロジックを共有したり、Visual Studioを使用してC#でクロスプラットフォームアプリケーションを作成したりする場合に特に便利です。公式ドキュメントによると、Xamarinを使用すると、アプリの約90%をプラットフォーム間で共有できます。つまり、複数の言語で記述することなく、各プラットフォームでネイティブのルックアンドフィール(ネイティブのパフォーマンスは言うまでもなく)を実現できます。

XamarinアプリをPCまたはMacで作成し、ネイティブパッケージにコンパイルして、AndroidデバイスとiOSデバイス用にそれぞれ.apkファイルと.ipaファイルとして送信できます。

Xamarinは、エネルギー、メディア、ヘルスケア、運輸など、さまざまな業界にサービスを提供するアプリの作成に使用されます。

Xamarinを使用して構築されたアプリは次のとおりです。

  • 将軍の頭蓋骨
  • スーパージャイアントゲーム
  • Storyo
  • 洞察力
  • FreshDirect
  • 世界銀行
  • ジャストギビング
  • オロ
  • サーモフィッシャーサイエンティフィック
  • APX

なぜXamarinを使用するのですか?

以下は、Xamarinクロスプラットフォームモバイルアプリ開発に関連するいくつかの利点です。

  • パフォーマンス:Xamarinアプリは、ほぼネイティブのようなパフォーマンスレベルを持つことで知られています
  • 完全な開発エコシステム:C#、. Net、およびXamarinを使用したMicrosoft Visual Studioは、Xamarinを使用してモバイルアプリを構築するために必要なすべてであり、Xamarinを最も完全なクロスプラットフォームモバイルアプリ開発フレームワークの1つにします。
  • シームレスなユーザーエクスペリエンスXamarin.Formsを使用すると、テンプレートのライブラリを提供することで標準のインターフェイス要素を利用できるため、さまざまなプラットフォームでコードを再利用できます。必要に応じて、 Xamarin.iOSおよびXamarin.Androidを使用して手動でカスタマイズすることもできます
  • 無料:小規模チーム向け

Xamarinを使用するデメリット

次に、Xamarinでクロスプラットフォームモバイルアプリを作成することに関連するいくつかの欠点を拡大してみましょう。

  • 更新の遅延:新しいプラットフォーム機能または更新が公開されるたびに、通常、これらの変更がXamarinツールに反映されるまで遅延が発生し、アプリで問題が発生する可能性があります
  • 大きなアプリサイズ:Xamarinアプリは、リリース用に約5メガバイト、デバッグビルド用に20メガバイトを追加できるため、ネイティブアプリよりも大きくなります。これは主に、C#呼び出しをネイティブ呼び出しに変換するために使用されるライブラリが原因です。
  • 重いグラフィック:Xamarinは、シンプルなUIを備えたアプリに最適です。ただし、Xamarinを使用して複雑なアプリケーションやモバイルゲームを構築することは、プラットフォーム固有のコードを作成するために多くの時間を費やす必要があるため、最善の方法ではない可能性があります。
  • プラットフォーム固有のコード:アプリのUIの一部をネイティブコードで書き直す必要がある場合があります。つまり、Androidの場合はKotlinやJava、iOSの場合はSwiftやObjective-Cなどのネイティブプログラミング言語に関する知識が必要になります。

Xamarin開発ツール

以下は、Xamarin開発者のエクスペリエンスを向上させるために設計されたツールとライブラリの部分的なリストです。

React Nativeとは何ですか?

React Nativeは、2015年にFacebookによって作成されたオープンソースのクロスプラットフォームモバイルアプリ開発フレームワークです。開発者がJavaScriptとReactをネイティブプラットフォーム機能とともに使用して、モバイルアプリを構築できるように設計されています。

なぜReactNativeを使うのですか?

以下は、ReactNativeを使用してクロスプラットフォームのモバイルアプリを構築する利点の一部です。

  • ユーザーインターフェース:ネイティブUIコンポーネントを実装し、アプリをネイティブアプリのように見せることで、高品質のユーザーインターフェースを提供します
  • 既製のコンポーネント:UIコンポーネントの膨大なライブラリを提供し、開発時間を短縮します。
  • ネイティブ機能へのアクセス:カメラ、加速度計など。
  • プラットフォーム固有のコード:ネイティブコードを使用して、個別のネイティブアプリをさらに最適化できます
  • ホットリロード:開発者は、アプリを再コンパイルしなくても、アプリに変更をすぐに適用できます
  • 信頼性:Facebookによって開発およびサポートされています
  • 無料:オープンソースプラットフォーム

ReactNativeで構築された注目度の高いアプリは次のとおりです。

  • フェイスブック
  • Facebookアナリティクス
  • Facebook広告マネージャー
  • インスタグラム
  • Uber Eats
  • テスラ
  • Skype
  • Pinterest
  • SoundCloudパルス
  • ウォルマート
  • ブルームバーグ
  • 不和
  • ミントラ
  • ジャイロスコープ
  • チョップ
  • 流行
  • アーティ
  • F8

ReactNativeを使用するデメリット

そのすべての利点について、React Nativeで次のモバイルアプリを作成することを決定する前に、考慮すべきいくつかの欠点があります。

  • ナビゲーション:React Nativeに組み込まれているナビゲーションはシームレスではなく、ネイティブナビゲーションとは比較できません。
  • 複雑なUI:React Nativeは、複雑なアニメーションとトランジションの構築に苦労しています

ReactNative開発ツール

以下は、Xamarin開発者のエクスペリエンスを向上させるために設計されたツールとライブラリの部分的なリストです。

XamarinはReactNativeよりも優れていますか?

XamarinとReactNativeの用途、それぞれの使用に関連する長所と短所、およびこれらのフレームワークを使用して顧客向けのモバイルアプリを構築する有名企業について理解できたので、ついにXamarinとを比較します。リアクトネイティブ。

次の基準に従って、XamarinとReactNativeを評価します。

パフォーマンス

クロスプラットフォーム開発フレームワークを選択する際に考慮すべき最も重要な要素の1つは、アプリのパフォーマンスです。

React NativeとXamarinはネイティブに近いアプリのパフォーマンスを提供しますが、DartコードはCライブラリにコンパイルされているため、 Flutterのパフォーマンスが優れていると主張する人もいます。つまり、ネイティブコードに近いということです。

これにより、通信速度が向上し、パフォーマンスが向上します。

ただし、パフォーマンスは、使用されているデバイス、コード、アプリ、機能など、多くの要因や変数に依存するため、ベンチマークを行うのは困難です。

人気

Xamarinは、120か国に160万人を超える開発者を擁し、長年にわたってかなりのユーザーベースを開発してきました。ただし、これは主に、最も古いフレームワークの1つであるという事実によるものです。

リリース以来、React Nativeはゆっくりと、しかし確実に人気を博し、2017年にはXamarinを上回りました。

 

StackOverflowの「 2020DeveloperSurvey」によると、React NativeはXamarinよりも「愛され」ており、開発者の57.9%が、Xamarinの45.4%に対して、ReactNativeでの開発を継続することに関心を示しています。

開発言語

クロスプラットフォームのツール開発言語は、決定を下す際に考慮すべきもう1つの重要な要素です。

Xamarinは、一般的な言語であり、ネイティブプラットフォームコードの記述に使用できるC#やF#などの.Net言語を使用します。React NativeはJavaScriptを使用しますが、JavaScriptはそのために発明されたものではありませんが、それでもReactNativeアプリで優れた機能を発揮します。

JavaScriptは元々Web用に開発されたものであるため、いくつかの問題が発生したり、いくつかの必要な回避策に遭遇したりする可能性があります。

その結果、一部のAPIは機能しない可能性がありますが、他のAPIはReactNativeによってプロキシされる必要がある場合があります。

TIOBEプログラミングコミュニティインデックスによると、C#は2021年2月の時点で世界で5番目に人気のあるプログラミング言語であり、JavaScriptが7番目に続いています。

これにより、開発言語に関しては、XamarinとReactNativeの両方が確実に選択されます。どちらも使い慣れた言語で動作するため、生産性が向上し、急な学習曲線に耐えることができなくなります。

コンポーネント

React Nativeは、ボタンやテキスト入力など、いくつかのビルド済みで部分的に適応可能なコンポーネントを提供します。ただし、これらのコンポーネントのほとんどは実際には適応性がありません。もう少し高度なものが必要な場合は、これらの組み込みコンポーネントを再構成して、自分でビルドする必要があります。

Xamarin.Formsは、プラットフォーム固有のUIコンポーネントにコンパイルされた、両方のプラットフォームのネイティブUIコンポーネントで構成される完全なクロスプラットフォームUIツールキットを提供します。

Xamarin.iOSまたはXamarin.Androidを使用して、カスタムアプリのUIとパフォーマンスを向上させることもできます。

コードの再利用

コードの再利用は、開発者をクロスプラットフォームフレームワークに導くものです。それで、各フレームワークで記述されたコードのどれだけが実際に再利用可能ですか?

React Nativeを使用すると、コードを1回記述してどこにでも出荷できますが、プラットフォームの違いも含まれます。つまり、実行しているプラ​​ットフォームを確認し、実行しているプラ​​ットフォームに応じて異なるコンポーネントまたはコンポーネントのセットをロードする必要がある場合があります。それでも、コードベースのかなりの部分を再利用できます。

Xamarinは、開発者が言語を活用してC#コードの最大96%を再利用できるようにすることに誇りを持っています。Xamarinはフォームコンポーネントも提供しているため、コードの平均60〜90%を共有するReact NativeやFlutterよりも、コードの再利用に適しています。

価格設定

XamarinとReactNativeはどちらも無料のオープンソースプラットフォームですが、Xamarinは個人と中小企業のみが無料で利用できます。大企業の場合、シングルユーザーライセンスは499ドルから始まり、VisualStudioEnterpriseの年間サブスクリプションで最大2,999ドルになります。

これは大企業にとっては問題ではないかもしれませんが、それでもコストが加算される可能性があり、大企業がReactNativeを採用する可能性があります。

サポートとエコシステム

フレームワークを選択するときは、特にフレームワークを初めて使用する場合は、コミュニティサポートも考慮する必要があります。これには、フォーラム、ドキュメント、チュートリアルなどが含まれます。

React Nativeには、かなりの量のサポートがあります。フォーラムやStackOverflowなどのQAサイトで、多くの学習資料や開発者を簡単に見つけることができ、サポートが必要なときはいつでもサポートを求めることができます。

Xamarinの場合、サポートはかなり制限されています。ただし、Microsoftは、開始に役立つ無料のXamarinコース と学習パスをいくつか提供しています。

結論

クロスプラットフォーム開発ツールを選択する場合、万能のオプションはありません。XamarinとReactNativeはどちらも、優れたモバイルアプリの構築に成功していることが証明されています。特定のニーズと好みによって、どのフレームワークが最適かが決まります。

たとえば、JavaScriptの予備知識がすでにある場合は、ReactNativeを使用するのが賢明かもしれません。結局のところ、それはすべて、構築しているものと達成したいものによって異なります。どのフレームワークにも落とし穴がありますが、利点がそれらの挫折を大幅に上回っているフレームワークは、おそらくあなたにとって正しい選択でしょう。

ソース:https ://blog.logrocket.com/xamarin-vs-react-native/ 

#xamarin #react 

XamarinとReact - 2つの人気のあるクロスプラットフォーム開発フレームワーク

Comparación De La Experiencia Del Desarrollador Para Marcos Multiplata

El desarrollo de aplicaciones móviles multiplataforma le permite crear aplicaciones móviles para múltiples plataformas, como iOS y Android, con solo una pila de tecnología.

Esto significa que, en lugar de crear varias versiones de su aplicación, cada una escrita en el idioma nativo dedicado para cada plataforma, puede escribir su código una vez e implementarlo en varias plataformas a la vez.

¿Qué es la experiencia del desarrollador?

Developer Experience (abreviado como DX) describe la experiencia que tienen los desarrolladores cuando usan bibliotecas de cliente, SDK, marcos, código fuente abierto, herramientas, API, tecnología o cualquier servicio.

DX comparte algunas ideas y filosofías del diseño de experiencia de usuario (UX).

¿Cómo hace esto una diferencia?

La oportunidad de implementar una aplicación web con un solo comando de terminal es una indicación de lo que se puede percibir como una mejor experiencia del desarrollador, en lugar de seguir una larga lista de instrucciones para lograr los mismos resultados.

DX es uno de los factores latentes que impulsan a los desarrolladores a usar una herramienta y apegarse a ella.

Esta publicación compara el DX de algunos marcos móviles multiplataforma populares en función de cuatro factores que son realmente importantes para los desarrolladores:

  • Configuración
  • Documentación
  • recarga en caliente
  • depuración

Nuestra comparación se centrará en 5 marcos multiplataforma:

  • reaccionar nativo
  • Aleteo
  • Xamarin
  • Iónico
  • Escritura nativa

Empezando

La configuración de un marco es su primera impresión. Comenzar fácilmente es lo que primero influye en DX sobre el flujo de trabajo del marco.

Aquí compararemos el proceso de configuración de los diferentes marcos móviles, sin tener en cuenta la configuración de Android Studio y/o XCode porque este es básicamente un paso obligatorio para todos ellos.

React Native : usando Expo , React Native es extremadamente fácil de comenzar.

Después de instalar NodeJS y Expo, solo tiene que escribir un solo comando y luego está listo para comenzar (sin instalar Android Studio o Xcode y suponiendo que tiene un dispositivo con la aplicación Expo instalada). La plantilla inicial se envía con una interfaz hermosa y simple para ayudar a guiar al desarrollador.

También puede iniciar una aplicación React Native sin Expo utilizando la herramienta de línea de comandos RN. Hacer que nuestra aplicación RN se ejecute con este método no es demasiado trabajo. La herramienta CLI ayuda a los desarrolladores a obtener su primera aplicación de pantalla lo suficientemente rápido.

Comenzar con RN solo se vuelve complicado cuando necesitamos integrarlo en una aplicación nativa existente o construir para plataformas fuera del árbol . Sin embargo, esto se considera una práctica avanzada y no debe tenerse en cuenta en esta comparación.

React Native ha estado haciendo su tarea tan bien que incluso lanzaron un react-native doctorpaquete para ayudar a verificar la configuración en su computadora.

Flutter : instalar Flutter SDK es tan fácil como instalar un paquete en su computadora. Su guía muestra cuatro pasos simples que son fáciles de seguir. Incluso si esto se vuelve un poco problemático para ti, Flutter te tiene cubierto.

Son bien conocidos por preocuparse mucho por DX. Integraron una herramienta llamada flutter doctoren su CLI para ayudarlo a obtener información sobre lo que funciona bien y lo que podría no funcionar bien en la cadena de herramientas del marco.

Las herramientas de Flutter también deben configurarse en su editor de código para ayudar a proporcionar un mejor DX. Esto explica algunos pasos adicionales en la configuración. Estos pasos son opcionales, pero ayudaron a lograr las mejores reseñas de Flutter en Internet.

Todo lo de Flutter se siente "fuera de la caja". Es fácil crear una aplicación más compleja usando solo los paquetes que se enviaron con el SDK de Flutter.

Xamarin : si es un desarrollador de C# acostumbrado a Visual Studio IDE, instalar Xamarin seguramente le parecerá un paseo por el parque. Sin embargo, si no tiene Visual Studio, es posible que la instalación de VS2019 y las herramientas de Xamarin le resulten tediosas.

Una vez que instale Xamarin, puede iniciar una aplicación a través de la GUI de introducción de Visual Studio. Aquí simplemente selecciona la aplicación móvil y elige una plantilla inicial de las proporcionadas (Maestro-detalle, Tabulado, Shell y En blanco). Luego selecciona la plataforma, haz clic en continuar y espera a que se inicialice.

Ionic : Desde v1, Ionic siempre ha sido muy fácil para comenzar. Ahora estamos en v5 y se está volviendo aún más fácil.

Ocurre en 3 pasos: instalar Ionic con Node, ejecutar y seguir las indicaciones de ionic start myApp <template-name>(donde le proporcionaron 3 plantillas: en blanco, pestañas y menú lateral), y finalmente ejecutar la aplicación con ionic serve.

Aquí, la aplicación predeterminada se muestra en su navegador como un sitio web móvil, pero así es como se verá la aplicación después de las compilaciones.

También es muy importante tener en cuenta que Ionic tiene v5, un asistente de inicio hermoso e intuitivo que lo ayuda a obtener el mismo resultado que el anterior con solo una instrucción de línea de comando.

NativeScript : tienen dos formas de comenzar: configuración rápida y configuración completa. El proceso de configuración rápida es similar a React Native con Expo: hay una aplicación que descarga en el dispositivo físico y luego React Native se conecta a la terminal de desarrollo a través de un enlace y podemos comenzar a trabajar en nuestra aplicación (sin instalar Android Studio o XCode) .

La configuración completa también es fácil, ya que proporcionan enlaces que funcionan bien con la terminal de su sistema operativo para instalar el marco. Además, como Flutter, tienen una herramienta médica accesible con: tns doctor, que verifica la configuración en su computadora.

Nota :
Cabe señalar que la mayoría de las configuraciones rápidas tienen algunas limitaciones con los flujos de trabajo. Por ejemplo, el acceso a algunos complementos nativos está restringido, las pruebas unitarias a veces son imposibles (en el caso de NativeScript) y algunos recursos (pantallas de presentación, íconos) no son accesibles.

Documentación

Cualquier desarrollador puede admitir que enamorarse de una herramienta a veces pasa por la facilidad de trabajar con el manual de la herramienta.

React Native : aunque últimamente se han realizado algunas mejoras importantes en los documentos de React Native, lo más probable es que los desarrolladores de React Native tiendan a obtener un toque de temas avanzados de recursos como publicaciones de blogs, tutoriales en línea y cursos.

Esto parece estar relacionado con el hecho de que los temas de React Native que van desde el nivel medio hasta el avanzado exigen mucho más (administración de estado, navegación, animaciones y mucho más) de lo que propone su API central.

Flutter : los documentos de Flutter deben ser los más queridos de los cinco marcos. Lo inundaron con información organizada para ayudar a cualquiera a revisarlos. Desde comandos simples hasta libros de cocina que incluyen videos informativos breves y clases de widgets, la documentación de Flutter está muy bien presentada. ¿Mencioné que se puede acceder fácilmente a la API de referencias de clase del widget desde el código fuente de cada widget?

Xamarin : los desarrolladores de Xamarin dicen que sus documentos están "llenos", ¡lo cual es cierto! Xamarin tiene, entre los cinco, uno de esos documentos a los que siempre volverá cuando necesite información sobre cualquier tema del marco.

Puede pasar de principiante a avanzado únicamente con el material de los documentos. Su navegación es realmente intuitiva e incluye breves tutoriales y enlaces a temas abiertos sobre los temas y casos de uso.

Ionic : Está claro que Ionic hizo un trabajo asombroso en su documentación. En cada actualización importante, todo el sitio web cambia a favor de una mejor experiencia de usuario.

A la mayoría de los desarrolladores que trabajan con Ionic les resulta fácil buscar, encontrar e integrar los componentes que necesitan.

NativeScript : una cosa sobre NativeScript es que es mucho mejor que lo que anuncian. Los documentos de NativeScript son bastante básicos: necesitan más guías para mostrar a los desarrolladores lo fácil que es aprovechar el poder del marco.

Además, al intentar pasar de principiante a experimentado, creemos que los documentos de NativeScript carecen de algunos ejemplos claros de lo que el marco realmente le permite hacer. La mayoría de las veces, los desarrolladores tienen que pasar por problemas de GitHub para comprender algunos conceptos básicos.

recarga caliente

Este es un tema candente entre los marcos multiplataforma móviles y, a veces, se puede denominar una parte eficiente del tiempo del desarrollo móvil.

React Native : durante mucho tiempo, la recarga en caliente fue una de las debilidades que alejó a los desarrolladores de esta solución multiplataforma. Sin embargo, en React Native 0.61, anunciaron Fast Refresh , que NO es exactamente una recarga en caliente , pero también hace felices a los desarrolladores de RN.

Lo increíble de la actualización rápida es que es totalmente compatible con React moderno (componentes de funciones y ganchos) y maneja errores con gracia.

Flutter : Es un placer trabajar con la función de recarga en caliente de Flutter. Es tan bueno que flutter proporciona 3 formas diferentes de recargar su aplicación mientras trabaja: recarga en caliente, reinicio en caliente y reinicio completo.

Hay algunas advertencias que están muy bien explicadas y elaboradas en sus documentos, pero estas no impiden que esta característica sea uno de los mejores puntos de venta de Flutter para los desarrolladores.

Xamarin : al igual que con los otros 4 marcos, la recarga en caliente de Xamarin funciona de forma inmediata. Sin configuración adicional, puede guardar sus archivos y activar una actualización. La recarga en caliente de Xamarin funciona en varias plataformas a la vez y usa un principio llamado recarga resistente .

También hay algunos problemas con la recarga activa de Xamarin: no puede recargar el código C#, incluidos los controladores de eventos, los controles personalizados, el código subyacente de la página y las clases adicionales. Además, no puede cambiar archivos durante una sesión de recarga en caliente. Para ver este cambio, deberá reconstruir y volver a implementar su aplicación para volver a habilitar la recarga en caliente

Ionic : la recarga en vivo en Ionic se puede ver de dos maneras, porque las aplicaciones de Ionic se pueden desarrollar utilizando dos enfoques diferentes. Uno puede usar el navegador para codificar la aplicación y ver los resultados, o puede conectar su teléfono a la computadora para poder evaluarlo desde allí. Sin embargo, Ionic tiene una función completa de recarga en caliente que lo ayudará a desarrollar su aplicación de manera eficiente, independientemente del enfoque que elija.

NativeScript : desde Native script 5.3, es oficialmente compatible con una increíble función HMR - Hot Module Replacement que admite la depuración de VSCode, ediciones de estilo, ediciones de JavaScript e incluso ediciones de archivos.

La función LiveSync , que se ejecuta cuando iniciamos una run or debug on device, también permite, como en el caso de Ionic, realizar cambios en su aplicación y ver los aplicados en tiempo real en todos los dispositivos y emuladores conectados.

Herramientas de depuración

Los desarrolladores a veces dicen que "la depuración es el doble de difícil que escribir el código en primer lugar". Dado que esto puede considerarse una de las partes más difíciles de nuestro trabajo, ¿por qué cualquier herramienta debería hacerlo más difícil?

La depuración multiplataforma móvil siempre ha sido incómoda, porque las herramientas no solo son híbridas, sino que también pueden no ser siempre compatibles de forma nativa.

Aquí, durante la comparación, combinaremos las herramientas de depuración y las funciones de informe de errores del marco.

React Native : al igual que con la recarga en caliente, la depuración con React Native siempre ha sido "incompleta", ya que el equipo central no admitía oficialmente ninguna herramienta.

Sin embargo, en React Native 0.62, anunciaron Flipper , que es el depurador de RN predeterminado desde el 26 de marzo. Flipper tiene excelentes funciones necesarias en un depurador, en particular:

  • React DevTools disponible
  • Inspectores de redes, diseños, bases de datos y preferencias
  • Acciones de Metro que ayudan a recargar la aplicación
  • Informe de fallas y registros del dispositivo.

Flutter : Flutter DevTools es una característica muy potente y completa. Se adapta a casi todos los casos de uso, desde salidas de consola simples, pasando por análisis de widgets visuales hasta inspección de red y rendimiento.

Flutter probablemente tiene la mejor función de depuración entre los 5 marcos.

Xamarin : Xamarin depura las aplicaciones de Android e iOS de manera diferente. Las aplicaciones de Android se depuran como cualquier otra aplicación .NET: después de ejecutar el dispositivo con la configuración de depuración, simplemente podemos agregar puntos de interrupción y seguir la ejecución de nuestra aplicación.

Xamarin.iOS usa el depurador Mono Soft , el código generado y el tiempo de ejecución Mono cooperan con el IDE para proporcionar una experiencia de depuración.

Ionic : en sus documentos, Ionic proporciona una amplia gama de funciones de depuración,  ya que los marcos crean aplicaciones híbridas (HTML, CSS y JavaScript en una vista web) que se pueden depurar fácilmente con los depuradores web.

En caso de que desee ver mejores registros o una depuración más profunda, Cordova proporciona una extensión de VSCode que se adaptará a casi todas sus necesidades.

NativeScript : con el comando tns debug <platform>, podemos iniciar fácilmente una sesión de depuración con NativeScript e iniciar Livesync.

Sin embargo, el resultado de la depuración se imprime en la consola y todos los cambios que realice se sincronizan con la aplicación. Sin embargo, cabe señalar que la extensión VSCode permite una experiencia de depuración mucho mejor.

Además, esta publicación de blog sobre cómo depurar los complementos de NativeScript ayuda a los desarrolladores a profundizar en la creación y depuración de aplicaciones con el esquema de NativeScript, que explica cómo los desarrolladores pueden abordar la depuración del código fuente nativo de los complementos que usan.

Otras comparaciones

Los anteriores son los principales factores que atraen y mantienen a los desarrolladores en una herramienta que utilizan. Ahora veamos las cosas opcionales que hacen que los desarrolladores disfruten el tiempo que pasan trabajando con herramientas multiplataforma.

Editor de código/integraciones IDE

De los 5 marcos anteriores, Flutter puede sonar como el mejor debido a la potencia de los complementos y las integraciones que envían para los diferentes editores que admiten.

Después de instalar las extensiones de Flutter en VSCode , rápidamente comienza a sentirse como si se hubiera convertido en un IDE con soporte completo de depuración, fragmentos de andamiaje, hermoso resaltado de sintaxis y finalización de código.

Aunque no es tan avanzado como las herramientas de Flutter, React Native también tiene React Native Tools de Microsoft para ayudarlo a ejecutar y depurar rápida y fácilmente sus aplicaciones React Native.

Xamarin bien porque VS2019 le brinda todo lo que necesita para el desarrollo de Xamarin cuando decide instalar el marco. Esto mantiene al desarrollador en la herramienta porque todo lo que pueden obtener es todo lo que necesitan del IDE.

Con Ionic y NativeScript, está bien con la mayoría de los editores de desarrollo web porque usan herramientas de interfaz de usuario populares como HTML, JSX, CSS, SASS, Angular, React y Vue, que ya tienen un buen soporte en los editores existentes.

módulos de terceros

Las aplicaciones Advanced React Native dependen en gran medida de módulos de terceros, que pueden convertirse rápidamente en un rompecabezas cuando se actualizan con partes faltantes debido a la compatibilidad con otros módulos o con la versión actual del marco.

Sin embargo, la comunidad React Native es asombrosamente grande, por lo que hay muchos paquetes de código abierto disponibles en npm que podrían ser muy útiles para crear aplicaciones.

Este problema es menor en Flutter y Xamarin porque están listos con la mayor parte de lo que necesitamos para crear aplicaciones multiplataforma y su proceso de actualización está bien administrado por los respectivos archivos YAML y XML.

Flutter tiene su propio sitio web de administración de paquetes  donde puede buscar y ver ejemplos de uso de los paquetes de Flutter.

Ionic en sí viene con la mayoría de los componentes de la interfaz de usuario necesarios para crear material o aplicaciones de interfaz de usuario de iOS, y respetan las pautas de diseño. Sin embargo, depende en gran medida de los complementos nativos de Cordova para acceder a las funcionalidades nativas, que a su vez pueden no estar actualizadas o carecer de documentación.

NativeScript, como Ionic, se incluye con una gran cantidad de componentes de interfaz de usuario atractivos. Sin embargo, los complementos nativos están disponibles y desarrollados por el equipo de NativeScript y su comunidad y se muestran en un Marketplace dedicado .

Conclusión

Los cinco marcos tienen una gran comunidad y ya son conocidos como las principales herramientas multiplataforma, debido a su amplio uso entre las empresas. Cada uno de ellos tiene flujos de trabajo únicos que pueden adaptarse a cada caso de uso.

Sin embargo, es importante comprender las fortalezas y limitaciones de cada uno y elegir de acuerdo con la tarea y el equipo con el que está tratando.

Fuente: https://blog.logrocket.com/comparing-developer-experience-for-cross-platform-frameworks/

#frameworks #xamarin #flutter #ionic #react 

Comparación De La Experiencia Del Desarrollador Para Marcos Multiplata
伊藤  直子

伊藤 直子

1649264520

クロスプラットフォームフレームワークの開発者エクスペリエンスの比較

クロスプラットフォームのモバイルアプリ開発では、1つのテクノロジースタックでiOSやAndroidなどの複数のプラットフォーム向けのモバイルアプリケーションを構築できます。

つまり、プラットフォームごとに専用の母国語を使用して記述されたアプリの複数のバージョンを作成する代わりに、コードを1回記述して、一度に複数のプラットフォームにデプロイできます。

開発者の経験とは何ですか?

開発者エクスペリエンス(DXと略記)は、開発者がクライアントライブラリ、SDK、フレームワーク、オープンソースコード、ツール、API、テクノロジー、またはその他のサービスを使用するときのエクスペリエンスを表します。

DXは、ユーザーエクスペリエンス(UX)デザインからのいくつかのアイデアと哲学を共有しています。

これはどのように違いを生むのでしょうか?

単一のターミナルコマンドでWebアプリをデプロイする機会は、同じ結果を達成するための長い指示のリストに従うのではなく、より優れた開発者エクスペリエンスとして認識できるものを示しています。

DXは、開発者がツールを使用してそれに固執するように駆り立てる潜在的な要因の1つです。

この投稿では、開発者にとって本当に重要な4つの要素に基づいて、いくつかの人気のあるクロスプラットフォームモバイルフレームワークのDXを比較しています。

  • 設定
  • ドキュメンテーション
  • ホットリロード
  • デバッグ

私たちの比較では、5つのクロスプラットフォームフレームワークに焦点を当てます。

  • リアクトネイティブ
  • フラッター
  • Xamarin
  • イオン
  • NativeScript

入門

フレームワークのセットアップが第一印象です。簡単に始めることが、フレームワークのワークフローに関してDXに最初に影響を与えるものです。

ここでは、Android StudioやXCodeのセットアップを無視して、さまざまなモバイルフレームワークのセットアッププロセスを比較します。これは、基本的にすべてのフレームワークにとって必須の手順だからです。

React NativeExpoを使用すると、ReactNativeを非常に簡単に開始できます。

NodeJSとExpoをインストールした後は、入力するコマンドが1つだけで、準備が整います(Android StudioまたはXcodeをインストールせずに、Expoアプリがインストールされたデバイスがあることを前提としています)。開始テンプレートには、開発者をガイドするのに役立つ美しくシンプルなインターフェイスが付属しています。

RNコマンドラインツールを使用して、ExpoなしでReactNativeアプリを起動することもできます。この方法を使用してRNアプリを実行するのは、それほど手間がかかりません。CLIツールは、開発者が最初の画面アプリをすぐに入手するのに役立ちます。

RNの使用を開始するには、RNを既存のネイティブアプリに統合する必要がある場合、またはツリー外のプラットフォーム用に構築する必要がある場合にのみ注意が必要です。ただし、これは高度な方法と見なされるため、この比較では考慮しないでください。

React Nativeは宿題をうまくやっているのでreact-native doctor、コンピューターのセットアップを確認するのに役立つパッケージもリリースしました。

Flutter:Flutter SDKをインストールするのは、コンピューターにパッケージをインストールするのと同じくらい簡単です。彼らのガイドは、従うのが簡単な4つの簡単なステップを示しています。これがあなたの側で少しバグがあるとしても、Flutterはあなたをカバーしてくれます。

彼らはDXを大事にすることでよく知られています。彼らはCLIに呼び出されるツールを統合しflutter doctorて、フレームワークのツールチェーンで何がうまく機能していて何がうまく機能しないかについての情報を取得できるようにしました。

より良いDXを提供するには、Flutterツールもコードエディターで構成する必要があります。これは、セットアップのいくつかの追加手順を説明します。これらの手順はオプションですが、インターネット上で最高のFlutterレビューを達成するのに役立ちました。

Flutterのすべてが「すぐに使える」と感じます。Flutter SDKに同梱されているパッケージのみを使用して、より複雑なアプリを簡単に構築できます。

Xamarin:Visual Studio IDEに慣れているC#開発者の場合、Xamarinのインストールは確かに公園を散歩しているように見えます。ただし、Visual Studioがない場合は、VS2019のインストールとXamarinツールが面倒になる可能性があります。

Xamarinをインストールすると、Visual Studio GettingStartedGUIを使用してアプリを起動できます。ここでは、モバイルアプリを選択し、提供されているテンプレート(マスター詳細、タブ付き、シェル、空白)から開始テンプレートを選択します。次に、プラットフォームを選択し、[続行]をクリックして、初期化されるのを待ちます。

Ionic:v1以降、Ionicは常に非常に簡単に使い始めることができます。現在、v5を使用しており、さらに簡単になっています。

これは3つのステップでionic start myApp <template-name>行われます。IonicwithNodeをインストールし、(空白、タブ、サイドメニューの3つのテンプレートが提供されている)のプロンプトを実行して実行し、最後に。を使用してアプリを実行しionic serveます。

ここでは、デフォルトのアプリがモバイルWebサイトのようにブラウザで提供されますが、これはビルド後のアプリの外観とほぼ同じです。

また、Ionicにはv5があります。これは、1つのコマンドライン命令だけで上記と同じ結果を得るのに役立つ、美しく直感的な起動ウィザードです。

NativeScript:開始するには、クイックセットアップとフルセットアップの2つの方法があります。クイックセットアッププロセスは、React Native with Expoに似ています。物理デバイスにアプリをダウンロードすると、React Nativeがリンクを介して開発端末に接続し、アプリの作業を開始できます(Android StudioまたはXCodeをインストールせずに) 。

フレームワークをインストールするためにOSの端末とうまく機能するリンクを提供するため、フルセットアップも簡単です。さらに、Flutterと同様に、次のコマンドでアクセスできるドクターツールがありますtns doctor。これは、コンピューターのセットアップを確認します。


ほとんどのクイックセットアップには、ワークフローにいくつかの制限があることに注意してください。たとえば、一部のネイティブプラグインへのアクセスが制限され、単体テストが不可能な場合があり(NativeScriptの場合)、一部のリソース(スプラッシュ画面、アイコン)にアクセスできません。

ドキュメンテーション

開発者なら誰でも、ツールのマニュアルを使いやすくすることで、ツールに夢中になることがあることを認めることができます。

React Native:最近、React Nativeのドキュメントにいくつかの大きな改善が加えられましたが、React Native開発者は、ブログ投稿、オンラインチュートリアル、コースなどのリソースから高度なトピックに触れる傾向があります。

これは、中級から上級レベルまでのReact Nativeトピックが、コアAPIによって提案されたものよりもはるかに多くの(状態管理、ナビゲーション、アニメーションなど)を要求するという事実に関連しているようです。

Flutter:Flutterのドキュメントは、5つのフレームワークの中で最も愛されている必要があります。彼らは、誰もがそれらを通り抜けるのを助けるために組織化された情報でそれを氾濫させました。単純なコマンドから、短い有益なビデオやウィジェットクラスを含むクックブックに至るまで、Flutterのドキュメントは非常によく提示されています。ウィジェットのクラス参照APIは、ウィジェットの各ソースコードから簡単にアクセスできることを述べましたか?

Xamarin:Xamarin開発者は、ドキュメントが「フル」であると言っています。これは本当です。Xamarinには、5つのドキュメントのうち、フレームワークのトピックに関する洞察が必要なときにいつでも戻ってくるドキュメントの1つがあります。

ドキュメントの資料だけで、初心者から上級者までかなりうまく行くことができます。そのナビゲーションは本当に直感的で、トピックとユースケースに関する未解決の問題への短いチュートリアルとリンクが含まれています。

Ionic:Ionicが彼らのドキュメントに驚くべき仕事をしていることは明らかです。メジャーアップデートのたびに、Webサイト全体が変更され、ユーザーエクスペリエンスが向上します。

Ionicを使用する開発者のほとんどは、必要なコンポーネントを簡単に検索、検索、統合できると感じています。

NativeScript:NativeScriptの1つは、宣伝するものよりもはるかに優れていることです。NativeScriptのドキュメントは非常に基本的です。フレームワークの能力を活用することがいかに簡単であるかを開発者に示すために、より多くのガイドが必要です。

さらに、初心者から熟練者に移行しようとすると、NativeScriptのドキュメントには、フレームワークで実際に実行できることの明確な例がいくつか欠けていると感じます。ほとんどの場合、開発者はいくつかの基本的な概念を理解するためにGitHubの問題を経験する必要があります。

ホットリロード

これは、モバイルクロスプラットフォームフレームワークの中でホットなトピックであり、モバイル開発の時間効率の良い部分と呼ばれることもあります。

React Native:長い間、ホットリロードは開発者をこのクロスプラットフォームソリューションから遠ざける弱点の1つでした。ただし、React Native 0.61で、彼らはFast Refreshを発表しました。これは、正確にはホットリロードではありませんが、RN開発者も満足させます。

高速リフレッシュの素晴らしい点は、最新のReact(関数コンポーネントとフック)を完全にサポートし、エラーを適切に処理することです。

Flutter:Flutterのホットリロード機能は操作するのが楽しいです。非常に優れているため、フラッターは、作業中にアプリをリロードする3つの異なる方法、ホットリロード、ホットリスタート、およびフルリスタートを提供します。

ドキュメントで非常によく説明され、解決されているいくつかの警告がありますが、これらはこの機能が開発者にとってFlutterのベストセールスポイントの1つであることを妨げるものではありません。

Xamarin:他の4つのフレームワークと同様に、Xamarinのホットリロードはそのままで機能します。さらに設定しなくても、ファイルを保存して更新をトリガーできます。Xamarinのホットリロードは、一度に複数のプラットフォームで機能し、復元力のあるリロードと呼ばれる原則を使用します。

Xamarinのホットリロードにはいくつかの問題もあります。イベントハンドラー、カスタムコントロール、ページコードビハインド、追加のクラスなど、C#コードをリロードできません。また、ホットリロードセッション中にファイルを変更することはできません。この変更を表示するには、アプリを再構築して再デプロイし、ホットリロードを再度有効にする必要があります

Ionic:Ionicアプリは2つの異なるアプローチを使用して開発できるため、Ionicでのライブリロードは2つの方法で表示できます。ブラウザを使用してアプリをコーディングして結果を表示するか、電話をコンピュータに接続してそこから評価できるようにすることができます。それでも、Ionicには完全なホットリロード機能があり、選択したアプローチに関係なく、アプリを効率的に開発するのに役立ちます。

NativeScript:ネイティブスクリプト5.3以降、VSCodeからのデバッグ、スタイリング編集、JavaScript編集、さらにはファイル編集をサポートする素晴らしいHMR –ホットモジュール置換機能を公式にサポートしています。

開始時に実行されるLiveSync機能を使用するrun or debug on deviceと、Ionicの場合と同様に、アプリに変更を加えて、接続されているすべてのデバイスとエミュレーターにリアルタイムで適用されたものを確認できます。

デバッグツール

開発者は、「デバッグは、そもそもコードを書くよりも2倍難しい」と言うことがあります。これは私たちの仕事の中で最も難しい部分の1つと見なすことができるので、なぜツールがそれを難し​​くする必要があるのでしょうか。

ツールはハイブリッドであるだけでなく、常にネイティブに互換性があるとは限らないため、モバイルクロスプラットフォームのデバッグは常に不安でした。

ここでは、比較中に、フレームワークのデバッグツールとエラーレポート機能を組み合わせます。

React Native:ホットリロードと同様に、コアチームによって公式にサポートされているツールがないため、ReactNativeを使用したデバッグは常に「大雑把」でした。

ただし、React Native 0.62では、3月26日以降のデフォルトのRNデバッガーであるFlipperを発表しました。Flipperには、デバッガーに必要な優れた機能があります。

  • 利用可能なReactDevTools
  • ネットワーク、レイアウト、データベース、および設定インスペクター
  • アプリのリロードに役立つメトロアクション
  • クラッシュレポートとデバイスログ。

FlutterFlutter DevToolsは、非常に強力で完全な機能です。シンプルなコンソール出力から、ビジュアルウィジェット分析、ネットワークおよびパフォーマンス検査に至るまで、ほぼすべてのユースケースに適合します。

Flutterは、おそらく5つのフレームワークの中で最高のデバッグ機能を備えています。

Xamarin:XamarinはAndroidアプリとiOSアプリを異なる方法でデバッグします。Androidアプリは、他の.NETアプリケーションと同じようにデバッグされます。デバッグ構成でデバイスを実行した後、ブレークポイントを追加してアプリの実行を追跡できます。

Xamarin.iOSは、Mono Softデバッガー、生成されたコード、およびMonoランタイムをIDEと連携して使用し、デバッグエクスペリエンスを提供します。

Ionic :彼らのドキュメントでは 、フレームワークがWebデバッガーを使用して簡単にデバッグ可能なハイブリッドアプリ(WebビューのHTML、CSS、JavaScript)を作成するため、Ionicは幅広いデバッグ機能を提供します。

より良いログまたはより深いデバッグを表示したい場合、 Cordovaはほとんどすべてのニーズに適合するVSCode拡張機能を提供します。

NativeScript:コマンドtns debug <platform>を使用すると、NativeScriptを使用してデバッグセッションを簡単に開始し、Livesyncを開始できます。

ただし、デバッグの出力はコンソールに出力され、行ったすべての変更はアプリと同期されます。ただし、 VSCode拡張機能を使用すると、はるかに優れたデバッグエクスペリエンスが可能になることに注意してください。

さらに、NativeScriptプラグインのデバッグに関するこのブログ投稿は、開発者が使用するプラグインのネイティブソースコードのデバッグにどのように取り組むことができるかを説明する、NativeScriptアウトラインを使用したアプリの構築とデバッグに深く取り組むのに役立ちます。

さらなる比較

上記は、開発者が使用するツールを引き付け、維持する主な要因です。次に、開発者がクロスプラットフォームツールでの作業に費やす時間を楽しむことができるオプションのものを見てみましょう。

コードエディタ/IDEの統合

上記の5つのフレームワークのうち、Flutterは、サポートするさまざまなエディター用に出荷されるプラグインと統合のパワーにより、最高のように聞こえるかもしれません。

Flutter拡張機能をVSCodeにインストールすると、完全なデバッグサポート、スキャフォールディングスニペット、美しい構文の強調表示、およびコード補完を備えたIDEになっているようにすぐに感じ始めます。

Flutterのツールほど高度ではありませんが、React Nativeには、ReactNativeアプリをすばやく簡単に実行およびデバッグするのに役立つMicrosoftのReactNativeToolsもあります。

Xamarinは、フレームワークのインストールを決定したときにVS2019がXamarin開発に必要なすべてを提供するため優れています。これにより、開発者はIDEから必要なものをすべて取得できるため、開発者はツールに固執します。

IonicとNativeScriptを使用すると、HTML、JSX、CSS、SASS、Angular、React、Vueなどの人気のあるフロントエンドツールを使用するため、ほとんどのWeb開発エディターで問題ありません。これらのツールは既存のエディターですでに十分にサポートされています。

サードパーティモジュール

Advanced React Nativeアプリは、サードパーティのモジュールに大きく依存しています。サードパーティのモジュールは、他のモジュールや現在のバージョンのフレームワークとの互換性のために、不足している部分で更新するとすぐにパズルになる可能性があります。

ただし、React Nativeコミュニティは驚くほど大きいため、アプリの構築に非常に役立つ可能性のある多くのオープンソースパッケージがnpmで利用できます。

この問題は、FlutterとXamarinのマイナーな問題です。これは、クロスプラットフォームアプリを構築するために必要なほとんどの準備が整っており、更新プロセスがそれぞれのYAMLファイルとXMLファイルによって適切に管理されているためです。

Flutterには独自のパッケージマネージャーWebサイト があり、Flutterパッケージの使用例を検索および表示できます。

Ionic自体には、マテリアルまたはiOS UIアプリの構築に必要なほとんどのUIコンポーネントが付属しており、設計ガイドラインを尊重しています。ただし、ネイティブ機能にアクセスするには、Cordovaのネイティブプラグインに強く依存しています。これらのプラグインは、最新ではないか、ドキュメントが不足している可能性があります。

NativeScriptは、Ionicと同様に、見栄えの良いUIコンポーネントが多数バンドルされています。ただし、ネイティブプラグインは、NativeScriptのチームとそのコミュニティによって利用および開発され、専用のマーケットプレイスで紹介されています。

結論

5つのフレームワークはすべて大きなコミュニティを持っており、企業間で広く使用されているため、すでに主要なクロスプラットフォームツールとして知られています。それぞれに独自のワークフローがあり、それぞれのユースケースに合わせて調整できます。

それでも、それぞれの長所と制限を理解し、どのタスクとチームを扱っているかに応じて選択することが重要です。

ソース:https ://blog.logrocket.com/comparing-developer-experience-for-cross-platform-frameworks/

#frameworks #xamarin #flutter #ionic #react 

クロスプラットフォームフレームワークの開発者エクスペリエンスの比較

Essential Cross Platform APIs for Your Mobile Apps Written in .NET

Xamarin.Essentials

Xamarin.Essentials gives developers essential cross-platform APIs for their mobile applications.

iOS, Android, and UWP offer unique operating system and platform APIs that developers have access to, all in C# leveraging Xamarin. It is great that developers have 100% API access in C# with Xamarin, but these APIs are different per platform. This means developers have to learn three different APIs to access platform-specific features. With Xamarin.Essentials, developers have a single cross-platform API that works with any iOS, Android, or UWP application that can be accessed from shared code no matter how the user interface is created.

Questions

Get your technical questions answered by experts on Microsoft Q&A.

Contribution Discussion

Contributing to Xamarin.Essentials? Join our Discord server and chat with the team

Build Status

Build ServerTypePlatformStatus
VSTSBuildWindowsBuild Status
App CenterSample AppAndroidBuild status
App CenterSample AppiOSBuild status

Sample App

Try out Xamarin.Essentials on your device!

Installation

Xamarin.Essentials is available via NuGet & is included in every template:

Please read our Getting Started with Xamarin.Essentials guide for full setup instructions.

Documentation

Browse our full documentation for Xamarin.Essentials, including feature guides, on how to use each feature.

Supported Platforms

Platform support & feature support can be found on our documentation

Contributing

Please read through our Contribution Guide. We are not accepting new PRs for full features, however any issue that is marked as up for grabs are open for community contributions. We encourage creating new issues for bugs found during usage that the team will triage. Additionally, we are open for code refactoring suggestions in PRs.

Building Xamarin.Essentials

Xamarin.Essentials is built with the new SDK-style projects with multi-targeting enabled. This means that all code for iOS, Android, and UWP exist inside of the Xamarin.Essentials project.

Visual Studio

A minimum version of Visual Studio 2019 16.3 or Visual Studio for Mac 2019 8.3 are required to build and compile Xamarin.Essentials.

Workloads needed:

  • Xamarin
  • .NET Core
  • UWP

You will need the following SDKs

  • Android 10.0, 9.0, 8.1, 8.0, 7.1, 7.0, & 6.0 SDK Installed
  • UWP 10.0.16299 SDK Installed

Your can run the included android-setup.ps1 script in Administrator Mode and it will automatically setup your Android environment.

FAQ

Here are some frequently asked questions about Xamarin.Essentials, but be sure to read our full FAQ on our Wiki.

Stats

Download Details:
Author: xamarin
Source Code: https://github.com/xamarin/Essentials
License: View license

#dotnet  #aspdotnet  #csharp #xamarin 

Essential Cross Platform APIs for Your Mobile Apps Written in .NET

MessagePack For C# (.NET, .NET Core, Unity, Xamarin)

MessagePack for C# (.NET, .NET Core, Unity, Xamarin)

The extremely fast MessagePack serializer for C#. It is 10x faster than MsgPack-Cli and outperforms other C# serializers. MessagePack for C# also ships with built-in support for LZ4 compression - an extremely fast compression algorithm. Performance is important, particularly in applications like games, distributed computing, microservices, or data caches.

Perf comparison graph

MessagePack has a compact binary size and a full set of general purpose expressive data types. Please have a look at the comparison with JSON, protobuf, ZeroFormatter section and learn why MessagePack C# is the fastest.

Table of Contents

Installation

This library is distributed via NuGet. Special Unity support is available, too.

We target .NET Standard 2.0 with special optimizations for .NET Core 2.1+, making it compatible with most reasonably recent .NET runtimes such as Core 2.0 and later, Framework 4.6.1 and later, Mono 5.4 and later and Unity 2018.3 and later. The library code is pure C# (with Just-In-Time IL code generation on some platforms).

NuGet packages

To install with NuGet, just install the MessagePack package:

Install-Package MessagePack

Install the optional C# analyzers package to get warnings about coding mistakes and automatic fix suggestions to save you time:

Install-Package MessagePackAnalyzer

There are also a range of official and third party Extension Packages available (learn more in our extensions section):

Install-Package MessagePack.ReactiveProperty
Install-Package MessagePack.UnityShims
Install-Package MessagePack.AspNetCoreMvcFormatter

Unity

For Unity projects, the releases page provides downloadable .unitypackage files. When using in Unity IL2CPP or Xamarin AOT environments, please carefully read the pre-code generation section.

Migration notes from v1.x

If you were using MessagePack for C# v1.x, check out the "How to update to our new v2.x version" document.

Quick Start

Define the struct or class to be serialized and annotate it with a [MessagePackObject] attribute. Annotate members whose values should be serialized (fields as well as properties) with [Key] attributes.

[MessagePackObject]
public class MyClass
{
    // Key attributes take a serialization index (or string name)
    // The values must be unique and versioning has to be considered as well.
    // Keys are described in later sections in more detail.
    [Key(0)]
    public int Age { get; set; }

    [Key(1)]
    public string FirstName { get; set; }

    [Key(2)]
    public string LastName { get; set; }

    // All fields or properties that should not be serialized must be annotated with [IgnoreMember].
    [IgnoreMember]
    public string FullName { get { return FirstName + LastName; } }
}

Call MessagePackSerializer.Serialize<T>/Deserialize<T> to serialize/deserialize your object instance. You can use the ConvertToJson method to get a human readable representation of any MessagePack binary blob.

class Program
{
    static void Main(string[] args)
    {
        var mc = new MyClass
        {
            Age = 99,
            FirstName = "hoge",
            LastName = "huga",
        };

        // Call Serialize/Deserialize, that's all.
        byte[] bytes = MessagePackSerializer.Serialize(mc);
        MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes);

        // You can dump MessagePack binary blobs to human readable json.
        // Using indexed keys (as opposed to string keys) will serialize to MessagePack arrays,
        // hence property names are not available.
        // [99,"hoge","huga"]
        var json = MessagePackSerializer.ConvertToJson(bytes);
        Console.WriteLine(json);
    }
}

By default, a MessagePackObject annotation is required. This can be made optional; see the Object Serialization section and the Formatter Resolver section for details.

Analyzer

The MessagePackAnalyzer package aids with:

  1. Automating definitions for your serializable objects.
  2. Produces compiler warnings upon incorrect attribute use, member accessibility, and more.

analyzergif

If you want to allow a specific custom type (for example, when registering a custom type), put MessagePackAnalyzer.json at the project root and change the Build Action to AdditionalFiles.

image

An example MessagePackAnalyzer.json:

[ "MyNamespace.FooClass", "MyNameSpace.BarStruct" ]

Built-in supported types

These types can serialize by default:

  • Primitives (int, string, etc...), Enums, Nullable<>, Lazy<>
  • TimeSpan, DateTime, DateTimeOffset
  • Guid, Uri, Version, StringBuilder
  • BigInteger, Complex, Half
  • Array[], Array[,], Array[,,], Array[,,,], ArraySegment<>, BitArray
  • KeyValuePair<,>, Tuple<,...>, ValueTuple<,...>
  • ArrayList, Hashtable
  • List<>, LinkedList<>, Queue<>, Stack<>, HashSet<>, ReadOnlyCollection<>, SortedList<,>
  • IList<>, ICollection<>, IEnumerable<>, IReadOnlyCollection<>, IReadOnlyList<>
  • Dictionary<,>, IDictionary<,>, SortedDictionary<,>, ILookup<,>, IGrouping<,>, ReadOnlyDictionary<,>, IReadOnlyDictionary<,>
  • ObservableCollection<>, ReadOnlyObservableCollection<>
  • ISet<>,
  • ConcurrentBag<>, ConcurrentQueue<>, ConcurrentStack<>, ConcurrentDictionary<,>
  • Immutable collections (ImmutableList<>, etc)
  • Custom implementations of ICollection<> or IDictionary<,> with a parameterless constructor
  • Custom implementations of IList or IDictionary with a parameterless constructor

You can add support for custom types, and there are some official/third-party extension packages for:

  • ReactiveProperty
  • for Unity (Vector3, Quaternion, etc...)
  • F# (Record, FsList, Discriminated Unions, etc...)

Please see the extensions section.

MessagePack.Nil is the built-in type representing null/void in MessagePack for C#.

Object Serialization

MessagePack for C# can serialize your own public class or struct types. By default, serializable types must be annotated with the [MessagePackObject] attribute and members with the [Key] attribute. Keys can be either indexes (int) or arbitrary strings. If all keys are indexes, arrays are used for serialization, which offers advantages in performance and binary size. Otherwise, MessagePack maps (dictionaries) will be used.

If you use [MessagePackObject(keyAsPropertyName: true)], then members do not require explicit Key attributes, but string keys will be used.

[MessagePackObject]
public class Sample1
{
    [Key(0)]
    public int Foo { get; set; }
    [Key(1)]
    public int Bar { get; set; }
}

[MessagePackObject]
public class Sample2
{
    [Key("foo")]
    public int Foo { get; set; }
    [Key("bar")]
    public int Bar { get; set; }
}

[MessagePackObject(keyAsPropertyName: true)]
public class Sample3
{
    // No need for a Key attribute
    public int Foo { get; set; }

    // If want to ignore a public member, you can use the  IgnoreMember attribute
    [IgnoreMember]
    public int Bar { get; set; }
}

// [10,20]
Console.WriteLine(MessagePackSerializer.SerializeToJson(new Sample1 { Foo = 10, Bar = 20 }));

// {"foo":10,"bar":20}
Console.WriteLine(MessagePackSerializer.SerializeToJson(new Sample2 { Foo = 10, Bar = 20 }));

// {"Foo":10}
Console.WriteLine(MessagePackSerializer.SerializeToJson(new Sample3 { Foo = 10, Bar = 20 }));

All public instance members (fields as well as properties) will be serialized. If you want to ignore certain public members, annotate the member with a [IgnoreMember] attribute.

Please note that any serializable struct or class must have public accessibility; private and internal structs and classes cannot be serialized! The default of requiring MessagePackObject annotations is meant to enforce explicitness and therefore may help write more robust code.

Should you use an indexed (int) key or a string key? We recommend using indexed keys for faster serialization and a more compact binary representation than string keys. However, the additional information in the strings of string keys can be quite useful when debugging.

When classes change or are extended, be careful about versioning. MessagePackSerializer will initialize members to their default value if a key does not exist in the serialized binary blob, meaning members using reference types can be initialized to null. If you use indexed (int) keys, the keys should start at 0 and should be sequential. If a later version stops using certain members, you should keep the obsolete members (C# provides an Obsolete attribute to annotate such members) until all other clients had a chance to update and remove their uses of these members as well. Also, when the values of indexed keys "jump" a lot, leaving gaps in the sequence, it will negatively affect the binary size, as null placeholders will be inserted into the resulting arrays. However, you shouldn't reuse indexes of removed members to avoid compatibility issues between clients or when trying to deserialize legacy blobs.

Example of index gaps and resulting placeholders:

[MessagePackObject]
public class IntKeySample
{
    [Key(3)]
    public int A { get; set; }
    [Key(10)]
    public int B { get; set; }
}

// [null,null,null,0,null,null,null,null,null,null,0]
Console.WriteLine(MessagePackSerializer.SerializeToJson(new IntKeySample()));

If you do not want to explicitly annotate with the MessagePackObject/Key attributes and instead want to use MessagePack for C# more like e.g. Json.NET, you can make use of the contractless resolver.

public class ContractlessSample
{
    public int MyProperty1 { get; set; }
    public int MyProperty2 { get; set; }
}

var data = new ContractlessSample { MyProperty1 = 99, MyProperty2 = 9999 };
var bin = MessagePackSerializer.Serialize(
  data,
  MessagePack.Resolvers.ContractlessStandardResolver.Options);

// {"MyProperty1":99,"MyProperty2":9999}
Console.WriteLine(MessagePackSerializer.ConvertToJson(bin));

// You can also set ContractlessStandardResolver as the default.
// (Global state; Not recommended when writing library code)
MessagePackSerializer.DefaultOptions = MessagePack.Resolvers.ContractlessStandardResolver.Options;

// Now serializable...
var bin2 = MessagePackSerializer.Serialize(data);

If you want to serialize private members as well, you can use one of the *AllowPrivate resolvers.

[MessagePackObject]
public class PrivateSample
{
    [Key(0)]
    int x;

    public void SetX(int v)
    {
        x = v;
    }

    public int GetX()
    {
        return x;
    }
}

var data = new PrivateSample();
data.SetX(9999);

// You can choose either StandardResolverAllowPrivate
// or ContractlessStandardResolverAllowPrivate
var bin = MessagePackSerializer.Serialize(
  data,
  MessagePack.Resolvers.DynamicObjectResolverAllowPrivate.Options);

If you want to use MessagePack for C# more like a BinaryFormatter with a typeless serialization API, use the typeless resolver and helpers. Please consult the Typeless section.

Resolvers are the way to add specialized support for custom types to MessagePack for C#. Please refer to the Extension point section.

DataContract compatibility

You can use [DataContract] annotations instead of [MessagePackObject] ones. If type is annotated with DataContract, you can use [DataMember] annotations instead of [Key] ones and [IgnoreDataMember] instead of [IgnoreMember].

Then [DataMember(Order = int)] will behave the same as [Key(int)], [DataMember(Name = string)] the same as [Key(string)], and [DataMember] the same as [Key(nameof(member name)].

Using DataContract, e.g. in shared libraries, makes your classes/structs independent from MessagePack for C# serialization. However, it is not supported by the analyzers nor in code generation by the mpc tool. Also, features like UnionAttribute, MessagePackFormatter, SerializationConstructor, etc can not be used. Due to this, we recommend that you use the specific MessagePack for C# annotations when possible.

Serializing readonly/immutable object members (SerializationConstructor)

MessagePack for C# supports serialization of readonly/immutable objects/members. For example, this struct can be serialized and deserialized.

[MessagePackObject]
public struct Point
{
    [Key(0)]
    public readonly int X;
    [Key(1)]
    public readonly int Y;

    public Point(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }
}

var data = new Point(99, 9999);
var bin = MessagePackSerializer.Serialize(data);

// Okay to deserialize immutable object
var point = MessagePackSerializer.Deserialize<Point>(bin);

MessagePackSerializer will choose the constructor with the best matched argument list, using argument indexes index for index keys, or parameter names for string keys. If it cannot determine an appropriate constructor, a MessagePackDynamicObjectResolverException: can't find matched constructor parameter exception will be thrown. You can specify which constructor to use manually with a [SerializationConstructor] annotation.

[MessagePackObject]
public struct Point
{
    [Key(0)]
    public readonly int X;
    [Key(1)]
    public readonly int Y;

    [SerializationConstructor]
    public Point(int x)
    {
        this.X = x;
        this.Y = -1;
    }

    // If not marked attribute, used this(most matched argument)
    public Point(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }
}

C# 9 record types

C# 9.0 record with primary constructor is similar immutable object, also supports serialize/deserialize.

// use key as property name
[MessagePackObject(true)]public record Point(int X, int Y);

// use property: to set KeyAttribute
[MessagePackObject] public record Point([property:Key(0)] int X, [property: Key(1)] int Y);

// Or use explicit properties
[MessagePackObject]
public record Person
{
    [Key(0)]
    public string FirstName { get; init; }

    [Key(1)]
    public string LastName { get; init; }
}

C# 9 init property setter limitations

When using init property setters in generic classes, a CLR bug prevents our most efficient code generation from invoking the property setter. As a result, you should avoid using init on property setters in generic classes when using the public-only DynamicObjectResolver/StandardResolver.

When using the DynamicObjectResolverAllowPrivate/StandardResolverAllowPrivate resolver the bug does not apply and you may use init without restriction.

Serialization Callback

Objects implementing the IMessagePackSerializationCallbackReceiver interface will received OnBeforeSerialize and OnAfterDeserialize calls during serialization/deserialization.

[MessagePackObject]
public class SampleCallback : IMessagePackSerializationCallbackReceiver
{
    [Key(0)]
    public int Key { get; set; }

    public void OnBeforeSerialize()
    {
        Console.WriteLine("OnBefore");
    }

    public void OnAfterDeserialize()
    {
        Console.WriteLine("OnAfter");
    }
}

Union

MessagePack for C# supports serializing interface-typed and abstract class-typed objects. It behaves like XmlInclude or ProtoInclude. In MessagePack for C# these are called Union. Only interfaces and abstracts classes are allowed to be annotated with Union attributes. Unique union keys are required.

// Annotate inheritance types
[MessagePack.Union(0, typeof(FooClass))]
[MessagePack.Union(1, typeof(BarClass))]
public interface IUnionSample
{
}

[MessagePackObject]
public class FooClass : IUnionSample
{
    [Key(0)]
    public int XYZ { get; set; }
}

[MessagePackObject]
public class BarClass : IUnionSample
{
    [Key(0)]
    public string OPQ { get; set; }
}

// ---

IUnionSample data = new FooClass() { XYZ = 999 };

// Serialize interface-typed object.
var bin = MessagePackSerializer.Serialize(data);

// Deserialize again.
var reData = MessagePackSerializer.Deserialize<IUnionSample>(bin);

// Use with e.g. type-switching in C# 7.0
switch (reData)
{
    case FooClass x:
        Console.WriteLine(x.XYZ);
        break;
    case BarClass x:
        Console.WriteLine(x.OPQ);
        break;
    default:
        break;
}

Unions are internally serialized to two-element arrays.

IUnionSample data = new BarClass { OPQ = "FooBar" };

var bin = MessagePackSerializer.Serialize(data);

// Union is serialized to two-length array, [key, object]
// [1,["FooBar"]]
Console.WriteLine(MessagePackSerializer.ConvertToJson(bin));

Using Union with abstract classes works the same way.

[Union(0, typeof(SubUnionType1))]
[Union(1, typeof(SubUnionType2))]
[MessagePackObject]
public abstract class ParentUnionType
{
    [Key(0)]
    public int MyProperty { get; set; }
}

[MessagePackObject]
public class SubUnionType1 : ParentUnionType
{
    [Key(1)]
    public int MyProperty1 { get; set; }
}

[MessagePackObject]
public class SubUnionType2 : ParentUnionType
{
    [Key(1)]
    public int MyProperty2 { get; set; }
}

Please be mindful that you cannot reuse the same keys in derived types that are already present in the parent type, as internally a single flat array or map will be used and thus cannot have duplicate indexes/keys.

Dynamic (Untyped) Deserialization

When calling MessagePackSerializer.Deserialize<object> or MessagePackSerializer.Deserialize<dynamic>, any values present in the blob will be converted to primitive values, i.e. bool, char, sbyte, byte, short, int, long, ushort, uint, ulong, float, double, DateTime, string, byte[], object[], IDictionary<object, object>.

// Sample blob.
var model = new DynamicModel { Name = "foobar", Items = new[] { 1, 10, 100, 1000 } };
var blob = MessagePackSerializer.Serialize(model, ContractlessStandardResolver.Options);

// Dynamic ("untyped")
var dynamicModel = MessagePackSerializer.Deserialize<dynamic>(blob, ContractlessStandardResolver.Options);

// You can access the data using array/dictionary indexers, as shown above
Console.WriteLine(dynamicModel["Name"]); // foobar
Console.WriteLine(dynamicModel["Items"][2]); // 100

Exploring object trees using the dictionary indexer syntax is the fastest option for untyped deserialization, but it is tedious to read and write. Where performance is not as important as code readability, consider deserializing with ExpandoObject.

Object Type Serialization

StandardResolver and ContractlessStandardResolver can serialize object/anonymous typed objects.

var objects = new object[] { 1, "aaa", new ObjectFieldType { Anything = 9999 } };
var bin = MessagePackSerializer.Serialize(objects);

// [1,"aaa",[9999]]
Console.WriteLine(MessagePackSerializer.ConvertToJson(bin));

// Support anonymous Type Serialize
var anonType = new { Foo = 100, Bar = "foobar" };
var bin2 = MessagePackSerializer.Serialize(anonType, MessagePack.Resolvers.ContractlessStandardResolver.Options);

// {"Foo":100,"Bar":"foobar"}
Console.WriteLine(MessagePackSerializer.ConvertToJson(bin2));

Unity supports is limited.

When deserializing, the behavior will be the same as Dynamic (Untyped) Deserialization.

Typeless

The typeless API is similar to BinaryFormatter, as it will embed type information into the blobs, so no types need to be specified explicitly when calling the API.

object mc = new Sandbox.MyClass()
{
    Age = 10,
    FirstName = "hoge",
    LastName = "huga"
};

// Serialize with the typeless API
var blob = MessagePackSerializer.Typeless.Serialize(mc);

// Blob has embedded type-assembly information.
// ["Sandbox.MyClass, Sandbox",10,"hoge","huga"]
Console.WriteLine(MessagePackSerializer.ConvertToJson(bin));

// You can deserialize to MyClass again with the typeless API
// Note that no type has to be specified explicitly in the Deserialize call
// as type information is embedded in the binary blob
var objModel = MessagePackSerializer.Typeless.Deserialize(bin) as MyClass;

Type information is represented by the MessagePack ext format, type code 100.

MessagePackSerializer.Typeless is a shortcut of Serialize/Deserialize<object>(TypelessContractlessStandardResolver.Instance). If you want to configure it as the default resolver, you can use MessagePackSerializer.Typeless.RegisterDefaultResolver.

TypelessFormatter can used standalone or combined with other resolvers.

// Replaced `object` uses the typeless resolver
var resolver = MessagePack.Resolvers.CompositeResolver.Create(
    new[] { MessagePack.Formatters.TypelessFormatter.Instance },
    new[] { MessagePack.Resolvers.StandardResolver.Instance });

public class Foo
{
    // use Typeless(this field only)
    [MessagePackFormatter(typeof(TypelessFormatter))]
    public object Bar;
}

If a type's name is changed later, you can no longer deserialize old blobs. But you can specify a fallback name in such cases, providing a TypelessFormatter.BindToType function of your own.

MessagePack.Formatters.TypelessFormatter.BindToType = typeName =>
{
    if (typeName.StartsWith("SomeNamespace"))
    {
        typeName = typeName.Replace("SomeNamespace", "AnotherNamespace");
    }

    return Type.GetType(typeName, false);
};

Security

Deserializing data from an untrusted source can introduce security vulnerabilities in your application. Depending on the settings used during deserialization, untrusted data may be able to execute arbitrary code or cause a denial of service attack. Untrusted data might come from over the network from an untrusted source (e.g. any and every networked client) or can be tampered with by an intermediary when transmitted over an unauthenticated connection, or from a local storage that might have been tampered with, or many other sources. MessagePack for C# does not provide any means to authenticate data or make it tamper-resistant. Please use an appropriate method of authenticating data before deserialization - such as a MAC .

Please be very mindful of these attack scenarios; many projects and companies, and serialization library users in general, have been bitten by untrusted user data deserialization in the past.

When deserializing untrusted data, put MessagePack into a more secure mode by configuring your MessagePackSerializerOptions.Security property:

var options = MessagePackSerializerOptions.Standard
    .WithSecurity(MessagePackSecurity.UntrustedData);

// Pass the options explicitly for the greatest control.
T object = MessagePackSerializer.Deserialize<T>(data, options);

// Or set the security level as the default.
MessagePackSerializer.DefaultOptions = options;

You should also avoid the Typeless serializer/formatters/resolvers for untrusted data as that opens the door for the untrusted data to potentially deserialize unanticipated types that can compromise security.

The UntrustedData mode merely hardens against some common attacks, but is no fully secure solution in itself.

Performance

Benchmarks comparing MessagePack For C# to other serializers were run on Windows 10 Pro x64 Intel Core i7-6700K 4.00GHz, 32GB RAM. Benchmark code is available here - and their version info. ZeroFormatter and FlatBuffers have infinitely fast deserializers, so ignore their deserialization performance.

image

MessagePack for C# uses many techniques to improve performance.

  • The serializer uses IBufferWriter<byte> rather than System.IO.Stream to reduce memory overhead.
  • Buffers are rented from pools to reduce allocations, keeping throughput high through reduced GC pressure.
  • Don't create intermediate utility instances (*Writer/*Reader, *Context, etc...)
  • Utilize dynamic code generation and JIT to avoid boxing value types. Use AOT generation on platforms that prohibit JITs.
  • Cached generated formatters on static generic fields (don't use dictionary-cache because dictionary lookup is overhead). See Resolvers
  • Heavily tuned dynamic IL code generation and JIT to avoid boxing value types. See DynamicObjectTypeBuilder. Use AOT generation on platforms that prohibit JIT.
  • Call the Primitive API directly when IL code generation determines target types to be primitive.
  • Reduce branching of variable length formats when IL code generation knows the target type (integer/string) ranges
  • Don't use the IEnumerable<T> abstraction to iterate over collections when possible, see: CollectionFormatterBase and derived collection formatters
  • Use pre-generated lookup tables to reduce checks of mgpack type constraints, see: MessagePackBinary
  • Uses optimized type key dictionary for non-generic methods, see: ThreadsafeTypeKeyHashTable
  • Avoid string key decoding for lookup maps (string key and use automata based name lookup with inlined IL code generation, see: AutomataDictionary
  • To encode string keys, use pre-generated member name bytes and fixed sized byte array copies in IL, see: UnsafeMemory.cs

Before creating this library, I implemented a fast fast serializer with ZeroFormatter#Performance. This is a further evolved implementation. MessagePack for C# is always fast and optimized for all types (primitive, small struct, large object, any collections).

Deserialization Performance for different options

Performance varies depending on the options used. This is a micro benchmark with BenchmarkDotNet. The target object has 9 members (MyProperty1 ~ MyProperty9), values are zero.

MethodMeanErrorScaledGen 0Allocated
M IntKey72.67 nsNA1.000.013256 B
M StringKey217.95 nsNA3.000.013156 B
M Typeless_IntKey176.71 nsNA2.430.013156 B
M Typeless_StringKey378.64 nsNA5.210.012956 B
MsgPackCliMap1,355.26 nsNA18.650.1431608 B
MsgPackCliArray455.28 nsNA6.260.0415176 B
ProtobufNet265.85 nsNA3.660.0319136 B
Hyperion366.47 nsNA5.040.0949400 B
JsonNetString2,783.39 nsNA38.300.67902864 B
JsonNetStreamReader3,297.90 nsNA45.381.42676000 B
JilString553.65 nsNA7.620.0362152 B
JilStreamReader1,408.46 nsNA19.380.84503552 B

ÌntKey, StringKey, Typeless_IntKey, Typeless_StringKey are MessagePack for C# options. All MessagePack for C# options achieve zero memory allocations in the deserialization process. JsonNetString/JilString is deserialized from strings. JsonNetStreamReader/JilStreamReader is deserialized from UTF-8 byte arrays using StreamReader. Deserialization is normally read from Stream. Thus, it will be restored from byte arrays (or Stream) instead of strings.

MessagePack for C# IntKey is the fastest. StringKey is slower than IntKey because matching the character string of property names is required. IntKey works by reading the array length, then for (array length) { binary decode }. StringKey works by reading map length, for (map length) { decode key, lookup key, binary decode }, so it requires an additional two steps (decoding of keys and lookups of keys).

String key is often a useful, contractless, simple replacement of JSON, interoperability with other languages, and more robust versioning. MessagePack for C# is also optimized for string keys as much a possible. First of all, it does not decode UTF-8 byte arrays to full string for matching with the member name; instead it will look up the byte arrays as it is (to avoid decoding costs and extra memory allocations).

And It will try to match each long type (per 8 character, if it is not enough, pad with 0) using automata and inline it when generating IL code.

image

This also avoids calculating the hash code of byte arrays, and the comparison can be made several times faster using the long type.

This is the sample of decompiled generated deserializer code, decompiled using ILSpy.

image

If the number of nodes is large, searches will use an embedded binary search.

Extra note, this is serialization benchmark result.

MethodMeanErrorScaledGen 0Allocated
IntKey84.11 nsNA1.000.009440 B
StringKey126.75 nsNA1.510.0341144 B
Typeless_IntKey183.31 nsNA2.180.0265112 B
Typeless_StringKey193.95 nsNA2.310.0513216 B
MsgPackCliMap967.68 nsNA11.510.1297552 B
MsgPackCliArray284.20 nsNA3.380.1006424 B
ProtobufNet176.43 nsNA2.100.0665280 B
Hyperion280.14 nsNA3.330.1674704 B
ZeroFormatter149.95 nsNA1.780.1009424 B
JsonNetString1,432.55 nsNA17.030.46161944 B
JsonNetStreamWriter1,775.72 nsNA21.111.55266522 B
JilString547.51 nsNA6.510.34811464 B
JilStreamWriter778.78 nsNA9.261.44486066 B

Of course, IntKey is fastest but StringKey also performs reasonably well.

LZ4 Compression

MessagePack is a fast and compact format but it is not compression. LZ4 is an extremely fast compression algorithm, and using it MessagePack for C# can achieve extremely fast performance as well as extremely compact binary sizes!

MessagePack for C# has built-in LZ4 support. You can activate it using a modified options object and passing it into an API like this:

var lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray);
MessagePackSerializer.Serialize(obj, lz4Options);

MessagePackCompression has two modes, Lz4Block and Lz4BlockArray. Neither is a simple binary LZ4 compression, but a special compression integrated into the serialization pipeline, using MessagePack ext code (Lz4BlockArray (98) or Lz4Block (99)). Therefore, it is not readily compatible with compression offered in other languages.

Lz4Block compresses an entire MessagePack sequence as a single LZ4 block. This is the simple compression that achieves best compression ratio, at the cost of copying the entire sequence when necessary to get contiguous memory.

Lz4BlockArray compresses an entire MessagePack sequence as a array of LZ4 blocks. Compressed/decompressed blocks are chunked and thus do not enter the GC's Large-Object-Heap, but the compression ratio is slightly worse.

We recommend to use Lz4BlockArray as the default when using compression. For compatibility with MessagePack v1.x, use Lz4Block.

Regardless of which LZ4 option is set at the deserialization, both methods can be deserialized. For example, when the Lz4BlockArray option was used, binary data using either Lz4Block and Lz4BlockArray can be deserialized. Neither can be decompressed and hence deserialized when the compression option is set to None.

Attributions

LZ4 compression support is using Milosz Krajewski's lz4net code with some modifications.

Comparison with protobuf, JSON, ZeroFormatter

protobuf-net is major, widely used binary-format library on .NET. I love protobuf-net and respect their great work. But when you use protobuf-net as a general purpose serialization format, you may encounter an annoying issue.

[ProtoContract]
public class Parent
{
    [ProtoMember(1)]
    public int Primitive { get; set; }
    [ProtoMember(2)]
    public Child Prop { get; set; }
    [ProtoMember(3)]
    public int[] Array { get; set; }
}

[ProtoContract]
public class Child
{
    [ProtoMember(1)]
    public int Number { get; set; }
}

using (var ms = new MemoryStream())
{
    // serialize null.
    ProtoBuf.Serializer.Serialize<Parent>(ms, null);

    ms.Position = 0;
    var result = ProtoBuf.Serializer.Deserialize<Parent>(ms);

    Console.WriteLine(result != null); // True, not null. but all property are zero formatted.
    Console.WriteLine(result.Primitive); // 0
    Console.WriteLine(result.Prop); // null
    Console.WriteLine(result.Array); // null
}

using (var ms = new MemoryStream())
{
    // serialize empty array.
    ProtoBuf.Serializer.Serialize<Parent>(ms, new Parent { Array = System.Array.Empty<int>() });

    ms.Position = 0;
    var result = ProtoBuf.Serializer.Deserialize<Parent>(ms);

    Console.WriteLine(result.Array == null); // True, null!
}

protobuf(-net) cannot handle null and empty collection correctly, because protobuf has no null representation (see this SO answer from a protobuf-net author).

MessagePack's type system can correctly serialize the entire C# type system. This is a strong reason to recommend MessagePack over protobuf.

Protocol Buffers have good IDL and gRPC support. If you want to use IDL, I recommend Google.Protobuf over MessagePack.

JSON is good general-purpose format. It is simple, human-readable and thoroughly-enough specified. Utf8Json - which I created as well - adopts same architecture as MessagePack for C# and avoids encoding/decoding costs as much as possible just like this library does. If you want to know more about binary vs text formats, see Utf8Json/which serializer should be used.

ZeroFormatter is similar as FlatBuffers but specialized to C#, and special in that regard. Deserialization is infinitely fast but the produced binary size is larger. And ZeroFormatter's caching algorithm requires additional memory.

For many common uses, MessagePack for C# would be a better fit.

Hints to achieve maximum performance when using MessagePack for C#

MessagePack for C# prioritizes maximum performance by default. However, there are also some options that sacrifice performance for convenience.

Use indexed keys instead of string keys (Contractless)

The Deserialization Performance for different options section shows the results of indexed keys (IntKey) vs string keys (StringKey) performance. Indexed keys serialize the object graph as a MessagePack array. String keys serializes the object graph as a MessagePack map.

For example this type is serialized to

[MessagePackObject]
public class Person
{
    [Key(0)] or [Key("name")]
    public string Name { get; set;}
    [Key(1)] or [Key("age")]
    public int Age { get; set;}
}

new Person { Name = "foobar", Age = 999 }
  • IntKey: ["foobar", 999]
  • StringKey: {"name:"foobar","age":999}.

IntKey is always fast in both serialization and deserialization because it does not have to handle and lookup key names, and always has the smaller binary size.

StringKey is often a useful, contractless, simple replacement for JSON, interoperability with other languages with MessagePack support, and less error prone versioning. But to achieve maximum performance, use IntKey.

Create own custom composite resolver

CompositeResolver.Create is an easy way to create composite resolvers. But formatter lookups have some overhead. If you create a custom resolver (or use StaticCompositeResolver.Instance), you can avoid this overhead.

public class MyApplicationResolver : IFormatterResolver
{
    public static readonly IFormatterResolver Instance = new MyApplicationResolver();

    // configure your custom resolvers.
    private static readonly IFormatterResolver[] Resolvers = new IFormatterResolver[]
    {
    };

    private MyApplicationResolver() { }

    public IMessagePackFormatter<T> GetFormatter<T>()
    {
        return Cache<T>.Formatter;
    }

    private static class Cache<T>
    {
        public static IMessagePackFormatter<T> Formatter;

        static Cache()
        {
            // configure your custom formatters.
            if (typeof(T) == typeof(XXX))
            {
                Formatter = new ICustomFormatter();
                return;
            }

            foreach (var resolver in Resolvers)
            {
                var f = resolver.GetFormatter<T>();
                if (f != null)
                {
                    Formatter = f;
                    return;
                }
            }
        }
    }
}

NOTE: If you are creating a library, recommend using the above custom resolver instead of CompositeResolver.Create. Also, libraries must not use StaticCompositeResolver - as it is global state - to avoid compatibility issues.

Use native resolvers

By default, MessagePack for C# serializes GUID as string. This is much slower than the native .NET format GUID. The same applies to Decimal. If your application makes heavy use of GUID or Decimal and you don't have to worry about interoperability with other languages, you can replace them with the native serializers NativeGuidResolver and NativeDecimalResolver respectively.

Also, DateTime is serialized using the MessagePack timestamp format. By using the NativeDateTimeResolver, it is possible to maintain Kind and perform faster serialization.

Be careful when copying buffers

MessagePackSerializer.Serialize returns byte[] in default. The final byte[] is copied from an internal buffer pool. That is an extra cost. You can use IBufferWriter<T> or the Stream API to write to buffers directly. If you want to use a buffer pool outside of the serializer, you should implement custom IBufferWriter<byte> or use an existing one such as Sequence<T> from the Nerdbank.Streams package.

During deserialization, MessagePackSerializer.Deserialize(ReadOnlyMemory<byte> buffer) is better than the Deserialize(Stream stream) overload. This is because the Stream API version starts by reading the data, generating a ReadOnlySequence<byte>, and only then starts the deserialization.

Choosing compression

Compression is generally effective when there is duplicate data. In MessagePack, arrays containing objects using string keys (Contractless) can be compressed efficiently because compression can be applied to many duplicate property names. Indexed keys compression is not as effectively compressed as string keys, but indexed keys are smaller in the first place.

This is some example benchmark performance data;

SerializerMeanDataSize
IntKey2.941 us469.00 B
IntKey(Lz4)3.449 us451.00 B
StringKey4.340 us1023.00 B
StringKey(Lz4)5.469 us868.00 B

IntKey(Lz4) is not as effectively compressed, but performance is still somewhat degraded. On the other hand, StringKey can be expected to have a sufficient effect on the binary size. However, this is just an example. Compression can be quite effective depending on the data, too, or have little effect other than slowing down your program. There are also cases in which well-compressible data exists in the values (such as long strings, e.g. containing HTML data with many repeated HTML tags). It is important to verify the actual effects of compression on a case by case basis.

Extensions

MessagePack for C# has extension points that enable you to provide optimal serialization support for custom types. There are official extension support packages.

Install-Package MessagePack.ReactiveProperty
Install-Package MessagePack.UnityShims
Install-Package MessagePack.AspNetCoreMvcFormatter

The MessagePack.ReactiveProperty package adds support for types of the ReactiveProperty library. It adds ReactiveProperty<>, IReactiveProperty<>, IReadOnlyReactiveProperty<>, ReactiveCollection<>, Unit serialization support. It is useful for save viewmodel state.

The MessagePack.UnityShims package provides shims for Unity's standard structs (Vector2, Vector3, Vector4, Quaternion, Color, Bounds, Rect, AnimationCurve, Keyframe, Matrix4x4, Gradient, Color32, RectOffset, LayerMask, Vector2Int, Vector3Int, RangeInt, RectInt, BoundsInt) and corresponding formatters. It can enable proper communication between servers and Unity clients.

After installation, extension packages must be enabled, by creating composite resolvers. Here is an example showing how to enable all extensions.

// Set extensions to default resolver.
var resolver = MessagePack.Resolvers.CompositeResolver.Create(
    // enable extension packages first
    ReactivePropertyResolver.Instance,
    MessagePack.Unity.Extension.UnityBlitResolver.Instance,
    MessagePack.Unity.UnityResolver.Instance,

    // finally use standard (default) resolver
    StandardResolver.Instance
);
var options = MessagePackSerializerOptions.Standard.WithResolver(resolver);

// Pass options every time or set as default
MessagePackSerializer.DefaultOptions = options;

For configuration details, see: Extension Point section.

The MessagePack.AspNetCoreMvcFormatter is add-on for ASP.NET Core MVC's serialization to boost up performance. This is configuration sample.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddMvcOptions(option =>
    {
        option.OutputFormatters.Clear();
        option.OutputFormatters.Add(new MessagePackOutputFormatter(ContractlessStandardResolver.Options));
        option.InputFormatters.Clear();
        option.InputFormatters.Add(new MessagePackInputFormatter(ContractlessStandardResolver.Options));
    });
}

Other authors are creating extension packages, too.

  • MagicOnion - gRPC based HTTP/2 RPC Streaming Framework
  • MasterMemory - Embedded Readonly In-Memory Document Database

You can make your own extension serializers or integrate with frameworks. Let's create and share!

Experimental Features

MessagePack for C# has experimental features which provides you with very performant formatters. There is an official package.

Install-Package MessagePack.Experimental

For detailed information, see: Experimental.md

API

High-Level API (MessagePackSerializer)

The MessagePackSerializer class is the entry point of MessagePack for C#. Static methods make up the main API of MessagePack for C#.

APIDescription
Serialize<T>Serializes an object graph to a MessagePack binary blob. Async variant for Stream available. Non-generic overloads available.
Deserialize<T>Deserializes a MessagePack binary to an object graph. Async variant for Stream available. Non-generic overloads available.
SerializeToJsonSerialize a MessagePack-compatible object graph to JSON instead of MessagePack. Useful for debugging.
ConvertToJsonConvert MessagePack binary to JSON. Useful for debugging.
ConvertFromJsonConvert JSON to a MessagePack binary.

The MessagePackSerializer.Typeless class offers most of the same APIs as above, but removes all type arguments from the API, forcing serialization to include the full type name of the root object. It uses the TypelessContractlessStandardResolver. Consider the result to be a .NET-specific MessagePack binary that isn't readily compatible with MessagePack deserializers in other runtimes.

MessagePack for C# fundamentally serializes using IBufferWriter<byte> and deserializes using ReadOnlySequence<byte> or Memory<byte>. Method overloads are provided to conveniently use it with common buffer types and the .NET Stream class, but some of these convenience overloads require copying buffers once and therefore have a certain overhead.

The high-level API uses a memory pool internally to avoid unnecessary memory allocation. If result size is under 64K, it allocates GC memory only for the return bytes.

Each serialize/deserialize method takes an optional MessagePackSerializerOptions parameter which can be used to specify a custom IFormatterResolver to use or to activate LZ4 compression support.

Multiple MessagePack structures on a single Stream

To deserialize a Stream that contains multiple consecutive MessagePack data structures, you can use the MessagePackStreamReader class to efficiently identify the ReadOnlySequence<byte> for each data structure and deserialize it. For example:

static async Task<List<T>> DeserializeListFromStreamAsync<T>(Stream stream, CancellationToken cancellationToken)
{
    var dataStructures = new List<T>();
    using (var streamReader = new MessagePackStreamReader(stream))
    {
        while (await streamReader.ReadAsync(cancellationToken) is ReadOnlySequence<byte> msgpack)
        {
            dataStructures.Add(MessagePackSerializer.Deserialize<T>(msgpack, cancellationToken: cancellationToken));
        }
    }

    return dataStructures;
}

Low-Level API (IMessagePackFormatter<T>)

The IMessagePackFormatter<T> interface is responsible for serializing a unique type. For example Int32Formatter : IMessagePackFormatter<Int32> represents Int32 MessagePack serializer.

public interface IMessagePackFormatter<T>
{
    void Serialize(ref MessagePackWriter writer, T value, MessagePackSerializerOptions options);
    T Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options);
}

Many built-in formatters exists under MessagePack.Formatters. Your custom types are usually automatically supported with the built-in type resolvers that generate new IMessagePackFormatter<T> types on-the-fly using dynamic code generation. See our AOT code generation support for platforms that do not support this.

However, some types - especially those provided by third party libraries or the runtime itself - cannot be appropriately annotated, and contractless serialization would produce inefficient or even wrong results. To take more control over the serialization of such custom types, write your own IMessagePackFormatter<T> implementation. Here is an example of such a custom formatter implementation. Note its use of the primitive API that is described in the next section.

/// <summary>Serializes a <see cref="FileInfo" /> by its full path as a string.</summary>
public class FileInfoFormatter : IMessagePackFormatter<FileInfo>
{
    public void Serialize(
      ref MessagePackWriter writer, FileInfo value, MessagePackSerializerOptions options)
    {
        if (value == null)
        {
            writer.WriteNil();
            return;
        }

        writer.WriteString(value.FullName);
    }

    public FileInfo Deserialize(
      ref MessagePackReader reader, MessagePackSerializerOptions options)
    {
        if (reader.TryReadNil())
        {
            return null;
        }

        options.Security.DepthStep(ref reader);

        var path = reader.ReadString();

        reader.Depth--;
        return new FileInfo(path);
    }
}

The DepthStep and Depth-- statements provide a level of security while deserializing untrusted data that might otherwise be able to execute a denial of service attack by sending MessagePack data that would deserialize into a very deep object graph leading to a StackOverflowException that would crash the process. This pair of statements should surround the bulk of any IMessagePackFormatter<T>.Deserialize method.

Important: A message pack formatter must read or write exactly one data structure. In the above example we just read/write a string. If you have more than one element to write out, you must precede it with a map or array header. You must read the entire map/array when deserializing. For example:

public class MySpecialObjectFormatter : IMessagePackFormatter<MySpecialObject>
{
    public void Serialize(
      ref MessagePackWriter writer, MySpecialObject value, MessagePackSerializerOptions options)
    {
        if (value == null)
        {
            writer.WriteNil();
            return;
        }

        writer.WriteArrayHeader(2);
        writer.WriteString(value.FullName);
        writer.WriteString(value.Age);
    }

    public MySpecialObject Deserialize(
      ref MessagePackReader reader, MessagePackSerializerOptions options)
    {
        if (reader.TryReadNil())
        {
            return null;
        }

        options.Security.DepthStep(ref reader);

        string fullName = null;
        int age = 0;

        // Loop over *all* array elements independently of how many we expect,
        // since if we're serializing an older/newer version of this object it might
        // vary in number of elements that were serialized, but the contract of the formatter
        // is that exactly one data structure must be read, regardless.
        // Alternatively, we could check that the size of the array/map is what we expect
        // and throw if it is not.
        int count = reader.ReadArrayHeader();
        for (int i = 0; i < count; i++)
        {
            switch (i)
            {
                case 0:
                    fullName = reader.ReadString();
                    break;
                case 1:
                    age = reader.ReadInt32();
                    break;
                default:
                    reader.Skip();
                    break;
            }
        }

        reader.Depth--;
        return new MySpecialObject(fullName, age);
    }
}

Your custom formatters must be discoverable via some IFormatterResolver. Learn more in our resolvers section.

You can see many other samples from builtin formatters.

Primitive API (MessagePackWriter, MessagePackReader)

The MessagePackWriter and MessagePackReader structs make up the lowest-level API. They read and write the primitives types defined in the MessagePack specification.

MessagePackReader

A MessagePackReader can efficiently read from ReadOnlyMemory<byte> or ReadOnlySequence<byte> without any allocations, except to allocate a new string as required by the ReadString() method. All other methods return either value structs or ReadOnlySequence<byte> slices for extensions/arrays. Reading directly from ReadOnlySequence<byte> means the reader can directly consume some modern high performance APIs such as PipeReader.

MethodDescription
SkipAdvances the reader's position past the current value. If the value is complex (e.g. map, array) the entire structure is skipped.
Read*Read and return a value whose type is named by the method name from the current reader position. Throws if the expected type does not match the actual type. When reading numbers, the type need not match the binary-specified type exactly. The numeric value will be coerced into the desired type or throw if the integer type is too small for a large value.
TryReadNilAdvances beyond the current value if the current value is nil and returns true; otherwise leaves the reader's position unchanged and returns false.
ReadBytesReturns a slice of the input sequence representing the contents of a byte[], and advances the reader.
ReadStringSequenceReturns a slice of the input sequence representing the contents of a string without decoding it, and advances the reader.
CloneCreates a new MessagePackReader with the specified input sequence and the same settings as the original reader.
CreatePeekReaderCreates a new reader with the same position as this one, allowing the caller to "read ahead" without impacting the original reader's position.
NextCodeReads the low-level MessagePack byte that describes the type of the next value. Does not advance the reader. See MessagePack format of first byte. Its static class has ToMessagePackType and ToFormatName utility methods. MessagePackRange means Min-Max fix range of MessagePack format.
NextMessagePackTypeDescribes the NextCode value as a higher level category. Does not advance the reader. See MessagePack spec of source types.
(others)Other methods and properties as described by the .xml doc comment file and Intellisense.

The MessagePackReader is capable of automatically interpreting both the old and new MessagePack spec.

MessagePackWriter

A MessagePackWriter writes to a given instance of IBufferWriter<byte>. Several common implementations of this exist, allowing zero allocations and minimal buffer copies while writing directly to several I/O APIs including PipeWriter.

The MessagePackWriter writes the new MessagePack spec by default, but can write MessagePack compatible with the old spec by setting the OldSpec property to true.

MethodDescription
CloneCreates a new MessagePackWriter with the specified underlying IBufferWriter<byte> and the same settings as the original writer.
FlushWrites any buffered bytes to the underlying IBufferWriter<byte>.
WriteNilWrites the MessagePack equivalent of .NET's null value.
WriteWrites any MessagePack primitive value in the most compact form possible. Has overloads for every primitive type defined by the MessagePack spec.
Write*IntType*Writes an integer value in exactly the MessagePack type specified, even if a more compact format exists.
WriteMapHeaderIntroduces a map by specifying the number of key=value pairs it contains.
WriteArrayHeaderIntroduces an array by specifying the number of elements it contains.
WriteExtensionFormatWrites the full content of an extension value including length, type code and content.
WriteExtensionFormatHeaderWrites just the header (length and type code) of an extension value.
WriteRawCopies the specified bytes directly to the underlying IBufferWriter<byte> without any validation.
(others)Other methods and properties as described by the .xml doc comment file and Intellisense.

DateTime is serialized to MessagePack Timestamp format, it serialize/deserialize UTC and loses Kind info and requires that MessagePackWriter.OldSpec == false. If you use the NativeDateTimeResolver, DateTime values will be serialized using .NET's native Int64 representation, which preserves Kind info but may not be interoperable with non-.NET platforms.

Main Extension Point (IFormatterResolver)

An IFormatterResolver is storage of typed serializers. The MessagePackSerializer API accepts a MessagePackSerializerOptions object which specifies the IFormatterResolver to use, allowing customization of the serialization of complex types.

Resolver NameDescription
BuiltinResolverBuiltin primitive and standard classes resolver. It includes primitive(int, bool, string...) and there nullable, array and list. and some extra builtin types(Guid, Uri, BigInteger, etc...).
StandardResolverComposited resolver. It resolves in the following order builtin -> attribute -> dynamic enum -> dynamic generic -> dynamic union -> dynamic object -> dynamic object fallback. This is the default of MessagePackSerializer.
ContractlessStandardResolverComposited StandardResolver(except dynamic object fallback) -> DynamicContractlessObjectResolver -> DynamicObjectTypeFallbackResolver. It enables contractless serialization.
StandardResolverAllowPrivateSame as StandardResolver but allow serialize/deserialize private members.
ContractlessStandardResolverAllowPrivateSame as ContractlessStandardResolver but allow serialize/deserialize private members.
PrimitiveObjectResolverMessagePack primitive object resolver. It is used fallback in object type and supports bool, char, sbyte, byte, short, int, long, ushort, uint, ulong, float, double, DateTime, string, byte[], ICollection, IDictionary.
DynamicObjectTypeFallbackResolverSerialize is used type in from object type, deserialize is used PrimitiveObjectResolver.
AttributeFormatterResolverGet formatter from [MessagePackFormatter] attribute.
CompositeResolverComposes several resolvers and/or formatters together in an ordered list, allowing reuse and overriding of behaviors of existing resolvers and formatters.
NativeDateTimeResolverSerialize by .NET native DateTime binary format. It keeps DateTime.Kind that loses by standard(MessagePack timestamp) format.
NativeGuidResolverSerialize by .NET native Guid binary representation. It is faster than standard(string) representation.
NativeDecimalResolverSerialize by .NET native decimal binary representation. It is faster than standard(string) representation.
DynamicEnumResolverResolver of enum and there nullable, serialize there underlying type. It uses dynamic code generation to avoid boxing and boostup performance serialize there name.
DynamicEnumAsStringResolverResolver of enum and there nullable. It uses reflection call for resolve nullable at first time.
DynamicGenericResolverResolver of generic type(Tuple<>, List<>, Dictionary<,>, Array, etc). It uses reflection call for resolve generic argument at first time.
DynamicUnionResolverResolver of interface marked by UnionAttribute. It uses dynamic code generation to create dynamic formatter.
DynamicObjectResolverResolver of class and struct made by MessagePackObjectAttribute. It uses dynamic code generation to create dynamic formatter.
DynamicContractlessObjectResolverResolver of all classes and structs. It does not needs MessagePackObjectAttribute and serialized key as string(same as marked [MessagePackObject(true)]).
DynamicObjectResolverAllowPrivateSame as DynamicObjectResolver but allow serialize/deserialize private members.
DynamicContractlessObjectResolverAllowPrivateSame as DynamicContractlessObjectResolver but allow serialize/deserialize private members.
TypelessObjectResolverUsed for object, embed .NET type in binary by ext(100) format so no need to pass type in deserialization.
TypelessContractlessStandardResolverComposited resolver. It resolves in the following order nativedatetime -> builtin -> attribute -> dynamic enum -> dynamic generic -> dynamic union -> dynamic object -> dynamiccontractless -> typeless. This is the default of MessagePackSerializer.Typeless

Each instance of MessagePackSerializer accepts only a single resolver. Most object graphs will need more than one for serialization, so composing a single resolver made up of several is often required, and can be done with the CompositeResolver as shown below:

// Do this once and store it for reuse.
var resolver = MessagePack.Resolvers.CompositeResolver.Create(
    // resolver custom types first
    ReactivePropertyResolver.Instance,
    MessagePack.Unity.Extension.UnityBlitResolver.Instance,
    MessagePack.Unity.UnityResolver.Instance,

    // finally use standard resolver
    StandardResolver.Instance
);
var options = MessagePackSerializerOptions.Standard.WithResolver(resolver);

// Each time you serialize/deserialize, specify the options:
byte[] msgpackBytes = MessagePackSerializer.Serialize(myObject, options);
T myObject2 = MessagePackSerializer.Deserialize<MyObject>(msgpackBytes, options);

A resolver can be set as default with MessagePackSerializer.DefaultOptions = options, but WARNING: When developing an application where you control all MessagePack-related code it may be safe to rely on this mutable static to control behavior. For all other libraries or multi-purpose applications that use MessagePackSerializer you should explicitly specify the MessagePackSerializerOptions to use with each method invocation to guarantee your code behaves as you expect even when sharing an AppDomain or process with other MessagePack users that may change this static property.

Here is sample of use DynamicEnumAsStringResolver with DynamicContractlessObjectResolver (It is Json.NET-like lightweight setting.)

// composite same as StandardResolver
var resolver = MessagePack.Resolvers.CompositeResolver.Create(
    MessagePack.Resolvers.BuiltinResolver.Instance,
    MessagePack.Resolvers.AttributeFormatterResolver.Instance,

    // replace enum resolver
    MessagePack.Resolvers.DynamicEnumAsStringResolver.Instance,

    MessagePack.Resolvers.DynamicGenericResolver.Instance,
    MessagePack.Resolvers.DynamicUnionResolver.Instance,
    MessagePack.Resolvers.DynamicObjectResolver.Instance,

    MessagePack.Resolvers.PrimitiveObjectResolver.Instance,

    // final fallback(last priority)
    MessagePack.Resolvers.DynamicContractlessObjectResolver.Instance
);

If you want to make an extension package, you should write both a formatter and resolver for easier consumption. Here is sample of a resolver:

public class SampleCustomResolver : IFormatterResolver
{
    // Resolver should be singleton.
    public static readonly IFormatterResolver Instance = new SampleCustomResolver();

    private SampleCustomResolver()
    {
    }

    // GetFormatter<T>'s get cost should be minimized so use type cache.
    public IMessagePackFormatter<T> GetFormatter<T>()
    {
        return FormatterCache<T>.Formatter;
    }

    private static class FormatterCache<T>
    {
        public static readonly IMessagePackFormatter<T> Formatter;

        // generic's static constructor should be minimized for reduce type generation size!
        // use outer helper method.
        static FormatterCache()
        {
            Formatter = (IMessagePackFormatter<T>)SampleCustomResolverGetFormatterHelper.GetFormatter(typeof(T));
        }
    }
}

internal static class SampleCustomResolverGetFormatterHelper
{
    // If type is concrete type, use type-formatter map
    static readonly Dictionary<Type, object> formatterMap = new Dictionary<Type, object>()
    {
        {typeof(FileInfo), new FileInfoFormatter()}
        // add more your own custom serializers.
    };

    internal static object GetFormatter(Type t)
    {
        object formatter;
        if (formatterMap.TryGetValue(t, out formatter))
        {
            return formatter;
        }

        // If type can not get, must return null for fallback mechanism.
        return null;
    }
}

MessagePackFormatterAttribute

MessagePackFormatterAttribute is a lightweight extension point of class, struct, interface, enum and property/field. This is like Json.NET's JsonConverterAttribute. For example, serialize private field, serialize x10 formatter.

[MessagePackFormatter(typeof(CustomObjectFormatter))]
public class CustomObject
{
    string internalId;

    public CustomObject()
    {
        this.internalId = Guid.NewGuid().ToString();
    }

    // serialize/deserialize internal field.
    class CustomObjectFormatter : IMessagePackFormatter<CustomObject>
    {
        public void Serialize(ref MessagePackWriter writer, CustomObject value, MessagePackSerializerOptions options)
        {
            options.Resolver.GetFormatterWithVerify<string>().Serialize(ref writer, value.internalId, options);
        }

        public CustomObject Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
        {
            var id = options.Resolver.GetFormatterWithVerify<string>().Deserialize(ref reader, options);
            return new CustomObject { internalId = id };
        }
    }
}

// per field, member

public class Int_x10Formatter : IMessagePackFormatter<int>
{
    public int Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
    {
        return reader.ReadInt32() * 10;
    }

    public void Serialize(ref MessagePackWriter writer, int value, MessagePackSerializerOptions options)
    {
        writer.WriteInt32(value * 10);
    }
}

[MessagePackObject]
public class MyClass
{
    // You can attach custom formatter per member.
    [Key(0)]
    [MessagePackFormatter(typeof(Int_x10Formatter))]
    public int MyProperty1 { get; set; }
}

Formatter is retrieved by AttributeFormatterResolver, it is included in StandardResolver.

IgnoreFormatter

IgnoreFormatter<T> is lightweight extension point of class and struct. If there exists types that can't be serialized, you can register IgnoreFormatter<T> that serializes those to nil/null.

// CompositeResolver can set custom formatter.
var resolver = MessagePack.Resolvers.CompositeResolver.Create(
    new IMessagePackFormatter[]
    {
        // for example, register reflection infos (can not serialize)
        new IgnoreFormatter<MethodBase>(),
        new IgnoreFormatter<MethodInfo>(),
        new IgnoreFormatter<PropertyInfo>(),
        new IgnoreFormatter<FieldInfo>()
    },
    new IFormatterResolver[]
    {
        ContractlessStandardResolver.Instance
    });

Reserved Extension Types

MessagePack for C# already used some MessagePack extension type codes, be careful to use same ext code.

CodeTypeUse by
-1DateTimeMessagePack-spec reserved for timestamp
30Vector2[]for Unity, UnsafeBlitFormatter
31Vector3[]for Unity, UnsafeBlitFormatter
32Vector4[]for Unity, UnsafeBlitFormatter
33Quaternion[]for Unity, UnsafeBlitFormatter
34Color[]for Unity, UnsafeBlitFormatter
35Bounds[]for Unity, UnsafeBlitFormatter
36Rect[]for Unity, UnsafeBlitFormatter
37Int[]for Unity, UnsafeBlitFormatter
38Float[]for Unity, UnsafeBlitFormatter
39Double[]for Unity, UnsafeBlitFormatter
98AllMessagePackCompression.Lz4BlockArray
99AllMessagePackCompression.Lz4Block
100objectTypelessFormatter

Unity support

Unity lowest supported version is 2018.3, API Compatibility Level supports both .NET 4.x and .NET Standard 2.0.

You can install the unitypackage from the releases page. If your build targets .NET Framework 4.x and runs on mono, you can use it as is. But if your build targets IL2CPP, you can not use Dynamic***Resolver, so it is required to use pre-code generation. Please see pre-code generation section.

MessagePack for C# includes some additional System.*.dll libraries that originally provides in NuGet. They are located under Plugins. If other packages use these libraries (e.g. Unity Collections package using System.Runtime.CompilerServices.Unsafe.dll), to avoid conflicts, please delete the DLL under Plugins.

Currently CompositeResolver.Create does not work on IL2CPP, so it is recommended to use StaticCompositeResolver.Instance.Register instead.

In Unity, MessagePackSerializer can serialize Vector2, Vector3, Vector4, Quaternion, Color, Bounds, Rect, AnimationCurve, Keyframe, Matrix4x4, Gradient, Color32, RectOffset, LayerMask, Vector2Int, Vector3Int, RangeInt, RectInt, BoundsInt and their nullable, array and list types with the built-in extension UnityResolver. It is included in StandardResolver by default.

MessagePack for C# has an additional unsafe extension. UnsafeBlitResolver is special resolver for extremely fast but unsafe serialization/deserialization of struct arrays.

image

x20 faster Vector3[] serialization than native JsonUtility. If use UnsafeBlitResolver, serialization uses a special format (ext:typecode 30~39) for Vector2[], Vector3[], Quaternion[], Color[], Bounds[], Rect[]. If use UnityBlitWithPrimitiveArrayResolver, it supports int[], float[], double[] too. This special feature is useful for serializing Mesh (many Vector3[]) or many transform positions.

If you want to use unsafe resolver, register UnityBlitResolver or UnityBlitWithPrimitiveArrayResolver.

Here is sample of configuration.

StaticCompositeResolver.Instance.Register(
    MessagePack.Unity.UnityResolver.Instance,
    MessagePack.Unity.Extension.UnityBlitWithPrimitiveArrayResolver.Instance,
    MessagePack.Resolvers.StandardResolver.Instance
);

var options = MessagePackSerializerOptions.Standard.WithResolver(StaticCompositeResolver.Instance);
MessagePackSerializer.DefaultOptions = options;

The MessagePack.UnityShims NuGet package is for .NET server-side serialization support to communicate with Unity. It includes shims for Vector3 etc and the Safe/Unsafe serialization extension.

If you want to share a class between Unity and a server, you can use SharedProject or Reference as Link or a glob reference (with LinkBase), etc. Anyway, you need to share at source-code level. This is a sample project structure using a glob reference (recommended).

  • ServerProject(.NET 4.6/.NET Core/.NET Standard)
    • [<Compile Include="..\UnityProject\Assets\Scripts\Shared\**\*.cs" LinkBase="Shared" />]
    • [MessagePack]
    • [MessagePack.UnityShims]
  • UnityProject
    • [Concrete SharedCodes]
    • [MessagePack](not dll/NuGet, use MessagePack.Unity.unitypackage's sourcecode)

AOT Code Generation (support for Unity/Xamarin)

By default, MessagePack for C# serializes custom objects by generating IL on the fly at runtime to create custom, highly tuned formatters for each type. This code generation has a minor upfront performance cost. Because strict-AOT environments such as Xamarin and Unity IL2CPP forbid runtime code generation, MessagePack provides a way for you to run a code generator ahead of time as well.

Note: When using Unity, dynamic code generation only works when targeting .NET Framework 4.x + mono runtime. For all other Unity targets, AOT is required.

If you want to avoid the upfront dynamic generation cost or you need to run on Xamarin or Unity, you need AOT code generation. mpc (MessagePackCompiler) is the code generator of MessagePack for C#. mpc uses Roslyn to analyze source code.

First of all, mpc requires .NET Core 3 Runtime. The easiest way to acquire and run mpc is as a dotnet tool.

dotnet tool install --global MessagePack.Generator

Installing it as a local tool allows you to include the tools and versions that you use in your source control system. Run these commands in the root of your repo:

dotnet new tool-manifest
dotnet tool install MessagePack.Generator

Check in your .config\dotnet-tools.json file. On another machine you can "restore" your tool using the dotnet tool restore command.

Once you have the tool installed, simply invoke using dotnet mpc within your repo:

dotnet mpc --help

Alternatively, you can download mpc from the releases page, that includes platform native binaries (that don't require a separate dotnet runtime).

Usage: mpc [options...]

Options:
  -i, -input <String>                                Input path to MSBuild project file or the directory containing Unity source files. (Required)
  -o, -output <String>                               Output file path(.cs) or directory(multiple generate file). (Required)
  -c, -conditionalSymbol <String>                    Conditional compiler symbols, split with ','. (Default: null)
  -r, -resolverName <String>                         Set resolver name. (Default: GeneratedResolver)
  -n, -namespace <String>                            Set namespace root name. (Default: MessagePack)
  -m, -useMapMode <Boolean>                          Force use map mode serialization. (Default: False)
  -ms, -multipleIfDirectiveOutputSymbols <String>    Generate #if-- files by symbols, split with ','. (Default: null)

mpc targets C# code with [MessagePackObject] or [Union] annotations.

// Simple Sample:
dotnet mpc -i "..\src\Sandbox.Shared.csproj" -o "MessagePackGenerated.cs"

// Use force map simulate DynamicContractlessObjectResolver
dotnet mpc -i "..\src\Sandbox.Shared.csproj" -o "MessagePackGenerated.cs" -m

By default, mpc generates the resolver as MessagePack.Resolvers.GeneratedResolver and formatters asMessagePack.Formatters.*.

Here is the full sample code to register a generated resolver in Unity.

using MessagePack;
using MessagePack.Resolvers;
using UnityEngine;

public class Startup
{
    static bool serializerRegistered = false;

    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    static void Initialize()
    {
        if (!serializerRegistered)
        {
            StaticCompositeResolver.Instance.Register(
                 MessagePack.Resolvers.GeneratedResolver.Instance,
                 MessagePack.Resolvers.StandardResolver.Instance
            );

            var option = MessagePackSerializerOptions.Standard.WithResolver(StaticCompositeResolver.Instance);

            MessagePackSerializer.DefaultOptions = option;
            serializerRegistered = true;
        }
    }

#if UNITY_EDITOR


    [UnityEditor.InitializeOnLoadMethod]
    static void EditorInitialize()
    {
        Initialize();
    }

#endif
}

In Unity, you can use MessagePack CodeGen windows at Windows -> MessagePack -> CodeGenerator.

Install the .NET Core runtime, install mpc (as a .NET Core Tool as described above), and execute dotnet mpc. Currently this tool is experimental so please tell me your opinion.

In Xamarin, you can install the the MessagePack.MSBuild.Tasks NuGet package into your projects to pre-compile fast serialization code and run in environments where JIT compilation is not allowed.

RPC

MessagePack advocated MessagePack RPC, but work on it has stopped and it is not widely used.

MagicOnion

I've created a gRPC based MessagePack HTTP/2 RPC streaming framework called MagicOnion. gRPC usually communicates with Protocol Buffers using IDL. But MagicOnion uses MessagePack for C# and does not need IDL. When communicating C# to C#, schemaless (or rather C# classes as schema) is better than using IDL.

StreamJsonRpc

The StreamJsonRpc library is based on JSON-RPC and includes a pluggable formatter architecture and as of v2.3 includes MessagePack support.

How to build

See our contributor's guide.

Author Info

Yoshifumi Kawai (a.k.a. neuecc) is a software developer in Japan. He is the Director/CTO at Grani, Inc. Grani is a mobile game developer company in Japan and well known for using C#. He is awarding Microsoft MVP for Visual C# since 2011. He is known as the creator of UniRx (Reactive Extensions for Unity)


Author: neuecc
Source Code: https://github.com/neuecc/MessagePack-CSharp
License: View license

#csharp #donet  #xamarin 

MessagePack For C# (.NET, .NET Core, Unity, Xamarin)
Saul  Alaniz

Saul Alaniz

1647267180

Adición Del Efecto De Sombra Paralela A Una Aplicación De Xamarin.form

En este artículo mostraré con qué facilidad se pueden agregar sombras a nuestras aplicaciones Xamarin.Forms, esto sin usar Frames y lo mejor de todo, se verá en menos de dos minutos.

Paso 1

Primero, instalemos el paquete NuGet de Xamarin.CommunityToolkit en todos nuestros proyectos de Xamarin.Forms (incluidos iOS, Android, UWP, etc., específicos de la plataforma).

Adición del efecto de sombra paralela a una aplicación de Xamarin.Forms

Paso 2

Ahora vayamos a cualquier archivo XAML al que queramos agregar una sombra, luego agreguemos el siguiente espacio de nombres (también puede ser un archivo C#, pero para este ejemplo, me enfocaré en XAML).

xmlns:xct="http://xamarin.com/schemas/2020/kit de herramientas"

Y listo, eso es todo! Ahora podemos hacer uso de ShadowEffect.

Ahora solo toca usar las propiedades adjuntas de ShadowEffect para controlar la sombra, por ejemplo,

<StackLayout
xct:ShadowEffect.Color="Red"
xct:ShadowEffect.OffsetY="5"
xct:ShadowEffect.Radius="10">

JavaScript

Adición del efecto de sombra paralela a una aplicación de Xamarin.Forms

Resultado / Salida

| Antes |

| Después |

Las propiedades Color, Opacidad, Radio, OffsetX, OffsetY están disponibles para que ajuste la sombra según lo requiera su diseño.

La buena noticia es que este efecto se puede aplicar a cualquier vista de Xamarin.Forms (no solo a los diseños). Así podemos agregar sombras tanto a las etiquetas (labels), botones y vistas personalizadas.

¡Felicidades! Ahora ya sabe cómo usar los efectos de sombra paralela de Xamarin.CommunityToolkit

Reanudar

Espero que este pequeño artículo te haya dado suficiente información para aplicar sombras a tus aplicaciones de Xamarin.Forms y ver los resultados tanto en Android como en iOS.

Aprovecho el espacio para invitarte a dejar un comentario si quieres que dé más detalles sobre cualquier cosa en este artículo.

Codificación feliz

Enlace: https://www.c-sharpcorner.com/article/adding-the-drop-shadow-effect-to-a-xamarin-forms-application/

#xamarin 

Adición Del Efecto De Sombra Paralela A Una Aplicación De Xamarin.form
伊藤  直子

伊藤 直子

1647266719

Xamarin.Formsアプリケーションへのドロップシャドウ効果の追加

この記事では、Xamarin.Formsアプリケーションにシャドウを簡単に追加できることを示します。これは、フレームを使用せずに、何よりも2分以内に表示されます。

ステップ1

まず、Xamarin.CommunityToolkit NuGetパッケージをすべてのXamarin.Formsプロジェクト(プラットフォーム固有のiOS、Android、UWPなどを含む)にインストールしましょう。

Xamarin.Formsアプリケーションにドロップシャドウ効果を追加する

ステップ2

次に、シャドウを追加するXAMLファイルに移動してから、次の名前空間を追加します(C#ファイルの場合もありますが、この例ではXAMLに焦点を当てます)。

xmlns:xct = "http://xamarin.com/schemas/2020/toolkit"

そして出来上がり、それだけです!これで、ShadowEffectを利用できます。

次に、ShadowEffectの添付プロパティをタッチして、シャドウを制御します。たとえば、

<StackLayout
xct:ShadowEffect.Color="Red"
xct:ShadowEffect.OffsetY="5"
xct:ShadowEffect.Radius="10">

JavaScript

Xamarin.Formsアプリケーションにドロップシャドウ効果を追加する

結果/出力

| 前|

| 後|

Color、Opacity、Radius、OffsetX、OffsetYプロパティを使用して、デザインの必要に応じてシャドウを調整できます。

幸いなことに、この効果は(レイアウトだけでなく)すべてのXamarin.Formsビューに適用できます。したがって、ラベル(ラベル)、ボタン、およびカスタムビューの両方に影を追加できます。

おめでとう!これで、Xamarin.CommunityToolkitのドロップシャドウ効果の使用方法がわかりました。

履歴書

この小さな記事で、Xamarin.Formsアプリケーションにシャドウを適用し、AndroidとiOSの両方で結果を確認するのに十分な情報が得られたことを願っています。

この記事の内容について詳しく教えてほしい場合は、このスペースを利用してコメントを残してください。

ハッピーコーディング

リンク:https ://www.c-sharpcorner.com/article/adding-the-drop-shadow-effect-to-a-xamarin-forms-application/

#xamarin 

Xamarin.Formsアプリケーションへのドロップシャドウ効果の追加

Sign in with Apple - Guide for App Owners

https://www.blog.duomly.com/sign-in-with-apple-guide/

Apple has announced a new sign-in feature called “Sign In with Apple.” This new feature will allow users to sign in to apps and websites using their Apple ID rather than creating a separate username and password. 

Here’s what you need to know about how Sign In with Apple will work for app owners.

#ios #mobile #mobile-apps #flutter #ionic #cordova #xamarin #nativescript #startup #startups 

Sign in with Apple - Guide for App Owners

Xamarin Macios: Bridges The Worlds Of .NET with The Native APIs Of Mac

Xamarin.iOS & Xamarin.Mac

This module is the main repository for both Xamarin.iOS and Xamarin.Mac.

These SDKs allow us to create native iOS, tvOS, watchOS and macOS applications using the same UI controls we would in Objective-C and Xcode, except with the flexibility and elegance of a modern language (C#), the power of the .NET Base Class Library (BCL), and two first-class IDEs—Visual Studio for Mac and Visual Studio—at our fingertips.

This repository is where we do development for the Xamarin.iOS and Xamarin.Mac SDKs. There are a few ways that you can contribute, for example:

Contributing

If you are interested in fixing issues and contributing directly to the code base, please see the document How to Contribute, which covers the following:

Downloads

The preferred method for installing Xamarin.iOS and Mac is to use the Visual Studio installers (Windows, Mac).

The team also strongly recommends using the latest Xamarin SDK and Xcode whenever possible.

However, we provide links to older Xamarin.iOS and Mac packages for macOS downgrades and build machine configuration.

VersionXamarin.iOSXamarin.Mac
d16.11 (Xcode 13.1)[15.2.0.1][30][8.2.0.1][33]
d16.11 (Xcode 13.0)[15.0.0.6][29]N/A
d16.10[14.20.0.24][31][7.14.0.27][32]
d16.9 (Xcode 12.5)[14.16.0.5][27][7.10.0.5][28]
d16.9[14.14.2.5][25][7.8.2.5][26]
d16.8 (Xcode 12.4)[14.10.0.4][23][7.4.0.10][24]
d16.8 (Xcode 12.3)[14.8.0.3][21][7.2.0.3][22]
d16.8 (Xcode 12.2)[14.6.0.15][19][7.0.0.15][20]
d16.8[14.4.1.3][17][6.22.1.26][18]
d16.7[14.2.0.12][15][6.20.2.2][16]
d16.6[13.18.2.1][13][6.18.2.1][14]
d16.5[13.16.0.13][11][6.16.0.13][12]
d16.4[13.10.0.21][9][6.10.0.21][10]
d16.3[13.6.0.12][7][6.6.0.12][8]
d16.2[12.14.0.114][5][5.14.0.114][6]
d16.1[12.10.0.157][3][5.10.0.157][4]
d16.0[12.8.0.2][1][5.8.0.0][2]

Feedback

Download Details:
Author: xamarin
Source Code: https://github.com/xamarin/xamarin-macios
License: View license

#dotnet  #aspdotnet  #csharp #xamarin 

Xamarin Macios: Bridges The Worlds Of .NET with The Native APIs Of Mac