<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sr. Kuantico</title>
    <description>The latest articles on DEV Community by Sr. Kuantico (@srkuantico).</description>
    <link>https://dev.to/srkuantico</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F483177%2Fa0cadb37-1b8d-4520-aa86-073425a39e24.jpg</url>
      <title>DEV Community: Sr. Kuantico</title>
      <link>https://dev.to/srkuantico</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/srkuantico"/>
    <language>en</language>
    <item>
      <title>Publish-Subscribe Pattern in .NET MAUI</title>
      <dc:creator>Sr. Kuantico</dc:creator>
      <pubDate>Sun, 13 Jul 2025 21:53:47 +0000</pubDate>
      <link>https://dev.to/srkuantico/publish-subscribe-pattern-in-net-maui-26d6</link>
      <guid>https://dev.to/srkuantico/publish-subscribe-pattern-in-net-maui-26d6</guid>
      <description>&lt;h2&gt;
  
  
  Why This Pattern?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Publish–Subscribe (Pub/Sub)&lt;/strong&gt; is like the PA system for your app: one bit of code (the publisher) shouts, “Hey, something just happened!” and anyone who cares (subscribers) quietly tunes in. Nobody swaps phone numbers, so publishers stay blissfully ignorant of who’s listening, and subscribers don’t sweat who triggered the event. That double-blind decoupling is catnip for event-driven or distributed setups.&lt;/p&gt;

&lt;p&gt;In a statically-typed world like C#, Pub/Sub is perfect when you need to fire off work without tripping over other patterns—or the UI thread. Strong typing keeps your contracts clear, while async subscribers do their thing off to the side so the main flow stays snappy.&lt;/p&gt;

&lt;p&gt;Think real-world stuff: an IoT sensor pings your app, a background job waits for a status flip before nudging the UI, or your backend shoots a push notification. For all those “react-as-soon-as-this-happens” moments, Pub/Sub is the buddy you’ll call first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommended Libraries
&lt;/h2&gt;

&lt;p&gt;Pub/Sub choices in .NET MAUI aren’t exactly scarce, but two names pop up in just about every repo and blog post you’ll stumble across.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CommunityToolkit.Mvvm WeakReferenceMessenger&lt;/strong&gt; – bundled with the official MAUI Community Toolkit, it keeps event contracts strongly-typed while holding references loosely so your pages don’t stick around in memory after you navigate away. Fire-and-forget, minimal ceremony, shipped by the same folks who maintain the toolkit you’re already using for MVVM goodness. &lt;strong&gt;Ref&lt;/strong&gt;: &lt;a href="https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/messenger" rel="noopener noreferrer"&gt;WeakMessaging&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plugin.Maui.MessagingCenter&lt;/strong&gt; – a lightweight, MAUI-friendly wrapper around the classic Xamarin .Forms MessagingCenter. Same dead-simple .Send() / .Subscribe() API you might already know, refreshed for the multi-target MAUI world with no extra dependencies. Ref: &lt;a href="https://github.com/jfversluis/Plugin.Maui.MessagingCenter" rel="noopener noreferrer"&gt;MessagingCenter By Gerald&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both libraries let your pages, view-models, and services gossip without swapping phone numbers: publishers broadcast, subscribers listen, and nobody keeps a hard reference to anyone else. They’re thread-safe, play nicely with async/await, and live entirely in-process—no broker, queues, or JSON schemas required. Pick the Toolkit if you want strong typing and built-in leak protection, or stick with MessagingCenter if you favor the ultra-simple “string topic + payload” vibe. Either way, you get that double-blind decoupling MAUI apps crave.&lt;/p&gt;

&lt;h2&gt;
  
  
  Good Practices
&lt;/h2&gt;

