dotnet

Accessing the UI in Xamarin.iOS

Oliver Brown
— This upcoming video may not be available to view yet.

An interesting discussion happened recently, triggered by a code review of (something like) the following C#:

public class ProductViewController
{
    private UIView _detailsView { get; set; }
    private ProductViewModel _viewModel { get; set; }

    private void Process()
    {
        if (_viewModel.ProcessDetails)
        {
            InvokeOnMainThread(() =>
            {
                if (_detailsView != null)
                {
                    UpdateDetailsView();
                }
            });
        }
    }
}

One of the reviewers suggested moving the second if outside the call to InvokeOnMainThread (and then combining it with the other if).

The theory was that it would more efficient to check if we need to be on the main thread before we do it, instead of doing the check on the main thread and finding out we have nothing to do.

The original author pushed back saying you can’t access _detailsView off the main thread since you would get an exception.

On the surface this sounds reasonable - everyone knows you can only access UIKit objects on the main thread. But it naturally leads to the question: what does “accessing a UIKit object” actually mean?

So I wrote a quick sample that intentionally tries to do lots of UIKit manipulation on background threads in various ways:

The tests

Quick refresher. The View property of a newly constructed UIViewController is not populated until it is first accessed. Some of the tests below refer to accessing this property either before or after it is created. By default properties declared in C# will not be visible to any native iOS code. They can be made visible by adding the [Export] attribute.

  • Create a UIViewController.
  • Create a UIView.
  • Create a UIColor.
  • Check if a view controller’s View property is equal to null.
  • Check if a view controller’s View property is null using pattern matching.
  • Check if a view controller’s IsViewLoaded property is equal to true.
  • Check if a view controller’s View property is equal to null after previously creating View on the main thread.
  • Check if a view controller’s View property is null using pattern matching after previously creating View on the main thread.
  • Check if a view controller’s IsViewLoaded property is equal to true after previously creating View on the main thread.
  • Check if a new UIView property, that is not exported is equal to null.
  • Check if a new UIView property, that is not exported is null using pattern matching.
  • Check if a new UIView property, that is exported is equal to null.
  • Check if a new UIView property, that is exported is null using pattern matching.
  • Check if a view controller’s NavigationController property is equal to null.
  • Check if a view controller’s NavigationController property is null using pattern matching.
  • Set a new UIView property, that is not exported, with a view created on the main thread.
  • Set a new UIView property, that is exported, with a view created on the main thread.

Results

Test Result
Create UIViewController Exception
Create UIView Exception
Create UIColor OK
Check if View is equal to null Exception
Check if View is null pattern Exception
Check if View is loaded Exception
Check if View is equal to null after creating View Exception
Check if View is null pattern after creating View Exception
Check if View is loaded after creating View Exception
Check if non-exported view is equal to null OK
Check if non-exported view is null pattern OK
Check if exported view is equal to null OK
Check if exported view is null pattern OK
Check if NavigationController is equal to null Exception
Check if NavigationController is null pattern Exception
Set non-exported view OK
Set exported view OK

Summary

This is by no means exhaustive, but it seems in general, acessing properties declared natively in iOS will throw an exception whereas accessing properties you have declared yourself will be fine. I had a suspicion that an exported view might behave the same as a native property, but apparently not.

The code for this test is available on GitHub.

The future of Microsoft MAUI (and Xamarin Forms)

Oliver Brown
— This upcoming video may not be available to view yet.

Since Google seems to like my post about the future of Xamarin Forms so much (and I have a slight history of such posts), I’d figure I’d post an update about interesting things happening in the Xamarin Forms repo specifically related to MAUI.

Renaming

The change that actually made me write this post - a large PR with 5000+ changed files that changes the Xamarin Forms name to MAUI.

Not much of a thing for actual functionality, but a significant symbolic milestone.

Handlers and the great big architecture shift

.NET MAUI will completely change the way renderers are handled in Xamarin Forms. There are many advantages of doing it the new way, but the mechanics of how it is done are fairly complex. This video by Javier Suárez covers it well.

Interacting with this video is done so under the Terms of Service of YouTube
View this video directly on YouTube

This is all happening right now in the main-handler branch.

Update

While I was writing this, work officially moved to the dotnet/maui repo and it is accepting pull requests directly.

AppHost and Microsoft.Extensions

Originally an ASP.NET concept, that then migrated its way to Windows client development, this provides a common way to provide dependency injection, logging, and lots of other infrastructure stuff. In isolation, the pattern and implementation is good and will make it easier to override certain things in MAUI (such as handlers). It’s also useful in a wider sense since it will make configuring different styles of .NET apps more similar.

Single project

Over the past couple of years there has been a move towards producing Xamarin libraries (and .NET libraries in general) using a single multi-targeted project. The most significant is probably Xamarin Essentials. This PR adds support for creating applications following the same pattern.

Merging in Xamarin Essentials

There is a lot of functionality in Xamarin Essentials that Xamarin Forms would like to use. Likewise there is some functionality in Forms that is useful when not using Forms. This lead to some overlap in functionality (and occasionally overlap in APIs but not a perfect match in functionality).

