Wednesday, 13 August 2025

Creating a Social Network Sharing App in .NET MAUI

Here's a comprehensive guide to building a MAUI app that allows users to share text and images on social networks.

1. Set Up the Project

First, create a new MAUI project:

bash
dotnet new maui -name SocialShareApp

2. Add Required Permissions

For Android, add these permissions to Platforms/Android/AndroidManifest.xml:

xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />

For iOS, add these entries to Platforms/iOS/Info.plist:

xml
<key>NSPhotoLibraryUsageDescription</key>
<string>Need photo library access to share images</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Need photo library access to save images</string>

3. Create the Sharing Service Interface

Add an interface in Services/IShareService.cs:

csharp
public interface IShareService
{
    Task ShareText(string text);
    Task ShareImage(byte[] imageData, string title, string message);
    Task ShareTextAndImage(string text, byte[] imageData, string title);
    Task PickAndShareImage();
}

4. Implement Platform-Specific Sharing

Create platform implementations:

Android Implementation (Platforms/Android/ShareService.android.cs):

csharp
using Android.Content;
using Android.Net;

public partial class ShareService : IShareService
{
    public async Task ShareText(string text)
    {
        var intent = new Intent(Intent.ActionSend);
        intent.SetType("text/plain");
        intent.PutExtra(Intent.ExtraText, text);
        intent.AddFlags(ActivityFlags.NewTask);
        Platform.CurrentActivity.StartActivity(Intent.CreateChooser(intent, "Share via"));
    }

    public async Task ShareImage(byte[] imageData, string title, string message)
    {
        var tempFile = System.IO.Path.Combine(FileSystem.CacheDirectory, "temp_image.jpg");
        await File.WriteAllBytesAsync(tempFile, imageData);
        
        var uri = FileProvider.GetUriForFile(Platform.CurrentActivity, 
            $"{Platform.CurrentActivity.PackageName}.fileprovider", 
            new Java.IO.File(tempFile));
            
        var intent = new Intent(Intent.ActionSend);
        intent.SetType("image/*");
        intent.PutExtra(Intent.ExtraStream, uri);
        intent.PutExtra(Intent.ExtraText, message);
        intent.AddFlags(ActivityFlags.GrantReadUriPermission);
        Platform.CurrentActivity.StartActivity(Intent.CreateChooser(intent, title));
    }

    public async Task ShareTextAndImage(string text, byte[] imageData, string title)
    {
        var tempFile = System.IO.Path.Combine(FileSystem.CacheDirectory, "temp_image.jpg");
        await File.WriteAllBytesAsync(tempFile, imageData);
        
        var uri = FileProvider.GetUriForFile(Platform.CurrentActivity, 
            $"{Platform.CurrentActivity.PackageName}.fileprovider", 
            new Java.IO.File(tempFile));
            
        var intent = new Intent(Intent.ActionSend);
        intent.SetType("image/*");
        intent.PutExtra(Intent.ExtraStream, uri);
        intent.PutExtra(Intent.ExtraText, text);
        intent.AddFlags(ActivityFlags.GrantReadUriPermission);
        Platform.CurrentActivity.StartActivity(Intent.CreateChooser(intent, title));
    }

    public async Task PickAndShareImage()
    {
        try
        {
            var fileResult = await MediaPicker.PickPhotoAsync();
            if (fileResult != null)
            {
                using var stream = await fileResult.OpenReadAsync();
                using var memoryStream = new MemoryStream();
                await stream.CopyToAsync(memoryStream);
                await ShareImage(memoryStream.ToArray(), "Share Image", "Check out this image!");
            }
        }
        catch (Exception ex)
        {
            await Shell.Current.DisplayAlert("Error", ex.Message, "OK");
        }
    }
}

iOS Implementation (Platforms/iOS/ShareService.ios.cs):

csharp
using UIKit;

public partial class ShareService : IShareService
{
    public Task ShareText(string text)
    {
        var items = new NSObject[] { new NSString(text) };
        var activityController = new UIActivityViewController(items, null);
        var window = UIApplication.SharedApplication.KeyWindow;
        var rootViewController = window.RootViewController;
        
        if (rootViewController.PresentedViewController is UINavigationController navController)
        {
            navController.PresentViewController(activityController, true, null);
        }
        else
        {
            rootViewController.PresentViewController(activityController, true, null);
        }
        
        return Task.CompletedTask;
    }

    public Task ShareImage(byte[] imageData, string title, string message)
    {
        var image = new UIImage(NSData.FromArray(imageData));
        var items = new NSObject[] { image, new NSString(message) };
        var activityController = new UIActivityViewController(items, null);
        var window = UIApplication.SharedApplication.KeyWindow;
        var rootViewController = window.RootViewController;
        
        if (rootViewController.PresentedViewController is UINavigationController navController)
        {
            navController.PresentViewController(activityController, true, null);
        }
        else
        {
            rootViewController.PresentViewController(activityController, true, null);
        }
        
        return Task.CompletedTask;
    }

    public Task ShareTextAndImage(string text, byte[] imageData, string title)
    {
        var image = new UIImage(NSData.FromArray(imageData));
        var items = new NSObject[] { image, new NSString(text) };
        var activityController = new UIActivityViewController(items, null);
        var window = UIApplication.SharedApplication.KeyWindow;
        var rootViewController = window.RootViewController;
        
        if (rootViewController.PresentedViewController is UINavigationController navController)
        {
            navController.PresentViewController(activityController, true, null);
        }
        else
        {
            rootViewController.PresentViewController(activityController, true, null);
        }
        
        return Task.CompletedTask;
    }