&lt;p&gt;There are 3 things that you can do to improve your Pub/Sub pattern. Again this practices are based on my dev experience, they can be better or other ref options, my intention in share my knowledge instead override others. Keep that in mind.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Usage on Handlers or Platform Specific&lt;/li&gt;
&lt;li&gt;Usage for Core Layer or ViewModels&lt;/li&gt;
&lt;li&gt;Example of messaging payload&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's code a little bit...&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage on Handlers or Platform Specific
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feisyoop0ly77rp1jootr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feisyoop0ly77rp1jootr.png" alt="maui_handler" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  What you can do
&lt;/h4&gt;

&lt;p&gt;When I’m wiring up custom handlers, Pub / Sub is my grab-and-go trick. Think of an Android barcode-scanner handler shouting “QR decoded!” while the shared view happily renders the result—no ugly #if ANDROID needed. Over on iOS, a Core Bluetooth handler yells “BLE connected,” Windows fires “pen pressure,” and the same shared code just listens. I can bolt on native NFC taps or game-controller events without splashing platform glue across my neutral layer.&lt;/p&gt;

&lt;p&gt;That recipe’s worked for me—your mileage may vary. I’m not laying down gospel here, just sharing what’s saved me headaches. With Pub/Sub all I track is a topic name. Swap out an Android Binding Library tweak for an iOS Binding Library shim, add a fresh Windows/MacOS target, and the rest of the app doesn’t flinch. Tests spoof messages, new platforms add their own handler publishers, and my shared codebase keeps its zen-garden cleanliness.&lt;/p&gt;

&lt;h4&gt;
  
  
  What you should avoid
&lt;/h4&gt;

&lt;p&gt;Stuff I dodge when wiring handlers to the bus: never blast messages every frame from a gyro stream—debounce or you’ll tank battery and FPS. Unhook in DisconnectHandler/Dispose/OnNavigatedFrom; leaked subscriptions survive orientation changes and eat RAM. Keep payloads skinny—pass a file path, not the &lt;strong&gt;4 MB photo bytes&lt;/strong&gt;. Don’t bury runtime-permission prompts inside callbacks; raise an event and let a page decide &lt;strong&gt;or task completions will vanish on suspend/resume&lt;/strong&gt;. And always program for the void—if a device lacks haptics, your “vibrate” message may meet exactly zero listeners.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage for Core Layer or ViewModels
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F02doz36xg7wguaz10qwn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F02doz36xg7wguaz10qwn.png" alt="pubsub_core_mvvm" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  What you can do
&lt;/h4&gt;

&lt;p&gt;In my .NET MAUI apps, wiring Pub/Sub between services and ViewModels (when necessary) keeps things nice and loose: the page fires an event, any background service handles it on its own thread, and the UI never hangs. That decoupling lets me push silent refreshes, live notifications, or analytics pings without sprinkling callbacks all over the codebase—smooth user flow, fewer spaghetti dependencies.&lt;/p&gt;

&lt;p&gt;These thoughts come straight from projects I’ve wrestled with; you might find slicker tricks or stronger refs elsewhere, and that’s cool. What Pub/Sub still buys me is painless testing (just inject a mock bus), cheap feature adds (new view just subscribes), and safer refactors because publishers never care who’s on the other end.&lt;/p&gt;

&lt;h4&gt;
  
  
  What you should avoid
&lt;/h4&gt;

&lt;p&gt;Things I try hard avoid: don’t blast huge payloads through the bus—pass IDs and pull details locally or you’ll choke memory. Resist treating Pub/Sub as a magic DI container: if a consumer is required, wire it directly so failures surface fast. Keep the messenger wrapped in a thin service so tests stay clean, and always unsubscribe; orphan handlers pin pages in memory and wreck perf on Android back-stacks. Skip heavy business logic in the callback—hand it off to a service or background task—and never assume UI-thread context; hop back to MainThread or enjoy random crashes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of messaging payload
&lt;/h3&gt;

