Free provisioning in Avalonia 11

Introduction

If you want to create mobile applications for iPhones (iOS operating system) then you have many ways to do that: Flutter, React Native, Cordova… But if you can write code in C# there are also a few frameworks: Xamarin, MAUI and Avalonia.

Currently I’m working with Avalonia UI so I wanted to deploy my apps for testing to my iPhone. The easiest way is to use Apple Developer account from Apple Developer Program and use TestFlight service. Although TestFlight is free, a paid developer control is required to use it (100$ per year). For me it was too much to pay for possibility to only test my apps.

But there is some free alternative: Free provisioning. To use it you need to have computers with MacOS (with installed Xcode) and Windows (with installed Microsoft Visual Studio), free Apple ID account and iPhone of course 😉

So today I would like to show you how you can use Free Provisioning with Avalonia UI framework.

How to use?

Options window used to set up an Apple ID account.

At the beginning set up Apple ID account in Visual Studio (Tools -> Options -> Xamarin -> Apple Accounts).

Connecting with Mac in Microsoft Visual Studio.

Next you have to turn on Remote Login in your Mac (in Mac: System settings… -> General -> Sharing -> Remote Login). After that pair and connect with your Mac from Visual Studio in Windows (Tools -> iOS -> Pair to Mac).

Then open Visual Studio solution that you want to deploy to iPhone (it’s „FreeProvisioning” in my case). You can try to run your app in iOS simulator to check if connection is working fine and if code is building without errors.

Now it’s time to config Free Provisioning.

Creating new iOS project in Xcode.

On Mac create in Xcode default iOS app project (File -> New -> Project). This project is needed to create keys used for our Avalonia app deploy (just create project, you don’t need to write any code in Xcode).

Setting up project properties.

In next page of wizard fill text inputs (remember to use your Apple ID account in „Team” field) and before clicking „Next” remember text showed in „Bundle Identifier” property (we will use it in future).

„Signing & Capabilities” tab in Xcode project properties.

After that step you should see opened project in Xcode. Click using left mouse key on your project name in Navigator (by default it’s top position in tree on the left). In new project properties go to „Signing & Capabilities” tab. Remember value from „Signing Certificate” field.

Adding new properties in csproj file.

Now go back to computer with Windows and open in notepad *.iOS.csproj file (in my case „FreeProvisioning.iOS.csproj”) in your iOS project directory. Add „CodesignProvision” (with your „Bundle Identifier”) and „CodesignKey” (with your „Signing Certificate”) properties with values from Xcode (you can see example in screenshot above).

Changing value „Bundle Identifier” in Visual Studio.

You have to also set up in „Info.plist” file property „Bundle Identifier” with value that you saw in Xcode.

Now set up your iPhone to be used in developer mode. Connect iPhone to Mac (accept and agree all pop-up’s on Mac and iPhone) and in iPhone go to Settings -> Privacy & Security, scroll down to the Developer Mode and turn it on. Probably after first deploy try you will have to give needed permits in „VPN & Device Management” page (Settings -> General -> VPN & Device Management).

After successful set up you should see your iPhone on device list in Visual Studio. Select your device and run app with debug from Visual Studio.

If iPhone is showing „App cannot be installed because its integrity could not be verified” errors then you can try to run your app in Release mode than in Debug. You can also try to completely remove app from iPhone and try to deploy it again.

Conclusion

If there are any problems during described process then you should also check Free Provisioning manual in MSFT docs.

I also had many problems with the configuration of the whole process, which I described above. I believe the problem is that Free Provisioning is too complex. But after many attempts and restarts of used devices and software finally it started to work.

With Free Provisioning you can test your apps with some limitations (check MSFT docs to read more), but in my case I could even test Bluetooth connection without any problems.

Solution presented in this post should also work with Xamarin and MAUI so if you have any problems in that frameworks then try to use my instructions 🙂

ARStreetLamp – opis projektu

Skąd pomysł na projekt?

