Friday, 1 August 2025

NET MAUI app with camera-based OCR for Android and iOS using Tesseract OCR.

 Goal

Build a .NET MAUI app that:

✅ Captures an image using the camera
✅ Runs OCR using Tesseract OCR
✅ Displays extracted text on screen


✅ Prerequisites


🧩 Key Libraries


dotnet add package Tesseract.Net.SDK dotnet add package SkiaSharp

SkiaSharp is used to handle and convert images into a format Tesseract can understand.

Step-by-Step Guide


1. Create the MAUI Project


dotnet new maui -n MauiCameraOCR cd MauiCameraOCR

2. Add Permissions

✅ Android: Platforms/Android/AndroidManifest.xml

Add inside <manifest><application>:


<uses-permission android:name="android.permission.CAMERA" />

And enable camera in capabilities:


<uses-feature android:name="android.hardware.camera" android:required="true" />

✅ iOS: Platforms/iOS/Info.plist

Add:


<key>NSCameraUsageDescription</key> <string>This app uses the camera for OCR scanning</string>

3. Add NuGet Packages


dotnet add package Tesseract.Net.SDK dotnet add package SkiaSharp

4. Download Tesseract Language Files

Download from: https://github.com/tesseract-ocr/tessdata

  1. Download eng.traineddata

  2. Create a folder tessdata in your project root

  3. Place eng.traineddata inside

  4. Set properties:

    • Build Action: Content

    • Copy to Output Directory: Copy always


5. Main UI (MainPage.xaml)


<VerticalStackLayout Padding="20" Spacing="15"> <Label Text="Camera OCR App" FontSize="24" HorizontalOptions="Center"/> <Button Text="Capture Image" Clicked="OnCaptureImage"/> <Image x:Name="CapturedImage" HeightRequest="200"/> <ScrollView HeightRequest="300"> <Label x:Name="ResultLabel" FontSize="16"/> </ScrollView> </VerticalStackLayout>

6. Main Logic (MainPage.xaml.cs)

