Mobile Development

.NET MAUI Cross-Platform Development

TOKEN

.NET MAUI Cross-Platform — XAML, MVVM, Shell, platform specifics, dependency injection, dan deployment ke 4 platform

📋 Daftar Isi
  1. Pengenalan .NET MAUI
  2. XAML Layout
  3. MVVM Pattern
  4. Shell Navigation
  5. Platform Specifics
  6. Dependency Injection
  7. Data Access
  8. Deployment
  9. Quiz Pemahaman

1. Pengenalan .NET MAUI

.NET MAUI (Multi-platform App UI) adalah framework dari Microsoft untuk membangun aplikasi cross-platform (Android, iOS, Windows, macOS) dari satu kode C# dan XAML. MAUI adalah penerus Xamarin.Forms dengan arsitektur yang lebih modern.

Arsitektur .NET MAUI
📝
XAML + C#
Shared UI
& Business Logic
⚙️
.NET MAUI
Handler Mapping
Platform Abstraction
📱
Platforms
Android, iOS
Windows, macOS
Bash — Membuat Proyek MAUI
# Install MAUI workload
dotnet workload install maui

# Buat proyek baru
dotnet new maui -n MyApp

# Jalankan di Android
dotnet build -t:Run -f net8.0-android

# Jalankan di Windows
dotnet build -t:Run -f net8.0-windows10.0.19041.0

# Jalankan di iOS
dotnet build -t:Run -f net8.0-ios

2. XAML Layout

XAML — Halaman Utama



    

        
        

2.1 Layout Types

LayoutArahGunakan Untuk
VerticalStackLayoutVertikalForm, daftar item
HorizontalStackLayoutHorizontalToolbar, chip row
GridBaris & kolomDashboard, complex layout
FlexLayoutWrap/nowrapTag cloud, responsive
AbsoluteLayoutAbsolutOverlay, floating element

3. MVVM Pattern

C# — ViewModel
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

public partial class MainViewModel : ObservableObject
{
    [ObservableProperty]
    private int _userCount;

    [ObservableProperty]
    private decimal _revenue;

    [ObservableProperty]
    private bool _isLoading;

    private readonly IApiService _api;

    public MainViewModel(IApiService api)
    {
        _api = api;
    }

    [RelayCommand]
    private async Task RefreshAsync()
    {
        IsLoading = true;
        try
        {
            var data = await _api.GetDashboardAsync();
            UserCount = data.UserCount;
            Revenue = data.Revenue;
        }
        catch (Exception ex)
        {
            await Shell.Current.DisplayAlert("Error", ex.Message, "OK");
        }
        finally
        {
            IsLoading = false;
        }
    }

    [RelayCommand]
    private async Task NavigateToDetailAsync(int userId)
    {
        await Shell.Current.GoToAsync($"detail?userId={userId}");
    }
}
📋 CommunityToolkit.MVVM

Gunakan NuGet CommunityToolkit.Mvvm untuk source generators: [ObservableProperty] menghasilkan property + INotifyPropertyChanged, [RelayCommand] menghasilkan ICommand.

4. Shell Navigation

XAML — Shell Structure



    
        

        

        
    

    
    
        
            
        
    

C# — Shell Navigation Code
// Navigate with parameters
await Shell.Current.GoToAsync("detail", new Dictionary
{
    ["userId"] = 42,
    ["userName"] = "Budi"
});

// Receive parameters
[QueryProperty(nameof(UserId), "userId")]
[QueryProperty(nameof(UserName), "userName")]
public partial class DetailViewModel : ObservableObject
{
    [ObservableProperty] private int _userId;
    [ObservableProperty] private string _userName;

    partial void OnUserIdChanged(int value)
    {
        // Load data when parameter arrives
        LoadUserDetail(value);
    }
}

5. Platform Specifics

C# — Platform-Specific Code
using Microsoft.Maui.Controls.PlatformConfiguration;
using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;

// Platform-specific XAML

    ()
        .SetPrefersLargeTitles(true) />

    
        ()
            .SetBounce(true) />
    