Będąc studentem w wielkim mieście musiałem wkręcić się w nową grę Pokemon GO (ale oczywiście dopiero jak przeszedł największy szał 😉 ). Dzięki niej spacery ze słuchawkami na uszach nabrały nowego sensu. Ale najbardziej w nowej grze zaintrygowała mnie funkcja AR (rozszerzonej rzeczywistości), bo tym razem nie ograniczała się do statycznych obiektów jak w wielu dostępnych w Internecie demach. A skoro i tak już robiłem kolejne projekty w Xamarinie to trzeba było zorientować się czy mogę coś takiego osiągnąć programując w C#. Mniej więcej w tym samym momencie pojawiła się pierwsza wersja biblioteki ARCore dla mojego Xiaomi Mi 9T. Coraz więcej znaków na niebie dawało nadzieję na fajny ciekawy. Niestety po przejrzeniu przykładów w dokumentacji biblioteki ARCore tworzonej przez Google’a stwierdziłem, że temat może być znaczniej bardziej skomplikowany niż sobie bym tego życzył. Ale tutaj z pomocą przyszedł Microsoft ze swoją dokumentacją oraz twórcy biblioteki UrhoSharp. Trzeba było jeszcze znaleźć jakieś zastosowanie dla rozszerzonej rzeczywistości… I tutaj z inspiracją przyszła moja obecna praca 🙂

O aplikacji

Plan był taki, aby opracować aplikację, która pozwoli handlowcom tworzyć szybkie wizualizacje opraw oświetleniowych (drogowych, do wnętrz, itd.) dla potencjalnych klientów. Wyszedłem z założenia, że każdy pracownik posiada smartphone’a oraz umie używać wbudowanej w niego kamery. Nic by też nie stało na przeszkodzie, aby wykorzystywać aplikację do prezentacji wszystkich produktów firmy bez dodatkowej potrzeby jeżdżenia ciężarówką wypełnioną każdym wariantem produkowanej przez zakład lampy.

Zacząłem od opracowania uproszczonego modelu 3D oprawy Siled Celebra. Na początku, z racji jakiejś znajomości ze szkoły średniej/studiów, postanowiłem wykorzystać do tego oprogramowanie Autodesk Autocad. Pomimo bardzo zadowalającego efektu podczas renderowania oprawy pod różnymi kątami (jak na swój pierwszy raz w świecie 3D) okazało się, że eksport modeli do formatów obsługiwanych przez UrhoSharp’a jest trochę bardziej skomplikowany. Po obejrzeniu wielu YouTube’owych poradników skończyłem z wirtualną maszyną Debian’a i zainstalowanym Blender’em posiadającym plug-in „Urho3D-Blender„. Po wielu podejściach do różnych konfiguracji oraz wersji Blendera i rozszerzenia udało się w końcu trafić na taką, z którą robienie kolejnych modeli było już szybsze i sprawniejsze.

Pierwszy render nowej kanciastej lampy 🙂
Podczas tworzenia nowych modeli dla rozszerzonej rzeczywistości

Po opracowaniu opraw zabrałem się za wykonanie słupa. Tutaj na szczęście mogłem posiłkować się gotowymi modelami (np. śrub z plug-in’u Bolt Factory). No i w końcu coś zaczęło się prezentować.

Modelowanie podstawy słupa

Równolegle do tworzonych modeli 3D powstawał również kod źródłowy robiony w Xamarin Android. SDK zostało wybrane ze względu na pokrycie niemal w 90% funkcji dostarczanych przez Javowe SDK od Google’a i dodatkowo po prostu bardziej jestem Team Microsoft niż Team Google czy Team Oracle.

Kodzenie zacząłem od interfejsu aplikacji (w sumie znany temat, więc chociaż od początku było widać jakiś efekt). Największy problem był z pionowym suwakiem do ustalania wysokości oprawy/długości słupa. Niestety Google nie przewidziało takiej kontrolki w swojej bibliotece. Na szczęście metodą prób i błędów udało się w końcu opracować jakiś kompromis co pozwoliło na przejście do bardziej zaawansowanych rzeczy.

Pierwsze testy aplikacji w terenie

Pierwszą z nich było wykonanie jakiegoś algorytmu pozwalającego na tworzenie całej instalacji lamp składającej się z zadanej ilości. W tym celu w świecie AR należało dodać minimum dwie oprawy, a algorytm robił resztę – obliczał odległość między najdalszymi oprawami i generował symetrycznie kolejne w tych samych odległościach. Do ekstrapolacji zostało wykorzystane proste równanie liniowe – w planach było opracowanie kolejnych wariantów algorytmu wykorzystujących bardziej wymyślne równania krzywych. Niestety świat w którym pracowałem występował w 3 wymiarach, więc estymacji potrzebnych parametrów musiałem dokonywać z pomocą równań macierzowych w funkcji StartCreatingNewInstallation() (czemu oczywiście podołałem 😉 ).