There was an attempt to add Essentials as a dependency of Forms but it faced some problems, and there was a “change of plans”.

Now the solution is to have Forms and Essentials in the same repo. I hope Essentials remains available as its own Nuget package (and it looks like that will be the case).

Resizetizer.NT

Resizertizer.NT, like its predecessor Resizetizer, is a package for generating platform specific images in all the right sizes at build time.

Managing image assets across iOS and Android (and using Visual Studio) has always been an unpleasant process. This tool makes it much easier and will be included in MAUI by default.

The future of Xamarin Forms

Oliver Brown
— This upcoming video may not be available to view yet.

Microsoft have just announced the future of Xamarin and Xamarin forms - the .NET Multi-platform App UI (or MAUI for short). As a name, it’s not great. The highlights are as follows:

  • It’s an evolution of Xamarin Forms. It basically is Xamarin Forms, but finally accepting some breaking changes. To be honest, I’m hoping for a lot since there is a lot of weirdness in Xamarin Forms that has been holding it back.
  • Single project, multi-targeted. It took a long time to get to the point where this was possible. From shared projects, to PCL projects, through .NET Standard. This should make things a lot easier.
  • Still based on platform renderers using native controls. This is a mixed bag. Using native controls has long been a selling point of Xamarin (with or without Forms). With the rise of Flutter this has been shown to be less important. Many people have been asking for consistent platform agnostic renderers instead.
  • The end of “Xamarin” as a name. Some time in the .NET 6 timeline (end of 2021) Xamarin.iOS will become .NET for iOS and Xamarin.Android will be .NET for Android. I have mixed feeling about this since this was a fairly succinct way to describe by top skillset.

I also already have my own enhancement issue submitted.

Xamarin Forms frame is the wrong color

Oliver Brown
— This upcoming video may not be available to view yet.
screenshot

screenshot

Xamarin Forms uses a naive conversion from it’s platform independent Color class to iOS’s CGColor, and as a result, Frame controls end up with inconsistent background colors. I’ve added a demo here.

Clarifying my position on ASP.net

Oliver Brown
— This upcoming video may not be available to view yet.

One of my most read (and most commented on) posts was the one claiming “ASP.NET sucks”, which only goes to show being a little offensive goes dissapointingly far on the internet. Since it has now been five years since I posted that, I thought a quick follow-up was in order. I stand by most of what I said my initial post, but with a little specificity. It’s not ASP.net that’s the problem but Webforms. Unfortunately at the time Webforms was all you ever saw. There are alternatives around today (and may have been back then but none were especially high profile and none were by Microsoft). These days of course Webforms are very much out of fashion. Following on from the success of Rails (and then many) Microsoft realised that Webforms weren’t an idea that could keep up with modern web development. A quick glance at the ASP.net home page today shows four out of five articles talking solely about ASP.net MVC and one article talking about both MVC and Webforms (of course that will vary by day I but I doubt the result will be very different). So taking into account a minor title change (ASP.net Webforms suck!) I’d say my original point stands…

This is an imported post and may not be formatted correctly. View the original here.

Silverlight is pretty cool

Oliver Brown
— This upcoming video may not be available to view yet.

More than two months since my last post. Which means I suddenly have a lot to say. Beware, rambling may follow… Nearly five months ago I claimed to be making “rapid progress with language learning”. Well obviously not rapid enough to actually reveal anything. Well that might be at an end soon. One of the problems of writing the app using things like LINQ means most people will have other things to install to use the app (.NET 3.5 specifically - and possibly .NET 3.0 for non Vista users) and even then it’s limited to Windows users as Mono support for Windows Presentation Foundation will be a long way off (if they do it all). Since Silverlight 2.0 is supposed to be really cool and now supports a big chunk of the widgets from standard WPF (and has has quickly developing Moonlight support), why not write the app in that? So that’s what I’ve been doing. And it was a lot easier than I thought. The first piece of easiness I found was that I oly had to make like three changes to my non-UI code to make it compile as a Silverlight DLL. Unfortunately I can’t persuade Visual Studio to compile it as a Silverlight DLL and a normal DLL in one go, so I’ve currently got the same code added as two different projects and I copy the code between them (not ideal). The only real work I had to do was reimplement my data provider. When I started, I cunningly made sure that all resources (lessons, media, user progress) was grabbed from a data class. I wrote a new class that fetches it from a RESTful server (more on that in another post). So hopefully, a nice Silverlight version of the app will be public soon… About Silverlight For those that don’t know, Silverlight is Microsofts answer to Flash. Apparently. I’m not sure if it’s that a good analogy really. Silverlight 1.0 basically gave you access to a nice environment to draw things in the browser and then manipulate it with Javascript. Or something. To be honest I didn’t really care about version 1.0 since writing complicated things in Javascript doesn’t sound like fun. Silverlight 2.0 (formerly Silverlight 1.1) on the other hand gives you that same environment but the ability to manipulate the things with compiled .NET assemblies written in any CLR language and comes with implementations of a lot of the widgets in the WPF.