// Platform check di C#
#if ANDROID
    // Android-specific code
    var statusBar = Platform.CurrentActivity?.Window;
    statusBar?.SetStatusBarColor(Android.Graphics.Color.ParseColor("#2196F3"));
#elif IOS
    // iOS-specific code
    UIApplication.SharedApplication.SetStatusBarStyle(
        UIStatusBarStyle.LightContent, false);
#endif

// Conditional compilation
public static class PlatformHelper
{
    public static bool IsAndroid => DeviceInfo.Platform == DevicePlatform.Android;
    public static bool IsIOS => DeviceInfo.Platform == DevicePlatform.iOS;
    public static bool IsDesktop => DeviceInfo.Idiom == DeviceIdiom.Desktop;
}

6. Dependency Injection

C# — DI Configuration
// MauiProgram.cs
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("FontAwesome.ttf", "FA");
            });

        // Services (Singleton - satu instance)
        builder.Services.AddSingleton<IApiService, ApiService>();
        builder.Services.AddSingleton<IDatabaseService, SqliteDatabase>();

        // Services (Transient - baru setiap request)
        builder.Services.AddTransient<IDialogService, DialogService>();

        // ViewModels
        builder.Services.AddTransient<MainViewModel>();
        builder.Services.AddTransient<DetailViewModel>();

        // Pages
        builder.Services.AddTransient<MainPage>();
        builder.Services.AddTransient<DetailPage>();

        // HTTP Client
        builder.Services.AddHttpClient("api", client =>
        {
            client.BaseAddress = new Uri("https://api.myapp.com");
            client.DefaultRequestHeaders.Add("Accept", "application/json");
        });

        return builder.Build();
    }
}

// Penggunaan di Page
public partial class MainPage : ContentPage
{
    public MainPage(MainViewModel viewModel)
    {
        InitializeComponent();
        BindingContext = viewModel;
    }
}

7. Data Access

C# — SQLite Database
using SQLite;

public class LocalDatabase
{
    private readonly SQLiteAsyncConnection _db;

    public LocalDatabase(string dbPath)
    {
        _db = new SQLiteAsyncConnection(dbPath);
        _db.CreateTableAsync<User>().Wait();
    }

    public Task<List<User>> GetUsersAsync() =>
        _db.Table<User>().ToListAsync();

    public Task<int> SaveUserAsync(User user) =>
        user.Id != 0 ? _db.UpdateAsync(user) : _db.InsertAsync(user);

    public Task<int> DeleteUserAsync(User user) =>
        _db.DeleteAsync(user);
}

[Table("users")]
public class User
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    [MaxLength(100)]
    public string Name { get; set; } = string.Empty;
    [MaxLength(200)]
    public string Email { get; set; } = string.Empty;
    public DateTime CreatedAt { get; set; } = DateTime.Now;
}

8. Deployment

PlatformFormatDistribusi
AndroidAAB / APKGoogle Play Store
iOSIPAApp Store / TestFlight
WindowsMSIX / EXEMicrosoft Store / Sideload
macOSDMG / PKGMac App Store / Direct

Quiz Pemahaman

Pertanyaan 1: Platform apa yang didukung .NET MAUI?

a) Android & iOS saja
b) Android, iOS, Windows, macOS
c) Android, iOS, Linux
d) Windows & macOS saja

Pertanyaan 2: Attribute apa untuk membuat observable property di CommunityToolkit.MVVM?

a) [Observable]
b) [Notify]
c) [ObservableProperty]
d) [Property]

Pertanyaan 3: Layout apa yang mendukung baris dan kolom seperti tabel?

a) StackLayout
b) FlexLayout
c) Grid
d) AbsoluteLayout

Pertanyaan 4: Method apa untuk navigasi dengan parameter di Shell?

a) Navigation.Push()
b) Shell.Current.GoToAsync()
c) App.Navigate()
d) Shell.PushPage()

Pertanyaan 5: Service lifetime apa yang membuat instance baru setiap kali?

a) Singleton
b) Scoped
c) Transient
d) Static
← SebelumnyaKembali ke Beranda Selanjutnya →Lihat Kategori
🔍 Zoom
100%
🎨 Tema