Nocne testy aplikacji. Migotanie opraw powodowane jest przez nadmierne obciążenie procesora telefonu ze względu na jednoczesne generowanie sceny w rozszerzonej rzeczywistości oraz rejestrowanie obrazu z ekranu (bez nagrywania wideo efekt ten nie występował)

Kolejną rzeczą na której mi zależało było generowanie cienia przez słup z lampą zgodnie z aktualnym położeniem słońca. Do wykonania tej funkcjonalności potrzebowałem dodać obsługę kompasu oraz GPS’u. Na bazie tych informacji (oraz aktualnej daty i godziny) mogłem obliczyć położenie słońca na niebie. Później wystarczyło dodać node’a ze źródłem światła znajdującym się w obliczonym miejscu i można było patrzeć jak wirtualny cień pokrywa się z tym rzeczywistym. W planach było jeszcze uzależnienie jasności źródła światła od wartości natężenia światła odczytywanego ze smartphone’owego czujnika, ale ostatecznie nie wcieliłem tego planu w życie.

Testy wirtualnych cieni rzucanych przez lampy vs. rzeczywiste cienie plażowiczów nad polskim Bałtykiem

Iiiiiiii… Potem czar UrhoSharp’a prysnął. Przy próbie wykonania bardziej zaawansowanych rzeczy w tym silniku graficznym zaczęły pojawiać się błędy i artefakty (np. nieprawidłowe generowanie cienia – szczegóły w zrzutach ekranu i nagraniach wideo). Na pomoc w Internecie też za bardzo nie było co liczyć – okazało się, że UrhoSharp był portem silnika graficznego Urho3D i użytkownicy Urho3D oraz UrhoSharp’a za bardzo się nie lubili (przynajmniej takie były moje odczucia, gdy prosiłem o wsparcie) 😉 . Microsoft reklamował UrhoSharp’a na stronie głównej dotyczącej Xamarin’a (na szczęście już z tego pomysłu się wycofał) i niestety dałem się zwieść. Na dodatek dzisiaj nie mam możliwości przetestowania mojej aplikacji na nowym telefonie Samsung Galaxy Note 10+, ponieważ najnowsza wersja ARCore’a generuje wyjątki zaraz po uruchomieniu opracowanej aplikacji (a UrhoSharp już od kilku lat nie jest aktualizowany) – teoretycznie jest możliwość manualnej aktualizacji potrzebnych bibliotek, ale stwierdziłem, że szkoda na to zachodu.

Głównym przekonującym argumentem za UrhoSharp’em (oprócz bardzo dużej prostoty przy tworzeniu wirtualnego świata) była licencja MIT, ale dzisiaj podchodząc jeszcze raz do tego projektu poszedłbym pewnie w stronę Unity albo bezpośrednio w ARCore’a – może kiedyś podejmę się przeportowania aplikacji, kto wie.

Ale co się nauczyłem przy tym projekcie to moje 😉

TODO

Poniżej prezentuję listę rzeczy, które chciałem uwzględnić w rozwoju tej aplikacji:

  • Poprawa działania światła dziennego i generowanego przez nie cienia,
  • Ulepszenie algorytmu do generowania całych instalacji lamp,
  • Dodanie nowych modeli opraw,
  • Opracowanie interfejsu pozwalającego na sterowanie wirtualnymi oprawami za pomocą aplikacji zarządzania inteligentnymi oprawami (CMS).

Zrzuty ekranu

Kody źródłowe

Kody źródłowe

Aplikacja

Tak jak wspominałem wcześniej aplikacja została opracowana raczej jako proof of concept i po nabytych doświadczeniach nie nadaje się raczej do rozwoju/udostępnienia 🙂 Oczywiście jak ktoś będzie naprawdę jej potrzebował to zapraszam do kontaktu/sekcji komentarzy albo zachęcam do własnoręcznej kompilacji ze źródeł dostępnych na moim GitHub’ie.