using Microsoft.Maui.Media; using Tesseract; using SkiaSharp; public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } async void OnCaptureImage(object sender, EventArgs e) { try { var photo = await MediaPicker.CapturePhotoAsync(); if (photo == null) return; var stream = await photo.OpenReadAsync(); CapturedImage.Source = ImageSource.FromStream(() => stream); stream.Seek(0, SeekOrigin.Begin); var text = await ExtractTextFromImage(stream); ResultLabel.Text = text; } catch (Exception ex) { await DisplayAlert("Error", ex.Message, "OK"); } } async Task<string> ExtractTextFromImage(Stream stream) { using var engine = new TesseractEngine("./tessdata", "eng", EngineMode.Default); // Convert stream to byte[] using var ms = new MemoryStream(); await stream.CopyToAsync(ms); var bytes = ms.ToArray(); using var pix = Pix.LoadFromMemory(bytes); using var page = engine.Process(pix); return page.GetText(); } }

πŸ“± Platform Notes

Android

  • MediaPicker will use the device camera.

  • Ensure emulator supports camera or test on device.

iOS

  • MediaPicker uses the system camera picker.

  • Permissions must be correctly set in Info.plist.


✅ Build and Run


dotnet build dotnet maui run -f:net8.0-android

Or:

dotnet maui run -f:net8.0-ios

live camera preview in a .NET MAUI app requires platform-specific code because .NET MAUI does not yet provide built-in camera preview controls as of .NET 8.

Here’s how you can implement live camera preview in Android and iOS using Handlers and native views, and integrate it into a .NET MAUI project.

🎯 Goal

  • Show live camera preview (not just capture)

  • Platform-specific implementations:

    • πŸ“± Android: Use CameraX or CameraPreview

    • 🍎 iOS: Use AVCaptureSession and AVCaptureVideoPreviewLayer

✅ Approach Overview

  1. Create a CameraPreview control in .NET MAUI.

  2. Add native handlers for Android and iOS.

  3. Embed native preview views.

  4. Add a "Capture" button to trigger OCR.

πŸ“¦ Step-by-Step Guide

πŸ”§ Step 1: Create the MAUI CameraPreview Control

πŸ“„ Controls/CameraPreview.cs

namespace MauiCameraOCR.Controls; public class CameraPreview : View { public event EventHandler<byte[]> PhotoCaptured; public void OnPhotoCaptured(byte[] imageData) => PhotoCaptured?.Invoke(this, imageData); public void CapturePhoto() { // This will be handled by the native handler } }

🎨 Step 2: Use It in XAML

πŸ“„ MainPage.xaml


<VerticalStackLayout Padding="20"> <Label Text="Live Camera OCR" FontSize="24" HorizontalOptions="Center" /> <ContentView HeightRequest="300"> <controls:CameraPreview x:Name="Camera" /> </ContentView> <Button Text="Capture and OCR" Clicked="OnCaptureClicked" /> <ScrollView HeightRequest="300"> <Label x:Name="ResultLabel" FontSize="16" /> </ScrollView> </VerticalStackLayout>

In code-behind:


private void OnCaptureClicked(object sender, EventArgs e) { Camera.CapturePhoto(); }

And subscribe to the PhotoCaptured event in OnAppearing.

πŸ€– Step 3: Android Handler

πŸ“„ Platforms/Android/Handlers/CameraPreviewHandler.cs


using Android.Content; using Android.Views; using AndroidX.Camera.Core; using AndroidX.Camera.Lifecycle; using AndroidX.Camera.View; using AndroidX.Lifecycle; using Microsoft.Maui.Handlers; using Microsoft.Maui.Platform; using MauiCameraOCR.Controls; [assembly: ExportHandler(typeof(CameraPreview), typeof(CameraPreviewHandler))] namespace MauiCameraOCR.Platforms.Android.Handlers; public class CameraPreviewHandler : ViewHandler<CameraPreview, PreviewView> { PreviewView _previewView; ImageCapture _imageCapture; protected override PreviewView CreatePlatformView() { _previewView = new PreviewView(Context); var cameraProviderFuture = ProcessCameraProvider.GetInstance(Context); cameraProviderFuture.AddListener(() => { var cameraProvider = (ProcessCameraProvider)cameraProviderFuture.Get(); var preview = new Preview.Builder().Build(); _imageCapture = new ImageCapture.Builder().Build(); preview.SetSurfaceProvider(_previewView.SurfaceProvider); var cameraSelector = CameraSelector.DefaultBackCamera; cameraProvider.UnbindAll(); cameraProvider.BindToLifecycle((ILifecycleOwner)Context, cameraSelector, preview, _imageCapture); }, Context.MainExecutor); return _previewView; } public override void ConnectHandler(PreviewView platformView) { base.ConnectHandler(platformView); VirtualView.CapturePhoto = async () => { var file = Java.IO.File.CreateTempFile("ocr_image", ".jpg"); var outputOptions = new ImageCapture.OutputFileOptions.Builder(file).Build(); _imageCapture.TakePicture(outputOptions, Context.MainExecutor, new ImageCaptureOnImageSavedCallback((bytes) => { (VirtualView as CameraPreview)?.OnPhotoCaptured(bytes); })); }; } class ImageCaptureOnImageSavedCallback : Java.Lang.Object, ImageCapture.IOnImageSavedCallback { readonly Action<byte[]> _onSaved; public ImageCaptureOnImageSavedCallback(Action<byte[]> onSaved) { _onSaved = onSaved; } public void OnImageSaved(ImageCapture.OutputFileResults output) { var path = output.SavedUri?.Path; var bytes = File.ReadAllBytes(path); _onSaved(bytes); } public void OnError(ImageCaptureException exc) { Console.WriteLine("Error capturing image: " + exc.Message); } } }

🍎 Step 4: iOS Handler

πŸ“„ Platforms/iOS/Handlers/CameraPreviewHandler.cs


using AVFoundation; using CoreGraphics; using Foundation; using Microsoft.Maui.Handlers; using UIKit; using MauiCameraOCR.Controls; [assembly: ExportHandler(typeof(CameraPreview), typeof(CameraPreviewHandler))] namespace MauiCameraOCR.Platforms.iOS.Handlers; public class CameraPreviewHandler : ViewHandler<CameraPreview, UIView> { AVCaptureSession _session; AVCapturePhotoOutput _photoOutput; UIView _nativeView; protected override UIView CreatePlatformView() { _session = new AVCaptureSession(); _photoOutput = new AVCapturePhotoOutput(); _session.AddOutput(_photoOutput); var device = AVCaptureDevice.GetDefaultDevice(AVMediaTypes.Video); var input = AVCaptureDeviceInput.FromDevice(device, out var error); if (input != null) _session.AddInput(input); var previewLayer = new AVCaptureVideoPreviewLayer(_session) { Frame = new CGRect(0, 0, 300, 300), VideoGravity = AVLayerVideoGravity.ResizeAspectFill }; _nativeView = new UIView(); _nativeView.Layer.AddSublayer(previewLayer); _session.StartRunning(); VirtualView.CapturePhoto = () => { var settings = AVCapturePhotoSettings.Create(); _photoOutput.CapturePhoto(settings, new PhotoCaptureDelegate((bytes) => { VirtualView.OnPhotoCaptured(bytes); })); }; return _nativeView; } class PhotoCaptureDelegate : AVCapturePhotoCaptureDelegate { private readonly Action<byte[]> _callback; public PhotoCaptureDelegate(Action<byte[]> callback) => _callback = callback; public override void DidFinishProcessingPhoto(AVCapturePhotoOutput output, AVCapturePhoto photo, NSError error) { if (photo.FileDataRepresentation != null) { _callback(photo.FileDataRepresentation.ToArray()); } } } }

🧠 OCR Integration (Shared Code)

In your MainPage.xaml.cs, handle:


protected override void OnAppearing() { base.OnAppearing(); Camera.PhotoCaptured += async (s, imgBytes) => { using var engine = new TesseractEngine("./tessdata", "eng", EngineMode.Default); using var pix = Pix.LoadFromMemory(imgBytes); using var page = engine.Process(pix); ResultLabel.Text = page.GetText(); }; }

✅ Final Touches

πŸ›‘ Permissions

Ensure you request camera permissions at runtime (especially on Android 13+).

var status = await Permissions.RequestAsync<Permissions.Camera>();

πŸ“¦ Summary

PlatformCameraLive PreviewCaptureOCR
Android✅ (CameraX)
iOS✅ (AVFoundation)



.NET MAUI app that connects to an AI service (like ChatGPT via OpenAI API)

Create a cross-platform MAUI app (Windows, Android, macOS, iOS) that:

  • Accepts a user prompt.

  • Sends it to an AI engine (e.g., OpenAI).

  • Displays the AI response.


πŸ“¦ Prerequisites

  • .NET 8 SDK

  • Visual Studio 2022/2025 with MAUI workload

  • An API Key (e.g., from OpenAI)


πŸ”§ Step-by-Step Setup

1. Create the MAUI App

dotnet new maui -n MauiAIChatApp cd MauiAIChatApp

2. Add Dependencies

Edit the .csproj to include System.Net.Http.Json (or add OpenAI.Net via NuGet for simplicity):

dotnet add package OpenAI.Net --version 7.0.1

OR, if using direct HTTP:

dotnet add package Newtonsoft.Json

3. Add the API Service

Create a service to call the AI engine.

πŸ”Ή Services/OpenAIService.cs

using System.Net.Http.Headers; using System.Text; using System.Text.Json; public class OpenAIService { private readonly HttpClient _httpClient; private const string apiKey = "sk-REPLACE_WITH_YOUR_KEY"; private const string endpoint = "https://api.openai.com/v1/chat/completions"; public OpenAIService() { _httpClient = new HttpClient(); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey); } public async Task<string> AskChatGPT(string userPrompt) { var requestBody = new { model = "gpt-3.5-turbo", messages = new[] { new { role = "user", content = userPrompt } }, max_tokens = 100 }; var json = JsonSerializer.Serialize(requestBody); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await _httpClient.PostAsync(endpoint, content); var result = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) return $"Error: {result}"; using var doc = JsonDocument.Parse(result); return doc.RootElement .GetProperty("choices")[0] .GetProperty("message") .GetProperty("content") .GetString() ?.Trim(); } }

4. Update MainPage.xaml UI

<VerticalStackLayout Padding="20" Spacing="20"> <Label Text="Ask AI Anything" FontSize="24" HorizontalOptions="Center" /> <Entry x:Name="PromptEntry" Placeholder="Enter your prompt..." /> <Button Text="Ask" Clicked="OnAskClicked" /> <ScrollView HeightRequest="300"> <Label x:Name="ResponseLabel" FontSize="18" /> </ScrollView> </VerticalStackLayout>

5. Update MainPage.xaml.cs

public partial class MainPage : ContentPage { private readonly OpenAIService _openAIService; public MainPage() { InitializeComponent(); _openAIService = new OpenAIService(); } private async void OnAskClicked(object sender, EventArgs e) { var prompt = PromptEntry.Text; if (string.IsNullOrWhiteSpace(prompt)) return; ResponseLabel.Text = "Thinking..."; var response = await _openAIService.AskChatGPT(prompt); ResponseLabel.Text = response; } }

✅ Run the App

dotnet build dotnet maui run


Theme in MAUI

 .NET MAUI (Multi-platform App UI), themes allow you to define consistent styling (colors, fonts, and other UI properties) across your application for light and dark modes or custom themes.

πŸ’‘ What Is a Theme in MAUI?

A theme in MAUI is typically a collection of ResourceDictionaries (colors, styles, etc.) that can be applied globally or per page. Themes support light and dark modes automatically, and you can also create your own custom themes.


πŸ”§ Basic Theme Setup in MAUI

1. App.xaml

Define your base styles and resources:


<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui" x:Class="YourApp.App"> <Application.Resources> <ResourceDictionary> <Color x:Key="PrimaryColor">#512BD4</Color> <Style TargetType="Label"> <Setter Property="TextColor" Value="{DynamicResource PrimaryColor}" /> </Style> </ResourceDictionary> </Application.Resources> </Application>

2. Light and Dark Theme Resource Files

Resources/Styles/ColorsLight.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"> <Color x:Key="PrimaryColor">#512BD4</Color> <Color x:Key="BackgroundColor">#FFFFFF</Color> </ResourceDictionary>
Resources/Styles/ColorsDark.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"> <Color x:Key="PrimaryColor">#BB86FC</Color> <Color x:Key="BackgroundColor">#121212</Color> </ResourceDictionary>

3. Load Themes Based on System Settings

In App.xaml.cs:

public App() { InitializeComponent(); if (Application.Current.RequestedTheme == AppTheme.Dark) { Resources.MergedDictionaries.Add(new ColorsDark()); } else { Resources.MergedDictionaries.Add(new ColorsLight()); } MainPage = new AppShell(); // or any page }

🎯 Tips for Working with Themes

  • Use DynamicResource instead of StaticResource for runtime theme switching.

  • MAUI supports App Theme Binding, which automatically changes resources when the system theme changes.

  • You can define multiple themes and switch them manually if needed.


πŸŒ™ Theme Switching Example

To switch themes manually at runtime:

void SwitchToDarkTheme() { Application.Current.Resources.MergedDictionaries.Clear(); Application.Current.Resources.MergedDictionaries.Add(new ColorsDark()); }

MAUI Weather App with GPS Location

MAUI Weather App with GPS Location


✅ Uses GPS to get current location,

✅ Fetches live weather updates for that location.

I'll walk you through the full solution, with all the pieces: permissions, GPS, API call, and UI.


🌍 MAUI Weather App with GPS Location

πŸ“² What It Does:

  • Gets the user's current location (latitude & longitude)

  • Sends location to OpenWeatherMap API

  • Displays live weather data for that location


✅ Step 1: Setup

1.1 Create MAUI App


dotnet new maui -n GpsWeatherApp cd GpsWeatherApp

πŸ” Step 2: Add Permissions

πŸ”Έ Android → Platforms/Android/AndroidManifest.xml

Inside <manifest>:


<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

πŸ”Έ iOS → Platforms/iOS/Info.plist

Inside <dict>:


<key>NSLocationWhenInUseUsageDescription</key> <string>This app needs your location to show weather updates.</string>

πŸ”§ Step 3: Add Weather + GPS Services

3.1 Weather Model

Models/WeatherInfo.cs


public class WeatherInfo { public Main main { get; set; } public List<Weather> weather { get; set; } public string name { get; set; } } public class Main { public float temp { get; set; } public int humidity { get; set; } } public class Weather { public string main { get; set; } public string description { get; set; } }

3.2 Weather Service

Services/WeatherService.cs


using System.Net.Http.Json; public class WeatherService { private const string ApiKey = "YOUR_API_KEY"; // Replace with your OpenWeatherMap API Key private readonly HttpClient _http; public WeatherService(HttpClient httpClient) { _http = httpClient; } public async Task<WeatherInfo?> GetWeatherAsync(double lat, double lon) { string url = $"https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={ApiKey}&units=metric"; return await _http.GetFromJsonAsync<WeatherInfo>(url); } }

3.3 Register Services

MauiProgram.cs


builder.Services.AddSingleton<HttpClient>(); builder.Services.AddSingleton<WeatherService>();

πŸ“± Step 4: Build the UI

MainPage.xaml


<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" x:Class="GpsWeatherApp.MainPage" Title="Weather App"> <VerticalStackLayout Padding="20" Spacing="15"> <Label Text="Live Weather" FontSize="28" HorizontalOptions="Center" /> <Button Text="Get Weather via GPS" Clicked="OnGetWeatherClicked" /> <Label x:Name="WeatherResultLabel" Text="Your weather info will appear here." FontSize="18" TextColor="DarkSlateBlue" HorizontalOptions="Center" /> </VerticalStackLayout> </ContentPage>

πŸ’‘ Step 5: Add Logic

MainPage.xaml.cs


using Microsoft.Maui.ApplicationModel; using GpsWeatherApp.Services; public partial class MainPage : ContentPage { private readonly WeatherService _weatherService; public MainPage(WeatherService weatherService) { InitializeComponent(); _weatherService = weatherService; } private async void OnGetWeatherClicked(object sender, EventArgs e) { try { var location = await Geolocation.GetLocationAsync(new GeolocationRequest { DesiredAccuracy = GeolocationAccuracy.High, Timeout = TimeSpan.FromSeconds(10) }); if (location == null) { WeatherResultLabel.Text = "Location unavailable."; return; } var weather = await _weatherService.GetWeatherAsync(location.Latitude, location.Longitude); if (weather != null) { WeatherResultLabel.Text = $"πŸ“ {weather.name}\n" + $"🌑 Temp: {weather.main.temp} °C\n" + $"πŸ’§ Humidity: {weather.main.humidity}%\n" + $"⛅ Condition: {weather.weather[0].description}"; } else { WeatherResultLabel.Text = "Could not fetch weather data."; } } catch (PermissionException) { WeatherResultLabel.Text = "Location permission not granted."; } catch (Exception ex) { WeatherResultLabel.Text = $"Error: {ex.Message}"; } } }

🌐 Step 6: Get Your OpenWeatherMap API Key

  1. Go to https://openweathermap.org/api

  2. Create an account

  3. Generate a free API key

  4. Replace "YOUR_API_KEY" in the service


πŸš€ Step 7: Run and Test

Run on:

  • Android Emulator or Device (preferred for GPS)

  • Windows (limited GPS support, returns null unless location enabled)

  • iOS (if using Mac)


✅ You're Done!

Final Features:

  • Uses device GPS

  • Fetches live weather data

  • Displays data in clean UI

  • Resilient to permission issues

Database integration with API in a .NET MAUI app.

 We'll build a small MAUI app that:

  1. Connects to a remote REST API

  2. API connects to a database (e.g., SQL Server)

  3. MAUI app fetches and displays data via HTTPClient

  4. Optionally, use local SQLite cache


Project Structure Overview

Components:

  1. Backend API (.NET 8 Web API)

  2. Database (SQL Server)

  3. MAUI App (frontend)


Part 1: Build the .NET Web API (with EF Core + SQL Server)

Step 1: Create the API Project

dotnet new webapi -n ProductApi cd ProductApi

Step 2: Define a Model

Models/Product.cs

public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } }

 Step 3: Add DbContext

Install EF Core:


dotnet add package Microsoft.EntityFrameworkCore.SqlServer dotnet add package Microsoft.EntityFrameworkCore.Tools

Data/AppDbContext.cs

using Microsoft.EntityFrameworkCore; public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Product> Products => Set<Product>(); }