This is an imported post and may not be formatted correctly. View the original here.

Google Docs rule - if you use them right

Oliver Brown
— This upcoming video may not be available to view yet.

I’ve been vaguely using Google Docs (specifically Spreadsheets) since it came out but never to do anything actually important. Most of the time I just had a list I need sorting, or if I was feeling sophisticated I’d use it to decide on what was best value for money (how much £/GB a range of hard drives were for instance). Recently I started using it to plan lessons for the language learning app. The ability to use it from work (or any other computer I might be on - including viewing it on my Nokia 770) was useful, but in the end I was only really writing a list with it. Until now. I now have a nifty little C# app that generates modules directly from a Google Spreadsheet which is definitely a Good Thing. I’ve been thinking of writing an app for module editing for a while since writing them by hand is tiresome and error prone. Google Spreadsheets does half the work for me by providing the user interface for generating a table and then provides access as simple XML. Which brings me to the matter of actually accessing the data. Google provide a client library in C# for accessing quite a lot of their API. I tried using it but found it a little confusing. Luckily since I was just wanting to query data, I discovered that raw access was actually easier. You simply make a GET request to http://spreadsheets.google.com/feeds/worksheets/_key_/public/values (where key is provided to you when you “publish” a spreadsheet - access to unpublished spreadsheets requires authorization which is more complicated). This gives you an Atom feed of URLs to the individual worksheets which them contain Atom feeds of either rows or columns (your choice). The query power of LINQ (along with XElement, XAttribute etc.) make transforming the feeds into modules really easy. In fact the code that does the hard work (takes a spreadsheet key and generates the XML) is only 102 lines long, and that’s including unnecessary spacing to make the LINQ more readable (the main LINQ query is 35 lines).

This is an imported post and may not be formatted correctly. View the original here.

LINQ is magical

Oliver Brown
— This upcoming video may not be available to view yet.

The secretly named language learning app has been revamped to use LINQ for most of the XML handling. For those that don’t know, LINQ is a new technology that provides querying functionality in the .NET world. In my case I’m using LINQ to XML and it has seriously cut down on the size of the heaviest methods. Also, the part of LINQ to XML that I found least interesting when I read about it is actually the part I’ve found the best - the new XDocument API. Anyway, LINQ combined with a new USB headset that provides some actually quite good audio means that the important fundamental features have been implemented and work. At the moment it can:

  • Generate lessons based on vocabulary1 modules
  • Generate lessons containing past content with the correct repetition timing.
  • Actually play the lessons (but only on Windows2)

There are a few more things I want to add before I release any of it (like more audio for a start). But I thought I’d at least point out development is still happening :o) 1Instead of the Conversation > Phrase > Term style of Pimsleur I’ve decided to go for a more freeform approach to start with (inspired by me listening to Michel Thomas again). A vocabulary module just contains list of words and phrases that are processed in order. 2I still need a cross platform way to play audio. At the moment I use MCI which is part of winmm.dll which is obviously Windows only. Although Wine has apparently implemented it almost completely but I’m not sure how I’d go about making that help me.

This is an imported post and may not be formatted correctly. View the original here.

So much for Gtk#…

Oliver Brown
— This upcoming video may not be available to view yet.

Well I’ve abandoned my plans to use Gtk# in the language app (which actually secretly has a name now).

The main reason for changing is simplicity. I had a look at the TreeView control in Gtk and decided it was too much work. Although the theory of good MVC separation is good, the user interface is such a small, simple part of my app it wasn’t worth it. The stuff I need from System.Windows.Forms should work in Mono (and .NET 1.1 and hopefully even the Compact Framework).

I still prefer the way Gtk handles layout of controls in general, but I console myself with the Windows form designer in Visual C# Express.

Cross platform games on the PS3 and the Xbox 360

Oliver Brown
— This upcoming video may not be available to view yet.

In case you didn’t know, the PS3 can run Linux. Not only that but it’s officially supported by Sony. You can download (for free) a utility to put a boot loader on to some media (most likely a hard-drive but memory cards, memory sticks and anything else the PS3 can read (and can hold 10Mb) are supported) and set it to boot “Other OS” (that’s what the menu says). There are already videos on the Internet of it running Fedora. Zac Bowling already has one running Mono, a task simplified by the fact that the cell processor appears as a PPC. So where does the Xbox 360 come into this? Well Microsoft are releasing something called XNA, a modified/extended version of the the .NET 2.0 run-time with emphasis on Managed DirectX that is available for Windows and the Xbox 360. A version of XNA called Mono.Xna that is built on top of the Tao framework is in development. The end result is that in theory, games developed using XNA will run on Windows, Linux, Macs, PS3’s and Xbox 360’s. A few problems still exist. The processor that the PS3 uses is rather strictly an in-order processor so most stuff that isn’t written specifically for that will run slowly (although video playback will be pretty zippy) and so far there is no hardware 3D support for an “Other OS” so XNA (if it were available now) would run slowly.

This is an imported post and may not be formatted correctly. View the original here.