MAUI is still in Preview. That means it has a relatively small feature set and some of it doesn’t work as you’d expect. The fun part is figuring out how to make it work.
We wanted to implement an interactive map in a portion of our app. Seems like MAUI doesn’t support a solution for it yet. Whoops. Xamarin.Forms, the predecessor of MAUI, does support it but it hasn’t been ported to MAUI yet. So what do you do?
Here’s what we did:
Create a React project
Implement a React Component that shows Google Maps
A lot of improvements have been added to our solution, described in detail below. As different parts start to connect, we can see the potential value provided by our solution. Not just in crime fighting, but also as a competitor to food delivery apps like Foodora or Wolt, or transport apps like Uber or Lyft. Our now fully integrated solution includes apps for employees, the back-office and end users, and is easily applied to areas like those described above.
.NET MAUI app
We’ve just updated some design elements of our Ninja Turtle SOS App. It has a modern minimalist design. Because when you’re in an emergency you don’t want to have a confusing patterned background or 20 menus to click through. We are still improving on it but it’s feeling more modern already.
Our app is truly cross-platform. It works on iOS, Android, MacOS and Windows. The MAUI framework makes sure our app runs natively and uses device-specific buttons and UI.
Two-way communication
The MAUI app now properly communicates with the gRPC service, giving it the ability to post SOS alerts to Dynamics and receive SOS status updates back, using a custom Dynamics API client. The status updates are streamed to the app from the server via gRPC.
The gRPC service is automatically deployed to an Azure App Service when we commit to master, using a GitHub Action.
gRPC isn’t properly supported in Azure App Services yet, because of how new it is. Hopefully we can demonstrate the gRPC service working from Azure tomorrow – in the meantime it’s working fine running locally.
New feature: Google Maps!
When you need help from a Ninja Turtle it’s very useful to know where they are in relation to you. So we have now added Google Maps support to the .NET MAUI app. When a Turtle has been assigned to your distress call you will see a map of your area and live updates of your Ninja Turtles location.
It’s a beautiful and easy to use feature that shows you where your Ninja Turtle and you are at any time. A small glance at the app and you know if they are close and you can continue to run towards your savior.
The Google Maps integration into MAUI was a challenge. We solved it by creating a React app that the MAUI app accesses using a WebView, basically rendering a website inside the app. The React app uses a Google Maps react library and is hosted as a separate web app (https://sosmap.vercel.app). We use CI/CD to update new features into our React app, so the users will always get the newest map features.
App for registering Turtles
We have added a web app for accepting new applicants for Ninja Turtles. This app allows for fast onboarding and expansion of the workforce in a gig economy style. Thus, Middle-aged Mutable Ninja Tuples can quickly become the biggest provider of Personal Safety as a Service, benefiting from the accompanying network effects.
The Blazor app is automatically deployed to an Azure App Service when committing to main, using a GitHub Action. It’s available here: https://mamntservice.azurewebsites.net/
After registering, the user should quickly be able to log in to the Dynamics mobile app. In order to make this possible, a lot of things need to happen behind the scenes.
The first step is automatic creation of an Azure AD user, and assigning of a Dynamics license. We created a custom Azure API client for this, which is called from the backend of the Blazor app. After that, the only thing missing is a Dynamics license. But first, the user must be synced to Dynamics from Azure AD, which can take up to an hour.
Because of this delay, we aren’t available to programmatically add a Dynamics license right away, so we created a Dynamics plug-in which automatically adds the license when a user is created. After it has run, the user should be able to log in to the Dynamics mobile app:
Note: it’s possible to force the user sync to happen right away using PowerShell, we’ll look into that as a possible improvement.
Feel The Heat
Dispatchers have a new tool at their disposal; a Power BI report that visualizes reported distress calls in a heatmap. This is achieved by pulling data using Azure Synapse Link to Dynamics 365, which is then used as a dataset for the Power BI report. For MaMNT, both Synapse and Power BI were uncharted waters before development began, and have proven to be just the tools we needed to bring some extra oomph to the user interface.The heatmap itself is a prebuilt feature by AppSource user Weiwei Cui that takes our latitude and longitude parameters as input and allows us to customize the clustering, values and the look and feel of the map.
The heatmap dots warp in shape as you zoom on the map, in order to scale the dots and heat signatures, which produces an awesome-looking effect when the dots are split and merged. Going forward, the heatmap will be limited to a set number of the most recent calls, and we may add a timelapse effect to show patterns and development in crimes committed in the city.
For dispatchers, we also added a filtering feature to the right-hand side where the different types of distress calls can be selected to filter the map instantly. This will enable the turtles to move towards proactively fighting and predicting crime instead of reacting to distress calls. This has great utility not just for improving our services for individual users, but also for providing business facing services to third party security entities (i.e. Police).
Automatic test data generation
When developing a tool to fight crime and respond to distress calls, it is imperative to be able to simulate different loads on the systems and dispatchers to build the best possible solution that fits real-life scenarios. MaMNT set up an Azure Data Factory to produce the desired effect of simulated, continuous distress calls being sent from all over the city of Oslo. The Data Factory job randomizes a caller name, a crime type and x-values of coordinates within the range of 59.9xxxx, 10.xxxxx. New distress calls pop up all over the city at set intervals, and you can see the heatmap updating with a new batch of distress calls every 15 minutes.
Users who register as Turtles (those who want to help people in need) in our Blazor web app are automatically created as Azure AD Users and automatically assigned a Dynamics license, using MS Graph API. The only thing missing for Turtles to be able to log in to the Dynamics mobile app is getting a security role in Dynamics.
We would have programatically assigned a Dynamics security role right away, but there’s a problem: users aren’t immediately synced from Azure AD to Dynamics – it can take several minutes.
As a workaround, a Dynamics plug-in listens to user creations and automatically adds the correct security role when new users are added to Dynamics.
When the plugin has done its work, users will be able to log in to the Dynamics app for phones.
Yesterday another team were stuck trying to boot their Raspberry Pi from a micro-sd card. They didn’t have a card reader compatible with micro-sd cards and couldn’t format and burn the Raspberry Pi OS image onto it.
We stepped in and used some of our precious time to fully setup a brand spanking new image of Raspberry Pi OS on their micro sd card so they could continue their work! ☺️
The backend for the end-user mobile app (.NET MAUI) is integrating with Dynamics 365 via MS Dynamics Web API, to create SOS alerts and get status updates.
The backend for the Turtle back-office (Blazor web app) is communicating with Azure via MS Graph API to programatically create Azure AD users.
Both backends are retrieving access tokens for MS APIs using MS OAuth API.
The Turtle code-base (GitHub) is configured to automatically post events to Discord, such as commits and releases.
We needed testdata to develop the functions, so we made a simple ADF pipeline that inserts “actions” every x sec (if we want to).. We also need a lot of data, since we are planning to run reports and AI, with this test-data function we can start develop.
The ADF-pipeline takes a few params so we can controll how many runs we get.
Vi var blant de to siste lagene til å legge oss i går, og blant de to første lagene til å starte dagen i dag.
Bildet viser 4 av 5 medlemmer som er i gang før solen går opp. Medlem nr 5 mangler på bildet av Covid-årsaker. Dette kan godt dokumenteres, dommere bes ta kontakt med oss for mer informasjon.
.NET MAUI is in Preview. Visual Studio is in Preview. If you try to do it on a Mac it feels like every single line of code is in Preview. It isn’t even the real Visual Studio, it’s “Visual Studio for Mac”.
Developing a .NET MAUI project on a MacBook is pain. The project will suddenly stop building and you will not know why. We spent hours debugging to get it working on a Mac again, but even then it is inconsistent.
To get a consistent build I created an ALIAS to run the app.
alias fuck="cd ~/git/all-the-code/Sos.ClientApp && rm -rf obj bin && dotnet restore && dotnet restore && dotnet build -t:Run -f net6.0-maccatalyst"
This command navigates to the project, removes any generated files, restores not once but twice (trust me, I have to) and then builds the project.
It’s way slower than just building normally, but it works. Now I can go back to being happy and creating awesomeness 😄
The MaMNT crime-and-disaster-prevention solution uses gRPC for two-way communication between the mobile app and backend. After initiating the connection, the app returns updates continously. gRPC is really new and groundbreaking stuff, and in many scenarios it can act as a replacement for SignalR and similar technologies.
MaMNT have travelled around the internets and found clever, ready-for-use third party solutions to aid them in the development process. The list below shows all the third party solutions they have proudly stole from other hard-working individuals and companies to lighten their own load.
gRPC (Google): two-way communication between the mobile app and backend
Discord: collaboration and integration with GitHub: events are posted to the MaMNT Discord server
XrmToolbox: managing plugins
Level up for Dynamics 365: Debugging and configuration