    public async Task PickAndShareImage()
    {
        try
        {
            var fileResult = await MediaPicker.PickPhotoAsync();
            if (fileResult != null)
            {
                using var stream = await fileResult.OpenReadAsync();
                using var memoryStream = new MemoryStream();
                await stream.CopyToAsync(memoryStream);
                await ShareImage(memoryStream.ToArray(), "Share Image", "Check out this image!");
            }
        }
        catch (Exception ex)
        {
            await Shell.Current.DisplayAlert("Error", ex.Message, "OK");
        }
    }
}

5. Register the Service

In MauiProgram.cs:

csharp
builder.Services.AddSingleton<IShareService, ShareService>();

6. Create the UI

Here's a simple UI in MainPage.xaml:

xml
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SocialShareApp.MainPage"
             Title="Social Share App">

    <ScrollView>
        <VerticalStackLayout Spacing="20" Padding="20">
            
            <!-- Text Sharing -->
            <Label Text="Share Text" FontSize="Title" />
            <Entry x:Name="ShareTextEntry" Placeholder="Enter text to share" />
            <Button Text="Share Text" Clicked="OnShareTextClicked" />
            
            <!-- Image Sharing -->
            <Label Text="Share Image" FontSize="Title" Margin="0,20,0,0" />
            <Button Text="Select Image" Clicked="OnSelectImageClicked" />
            <Image x:Name="PreviewImage" HeightRequest="200" Aspect="AspectFit" />
            <Entry x:Name="ImageCaptionEntry" Placeholder="Enter caption for image" />
            <Button Text="Share Image" Clicked="OnShareImageClicked" />
            
            <!-- Combined Sharing -->
            <Label Text="Share Text with Image" FontSize="Title" Margin="0,20,0,0" />
            <Entry x:Name="CombinedTextEntry" Placeholder="Enter text to share with image" />
            <Button Text="Share Text with Image" Clicked="OnShareTextWithImageClicked" />
            
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

7. Implement the Code-Behind

In MainPage.xaml.cs:

csharp
public partial class MainPage : ContentPage
{
    private byte[] _selectedImageData;
    private readonly IShareService _shareService;

    public MainPage(IShareService shareService)
    {
        InitializeComponent();
        _shareService = shareService;
    }

    private async void OnShareTextClicked(object sender, EventArgs e)
    {
        if (string.IsNullOrWhiteSpace(ShareTextEntry.Text))
        {
            await DisplayAlert("Error", "Please enter some text to share", "OK");
            return;
        }

        await _shareService.ShareText(ShareTextEntry.Text);
    }

    private async void OnSelectImageClicked(object sender, EventArgs e)
    {
        try
        {
            var fileResult = await MediaPicker.PickPhotoAsync();
            if (fileResult != null)
            {
                using var stream = await fileResult.OpenReadAsync();
                PreviewImage.Source = ImageSource.FromStream(() => stream);
                
                // Store the image data for sharing
                using var memoryStream = new MemoryStream();
                await stream.CopyToAsync(memoryStream);
                _selectedImageData = memoryStream.ToArray();
            }
        }
        catch (Exception ex)
        {
            await DisplayAlert("Error", ex.Message, "OK");
        }
    }

    private async void OnShareImageClicked(object sender, EventArgs e)
    {
        if (_selectedImageData == null)
        {
            await DisplayAlert("Error", "Please select an image first", "OK");
            return;
        }

        await _shareService.ShareImage(
            _selectedImageData, 
            "Shared from my app", 
            ImageCaptionEntry.Text ?? "Check out this image!");
    }

    private async void OnShareTextWithImageClicked(object sender, EventArgs e)
    {
        if (_selectedImageData == null)
        {
            await DisplayAlert("Error", "Please select an image first", "OK");
            return;
        }

        if (string.IsNullOrWhiteSpace(CombinedTextEntry.Text))
        {
            await DisplayAlert("Error", "Please enter some text to share", "OK");
            return;
        }

        await _shareService.ShareTextAndImage(
            CombinedTextEntry.Text,
            _selectedImageData,
            "Shared from my app");
    }
}

8. Android-Specific Configuration

For Android file sharing, add this to Platforms/Android/MainApplication.cs:

csharp
[Application]
public class MainApplication : MauiApplication
{
    public MainApplication(IntPtr handle, JniHandleOwnership ownership)
        : base(handle, ownership)
    {
    }

    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

And create Platforms/Android/Resources/xml/file_paths.xml:

xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="shared_images" path="." />
</paths>

Add this to Platforms/Android/AndroidManifest.xml inside the <application> tag:

xml
<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

9. iOS-Specific Configuration

No additional configuration is needed for iOS beyond the Info.plist entries we already added.

10. Testing the App

Now you can:

  1. Share plain text to any social app

  2. Select and share images

  3. Share text with images

  4. Add captions to shared images

Additional Features to Consider

  1. Social Platform-Specific Sharing: Add direct sharing to specific platforms using their SDKs

  2. Multiple Image Sharing: Extend to share multiple images at once

  3. Video Sharing: Add support for video sharing

  4. Analytics: Track what content is being shared

  5. Link Preview: Generate link previews when sharing URLs

This implementation provides a complete cross-platform solution for sharing content to social networks from a MAUI app. 

No comments:

Post a Comment

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...