Step 4: Register DbContext

Program.cs

builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default"))); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen();

appsettings.json

"ConnectionStrings": { "Default": "Server=.;Database=ProductDb;Trusted_Connection=True;" }

 Step 5: Create Controller

Controllers/ProductsController.cs

[ApiController] [Route("api/[controller]")] public class ProductsController : ControllerBase { private readonly AppDbContext _context; public ProductsController(AppDbContext context) => _context = context; [HttpGet] public async Task<IEnumerable<Product>> Get() => await _context.Products.ToListAsync(); [HttpPost] public async Task<IActionResult> Post(Product product) { _context.Products.Add(product); await _context.SaveChangesAsync(); return CreatedAtAction(nameof(Get), new { id = product.Id }, product); } }

Step 6: Apply Migrations


dotnet ef migrations add InitialCreate dotnet ef database update

Run the API and check: https://localhost:port/api/products

Part 2: Connect MAUI App to the API

Step 1: Create MAUI App

dotnet new maui -n MauiWithApi cd MauiWithApi

 Step 2: Create Model

public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } }

Step 3: Create API Service

Services/ProductService.cs

using System.Net.Http.Json; public class ProductService { private readonly HttpClient _http; public ProductService(HttpClient httpClient) { _http = httpClient; _http.BaseAddress = new Uri("https://localhost:5001"); // replace with your API } public async Task<List<Product>> GetProductsAsync() { return await _http.GetFromJsonAsync<List<Product>>("/api/products"); } public async Task AddProductAsync(Product product) { await _http.PostAsJsonAsync("/api/products", product); } }

Step 4: Register Service

MauiProgram.cs

builder.Services.AddSingleton<HttpClient>(); builder.Services.AddSingleton<ProductService>();

 Step 5: Call Service in UI

MainPage.xaml.cs

public partial class MainPage : ContentPage { private readonly ProductService _productService; public MainPage(ProductService productService) { InitializeComponent(); _productService = productService; LoadProducts(); } private async void LoadProducts() { var products = await _productService.GetProductsAsync(); ProductsListView.ItemsSource = products; } }

MainPage.xaml


<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" x:Class="MauiWithApi.MainPage"> <VerticalStackLayout Padding="20"> <ListView x:Name="ProductsListView"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding Name}" Detail="{Binding Price}" /> </DataTemplate> </ListView.ItemTemplate> </ListView> </VerticalStackLayout> </ContentPage>

Optional: Add SQLite Caching in MAUI

To work offline or cache data:

  1. Install SQLite NuGet:

dotnet add package sqlite-net-pcl
  1. Create local DB service (I can guide you if needed).

Now your MAUI app is:

  • Consuming a .NET Web API

  • API is connected to SQL Server using EF Core

  • You're able to fetch/post product data from mobile/desktop

Comprehensive step-by-step guide to develop a cross-platform .NET MAUI

 

Step 1: Environment Setup

1.1 Install Prerequisites

  • .NET SDK 8+Download here

  • Visual Studio 2022/2025 with:

    • .NET MAUI workload

    • Android/iOS workloads (optional for mobile testing)

    • Desktop development with .NET

Open Visual Studio Installer → Modify → Check ".NET Multi-platform App UI development" → Install

1.2 Verify Installation

Open terminal or command prompt:


dotnet --version dotnet workload list

 Step 2: Create a New MAUI App

Using CLI:


dotnet new maui -n MyMauiApp cd MyMauiApp

Using Visual Studio:

  • File → New → Project → "MAUI App" → Next

  • Name your project → Choose folder → Create


Step 3: Understand the Project Structure

  • MainPage.xaml / .cs – UI and code-behind

  • App.xaml / .cs – Application resources and navigation

  • Platforms/ – Platform-specific code (Android, iOS, Windows, MacCatalyst)

  • Resources/ – Images, fonts, styles

  • MauiProgram.cs – Dependency injection and app configuration


Step 4: Build the UI

Use XAML (for declarative UI) or C# (programmatic UI).

Example (MainPage.xaml):


<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" x:Class="MyMauiApp.MainPage"> <VerticalStackLayout Padding="30"> <Label Text="Hello, MAUI!" FontSize="32" HorizontalOptions="Center" /> <Button Text="Click Me" Clicked="OnCounterClicked" /> </VerticalStackLayout> </ContentPage>

Code-Behind (MainPage.xaml.cs):


private int count = 0; private void OnCounterClicked(object sender, EventArgs e) { count++; ((Button)sender).Text = $"Clicked {count} times"; }

Step 5: Run and Test the App

Platforms you can test on:

  • Android – Emulator or physical device

  • iOS – Xcode & Mac required

  • Windows – Direct

  • Mac Catalyst – Mac required

Run:

dotnet build dotnet run

Or click Run in Visual Studio and choose the platform/device.


Step 6: Add Features

You can integrate:

  • MVVM architecture (Model-View-ViewModel)

  • Data binding

  • Navigation

  • Dependency Injection

  • SQLite/local storage

  • APIs (HTTPClient, REST APIs)


Step 7: Platform-Specific Code (If Needed)

Use:


#if ANDROID // Android-specific code #elif IOS // iOS-specific code #endif

Or use DependencyService / Dependency Injection to write platform-specific services.


Step 8: Debugging and Diagnostics

Use:

  • Breakpoints

  • Visual Studio Diagnostic Tools

  • Console logs (Debug.WriteLine)

  • Hot Reload


Step 9: Publish the App

Windows:


dotnet publish -f:net8.0-windows10.0.19041.0 -c Release -o ./publish

Android:

  • Create an APK or AAB

  • Sign with a certificate

  • Use Android Studio tools or MAUI CLI

iOS:

  • Requires Mac

  • Sign with Apple developer account

  • Use Xcode to archive and upload

MacCatalyst:

  • Publish from Mac environment


Step 10: Maintain and Scale

  • Use NuGet packages

  • Write unit tests

  • Implement CI/CD

  • Add analytics and crash reporting (e.g., App Center, Firebase)


Optional: MAUI Libraries and Tools

  • CommunityToolkit.Maui

  • SkiaSharp for 2D drawing

  • Prism / MVVM Toolkit

  • SQLite-net or EF Core

Complete Guide: Building a Live Cricket Streaming App for 100M Users

Comprehensive guide to building a scalable live cricket streaming platform for 100M users, covering backend infrastructure, streaming techno...