&lt;p&gt;If you are looking some Pub/Sub implementation code in .NET MAUI, this is your section. Now there is two libraries mention in this post, so I will created code for both of them. Are you ready?&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Plugin.Maui.MessagingCenter&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Let's create the Subscribe and Unsubscribe functions in the class that you will Subscribe/Register the payload.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    /// &amp;lt;summary&amp;gt;
    /// Subscribes to MessagingCenter messages carrying a MessagingResponse payload.
    /// &amp;lt;/summary&amp;gt;
    public void Subscribe()
    {
        MessagingCenter.Subscribe&amp;lt;object, MessagingResponse&amp;gt;(
            this,
            nameof(MessagingResponse),
            DoWhenMessageReceived);
    }

    /// &amp;lt;summary&amp;gt;
    /// Unsubscribes from MessagingCenter messages.
    /// &amp;lt;/summary&amp;gt;
    public void Unsubscribe()
    {
        MessagingCenter.Unsubscribe&amp;lt;object, MessagingResponse&amp;gt;(
            this,
            nameof(MessagingResponse));
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, add the next model to your project or Entity layer. This will gives to every Pub/Sub hop a single, consistent envelope: Result carries data, MessageType hints at shape, and built-in error/exception flags travel with it, so subscribers can act or bail fast. One strongly-typed wrapper means less casting, safer logging, and cleaner testing across MAUI targets.&lt;/p&gt;

&lt;p&gt;If you have a global constant class, add the enum there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MessagingResponse
{
    public enum MessageType
    {
        SingleResponse,
        ComplexResponse
    }

    public object? Result { get; set; }
    public bool HasError { get; set; }
    public bool HasException { get; set; }
    public string? ErrorMessage { get; set; }
    public Exception? Exception { get; set; }
    public MessageType MessageType { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next thing to do is define what you need when the Subscription get hits. I did a sample function for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Handles incoming MessagingResponse messages.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="sender"&amp;gt;The publisher sending the message.&amp;lt;/param&amp;gt;
/// &amp;lt;param name="message"&amp;gt;The message payload.&amp;lt;/param&amp;gt;
private async void DoWhenMessageReceived(object sender, MessagingResponse message)
{
    if (message.HasException || message.HasError)
    {
        Console.WriteLine($"Do Something when error or exception: {message.Exception?.Message} {message.ErrorMessage}");
        return;
    }

    switch (message.MessageType)
    {
        case MessageType.SingleResponse:
            // Example: message.Result = https://www.google.com to Ping Google in the background
            try
            {
                if(message.Result == null)
                  return;

                using var client = new HttpClient();
                var response = await client.GetAsync((string)message.Result));
                Console.WriteLine($"Website ping status: {response.StatusCode}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Ping failed: {ex.Message}");
            }
            break;
        case MessageType.ComplexResponse:
            // Handle complex objects here. Ex: Iterate a list, call a services, or another kind of sync/async activity.
            break;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, do not forget to call &lt;code&gt;using Plugin.Maui.MessagingCenter;&lt;/code&gt; in your class or implement your publishHelper or service to the send the messages from your most convenient case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   public void Subscribe() =&amp;gt;
        MessagingCenter.Subscribe&amp;lt;object, MessagingResponse&amp;gt;(
            this,
            nameof(MessagingResponse),
            DoWhenMessageReceived);

    public void Unsubscribe() =&amp;gt;
        MessagingCenter.Unsubscribe&amp;lt;object, MessagingResponse&amp;gt;(
            this,
            nameof(MessagingResponse));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CommunityToolkit.Mvvm WeakReferenceMessenger
&lt;/h3&gt;

&lt;p&gt;Let's reuse the previous example, first add the library to and nuget package for &lt;code&gt;using CommunityToolkit.Mvvm.Messaging;&lt;/code&gt; to Send a message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Publishes this &amp;lt;see cref="MessagingResponse"/&amp;gt; instance through the toolkit messenger.
/// &amp;lt;/summary&amp;gt;
public void Send() =&amp;gt; WeakReferenceMessenger.Default.Send(this);

/// &amp;lt;summary&amp;gt;
/// Static helper to publish any &amp;lt;see cref="MessagingResponse"/&amp;gt; payload.
/// &amp;lt;/summary&amp;gt;
public static void Send(MessagingResponse payload) =&amp;gt; WeakReferenceMessenger.Default.Send(payload);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's more or less the same than previous to Subscribed and unsubscribe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public void Subscribe() =&amp;gt;
        WeakReferenceMessenger.Default.Register&amp;lt;MessagingResponse&amp;gt;(
            this,
            (recipient, message) =&amp;gt; _ = HandleMessageAsync(message));

    public void Unsubscribe() =&amp;gt;
        WeakReferenceMessenger.Default.Unregister&amp;lt;MessagingResponse&amp;gt;(this);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, your to-do function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static async Task HandleMessageAsync(MessagingResponse message)
{
    if (message.HasException || message.HasError)
    {
        Console.WriteLine($"Error or exception: {message.Exception?.Message ?? message.ErrorMessage}");
        return;
    }

    switch (message.MessageType)
    {
        case MessageType.SingleResponse:
            if (message.Result is string url)
            {
                try
                {
                    using var client = new HttpClient();
                    var response = await client.GetAsync(url);
                    Console.WriteLine($"Website ping status: {response.StatusCode}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Ping failed: {ex.Message}");
                }
            }
            break;
        case MessageType.ComplexResponse:
            Console.WriteLine("Complex response processing...");
            break;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope this could help you. Enjoy the coding!...&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits To:
&lt;/h2&gt;

&lt;p&gt;Many thanks to these cracks...&lt;/p&gt;

&lt;p&gt;Ref: &lt;a href="https://github.com/jfversluis/Plugin.Maui.MessagingCenter" rel="noopener noreferrer"&gt;Gerald Versluis&lt;/a&gt;&lt;br&gt;
Ref: &lt;a href="https://github.com/CommunityToolkit/dotnet/blob/main/README.md" rel="noopener noreferrer"&gt;CommunityToolkit.Mvvm Contributors&lt;/a&gt;&lt;/p&gt;

</description>
      <category>xamarinforms</category>
      <category>xamarin</category>
      <category>dotnet</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Microsoft Teams Video Calls to .NET MAUI: A Seamless Integration Guide for iOS</title>
      <dc:creator>Sr. Kuantico</dc:creator>
      <pubDate>Sun, 22 Jun 2025 16:39:51 +0000</pubDate>
      <link>https://dev.to/srkuantico/microsoft-teams-video-calls-to-net-maui-a-seamless-integration-guide-for-ios-1g77</link>
      <guid>https://dev.to/srkuantico/microsoft-teams-video-calls-to-net-maui-a-seamless-integration-guide-for-ios-1g77</guid>
      <description>&lt;p&gt;And now let's continue with the other part of the implementation. If you missed the first one, &lt;a href="https://dev.to/srkuantico/microsoft-teams-video-calls-to-net-maui-a-seamless-integration-guide-for-android-2og6"&gt;go to this post&lt;/a&gt; where I explained how to do it for Android platform.&lt;/p&gt;

&lt;p&gt;Now, it's to start with the steps. Enjoy the code!...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You will required a Mac for this&lt;/strong&gt;. Sorry for that, but we will need to run some files via CocoaPods + Xcode too.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;First at all, download the repo from here: &lt;a href="http://bit.ly/4dROPnr" rel="noopener noreferrer"&gt;http://bit.ly/4dROPnr&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In your CMD or Terminal go to: [repo]/ProxyLibs/CommunicationUI-Proxy/CommunicationUI-Proxy.xcworkspace folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make sure to have &lt;a href="https://docs.brew.sh/Installation" rel="noopener noreferrer"&gt;homebrew&lt;/a&gt;, Ruby &amp;amp; Cocoapods installed&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Run this in your terminal, consider use *sudo* for permissions. After all these commands pay attention to the console due probably will required extra libraries to install.

brew install ruby
export PATH="/opt/homebrew/opt/ruby/bin:$PATH"
source ~/.zshrc
gem install cocoapods

//This next command will help us to install part of the necessary resource for Proxy xcworkspace.
pod install
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jump back, in your terminal, to: [repo]/ProxyLibs/CommunicationUI-Proxy and run&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//This will create the xcode project framework

./iOSFramework.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5.In my case, I didn't have to, but if after these steps your Proxy dir doesn't look like the image below; You will need to execute the &lt;a href="https://github.com/Azure-Samples/communication-services-ui-library-maui/blob/main/iOSMauiBindings/README.md" rel="noopener noreferrer"&gt;Sharpie commands for this project&lt;/a&gt;. However, AFTER SHARPIE make sure your dir looks like this: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2x9b6desggrnpgja9ot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2x9b6desggrnpgja9ot.png" alt="folder_path_" width="534" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6.Let's jump to our project in VSCode where we will add the necessary project reference, and your solution explorer should looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'"&amp;gt;
    &amp;lt;ProjectReference Include="../iOS.CallingUI.Binding/iOS.CallingUI.Binding.csproj" /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fe280z62p1dooi19y5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fe280z62p1dooi19y5b.png" alt="project_dir_org" width="282" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7.Do not forget to create your Composite class in iOS and extended it from IComposite interface created &lt;a href="https://dev.to/srkuantico/microsoft-teams-video-calls-to-net-maui-a-seamless-integration-guide-for-android-2og6"&gt;in the Android post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;8.Clean and Build, always make sure whatever you are adding AT LEAST compile.&lt;/p&gt;

&lt;p&gt;9.Considered to add in your Azure Portal the necessary resources to make this work. For this one we will need an Azure Communication Service. First &lt;a href="https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&amp;amp;pivots=platform-azp" rel="noopener noreferrer"&gt;create the resource&lt;/a&gt; and finally, &lt;a href="https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/identity/access-tokens?tabs=windows&amp;amp;pivots=platform-azportal" rel="noopener noreferrer"&gt;generate the token&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;10.Finally, the place to put your token and meeting info, you will find it on &lt;code&gt;MainPage.xaml.cs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;callComposite.joinCall("[Your Name]",
            "[Your Azure Communication Services Token]",
            "[Teams Link]",
            CallType.TeamsCall, _localization, _dataModelInjection, _orientationProps, _callControlProps);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  NOTES TO CONSIDER
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;.I left an alert setup, because this get crash if you try to join into a meeting from a simulator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (DeviceInfo.Platform == DevicePlatform.iOS &amp;amp;&amp;amp; DeviceInfo.DeviceType == DeviceType.Virtual)
            {
                DisplayAlert("Error", "Joining calls is not supported on iOS Simulators.", "OK");
                return;
            }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt;.Point #5 of this post is very important. When you finish to download the framework files, they gets located in a different folder path than the image. I have to move them manually to make it work. This is because when you compile the project the binding will try to reach this files ON THIS path instead on the other installed by default. &lt;strong&gt;Don't forget it&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt;.If My repo on github give you errors when compile, if because you need to follow to steps to decompress the missing files and libraries. Good luck! &lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  CREDITS
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;I want to say thanks to the .NET MAUI and Microsoft team whose collaborate to give us the base code for this. They did the major part and deserve my gratitude.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Azure-Samples/communication-services-ui-library-maui/graphs/contributors" rel="noopener noreferrer"&gt;Collaborators&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy the coding!&lt;/p&gt;

</description>
      <category>dotnetmaui</category>
      <category>ios</category>
      <category>mobile</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Microsoft Teams Video Calls to .NET MAUI: A Seamless Integration Guide for Android</title>
      <dc:creator>Sr. Kuantico</dc:creator>
      <pubDate>Sat, 24 May 2025 04:20:12 +0000</pubDate>
      <link>https://dev.to/srkuantico/microsoft-teams-video-calls-to-net-maui-a-seamless-integration-guide-for-android-2og6</link>
      <guid>https://dev.to/srkuantico/microsoft-teams-video-calls-to-net-maui-a-seamless-integration-guide-for-android-2og6</guid>
      <description>&lt;p&gt;Ever wished you could blend .NET MAUI with the collaboration magic of Microsoft Teams? With .NET MAUI, building native apps for multiple platforms is easier than ever — and now, you can take it a step further by integrating a new Azure UI Library that get you directly with Teams video calls! making your apps more collaborative and accessible with the power of Azure + Teams. 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Not too many .NET MAUI Frameworks for video calls&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One noticeable gap in .NET MAUI right now is the lack of built-in support for implementing video calls. While MAUI excels at creating cross-platform applications with a single codebase, developers looking to integrate real-time video communication need to rely on third-party SDKs or platform-specific implementations. Unlike some frameworks that offer native modules for video conferencing, .NET MAUI doesn't currently provide an out-of-the-box solution, which can add complexity when targeting multiple platforms like Android, iOS, Windows, and macOS. This means handling platform-specific quirks and ensuring smooth video performance across devices, often leading to additional development overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Azure Communication Service UI Library for Mobile&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Even with the market being blooding by the lack of options The Azure team has designed &lt;a href="https://github.com/Azure-Samples/communication-services-ui-library-maui/tree/main" rel="noopener noreferrer"&gt;this new library&lt;/a&gt; as a solution. This required a platform-specific implementation, but today we will just focus on Android.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://learn.microsoft.com/en-us/azure/communication-services/concepts/ui-library/ui-library-overview?pivots=platform-mobile" rel="noopener noreferrer"&gt;Azure Communication UI Mobile Library&lt;/a&gt; gives you plug-and-play UI components for building B2C and B2B calling experiences fast—no need to start from scratch. Now let's start the coding...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Based on &lt;a href="https://github.com/Azure/communication-ui-library-android#prerequisites" rel="noopener noreferrer"&gt;Contributors Documentation&lt;/a&gt; take this requirements as must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an &lt;a href="https://azure.microsoft.com/free/?WT.mc_id=A261C142F" rel="noopener noreferrer"&gt;Azure account&lt;/a&gt; and make a &lt;a href="https://www.youtube.com/watch?v=u5wf8KMD_M8" rel="noopener noreferrer"&gt;subscription active&lt;/a&gt;:&lt;/li&gt;
&lt;li&gt;Don't forget to &lt;a href="https://developer.android.com/studio" rel="noopener noreferrer"&gt;Download Android Studio&lt;/a&gt; and run a test project.&lt;/li&gt;
&lt;li&gt;Create and add the &lt;a href="https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&amp;amp;pivots=platform-azp" rel="noopener noreferrer"&gt;Azure Communication Resource&lt;/a&gt; into your previous Azure account created.&lt;/li&gt;
&lt;li&gt;Don't forget to get your &lt;a href="https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/identity/access-tokens?tabs=windows&amp;amp;pivots=platform-azportal" rel="noopener noreferrer"&gt;service Token&lt;/a&gt; for authentication.&lt;/li&gt;
&lt;li&gt;Remember having setup your &lt;a href="https://docs.microsoft.com/en-us/xamarin/get-started/installation/?pivots=macos" rel="noopener noreferrer"&gt;Visual Studio&lt;/a&gt; Or &lt;a href="https://learn.microsoft.com/en-us/dotnet/maui/get-started/first-app?pivots=devices-android&amp;amp;view=net-maui-8.0&amp;amp;tabs=visual-studio-code" rel="noopener noreferrer"&gt;Visual Code&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;GitBash&lt;/a&gt; at your end or have installed anything that could run &lt;code&gt;.sh&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;And finally, download &lt;a href="https://github.com/Azure-Samples/communication-services-ui-library-maui/tree/main?tab=readme-ov-file" rel="noopener noreferrer"&gt;this repo&lt;/a&gt; at your end.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After having done all preparation points, let's start with the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Getting Start&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;1- Open the repo downloaded call: &lt;code&gt;CommunicationCallingSampleMauiApp&lt;/code&gt; with your file explorer/finder.&lt;/p&gt;

&lt;p&gt;2- Now, create your own .NET MAUI project. In my case, I created one based on .NET 9 just for Android.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqr142mv5g0pa5qhvybh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqr142mv5g0pa5qhvybh.png" alt="KCode" width="550" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3- From the repo project downloaded, find this folder &lt;code&gt;AndroidMauiBindings&lt;/code&gt; and copy the files from the image into your solution folder: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fss0uirs2t7x29pelzug1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fss0uirs2t7x29pelzug1.png" alt="KCode" width="635" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4- Run the script file with your Gitbash (Windows) console or your preference editor, like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwehdaz0lzc5t7nyes2to.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwehdaz0lzc5t7nyes2to.png" alt="KCode" width="601" height="217"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;///First command
chmod +x downloadJarScript.sh
///Second command
./downloadJarScript.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5- Import the android bindings previously copied under your solution:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpsizudfnthcz06qhwn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpsizudfnthcz06qhwn8.png" alt="KCode" width="267" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fox7bsbze59g5yt6atkn0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fox7bsbze59g5yt6atkn0.png" alt="KCode" width="738" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nk80q0midvu6y02a0sl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nk80q0midvu6y02a0sl.png" alt="KCode" width="367" height="719"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This binding are very important and their Jars libreries too. If you can get it correctly from the repo, try it from the original source.&lt;/p&gt;

&lt;p&gt;6- After that, add the resources folder require for bindings to get the necessary assets to drawing the Video Call UI:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr80c49ukcxfc70npxalh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr80c49ukcxfc70npxalh.png" alt="KCode" width="256" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0fti4ld1n0dsz2upiej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0fti4ld1n0dsz2upiej.png" alt="KCode" width="721" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7- Now go to your Android Manifest file and make sure it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"&amp;gt;
  &amp;lt;application
    android:allowBackup="true"
    tools:replace="android:label"
    android:icon="@mipmap/appicon"
    android:roundIcon="@mipmap/appicon_round"
    android:supportsRtl="true"
    android:enableOnBackInvokedCallback="true"/&amp;gt;
  &amp;lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&amp;gt;
    &amp;lt;uses-permission android:name="android.permission.INTERNET" /&amp;gt;
&amp;lt;/manifest&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8- Now is time to compile your project and everything should be good.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8tql8nybuah3t1mj75u9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8tql8nybuah3t1mj75u9.png" alt="KCode" width="534" height="53"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;9- I submitted a &lt;a href="https://github.com/Cacata/KCode.TeamsVideoCalls/tree/main" rel="noopener noreferrer"&gt;repo&lt;/a&gt; with this working, and you can find the missed pieces in there.&lt;/p&gt;

&lt;p&gt;10- Considered to add in your Azure Portal the necessary resources to make this work. For this one we will need an Azure Communication Service. First &lt;a href="https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/create-communication-resource?tabs=windows&amp;amp;pivots=platform-azp" rel="noopener noreferrer"&gt;create the resource&lt;/a&gt; and finally, &lt;a href="https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/identity/access-tokens?tabs=windows&amp;amp;pivots=platform-azportal" rel="noopener noreferrer"&gt;generate the token&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;11- Finally, the place to put your token and meeting info, you will find it on &lt;code&gt;MainPage.xaml.cs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void OnCounterClicked(object sender, EventArgs e)
        {
             callComposite.joinCall("[Your Name]", "[Place your token in here]", "[Place your Teams link meeting in here]", CallType.TeamsCall, _localization, _dataModelInjection, _orientationProps, _callControlProps);
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;NOTES TO CONSIDERE&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NOTE #1:&lt;/strong&gt; There is a reported about this kind of implementation saved on a very long file path. Consider to save this in a shorter place, As: C:/src/[MyProject]. &lt;a href="https://github.com/dotnet/android/issues/7971" rel="noopener noreferrer"&gt;Issue Link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE #2:&lt;/strong&gt; Make sure to setup the project file as was recommended other wise, you could get this type of &lt;a href="https://github.com/Azure-Samples/communication-services-ui-library-maui/issues/40" rel="noopener noreferrer"&gt;Issue&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>dotnet</category>
      <category>ios</category>
      <category>azure</category>
    </item>
  </channel>
</rss>
