msicc

.NET Dev at day & night, Geek. Father of 2 teenagers, husband of a fantastic wife. Founder of MSiccDev Software Development. Opinions are mine.
.NET Dev at day & night, Geek. Father of 2 teenagers, husband of a fantastic wife. Founder of MSiccDev Software Development. Opinions are mine.
Fix ‘Xcode is not currently installed or could not be found’ error in Visual Studio 2019 for Mac

Fix ‘Xcode is not currently installed or could not be found’ error in Visual Studio 2019 for Mac

Every now and then, our IDE’s get some updates. This week, Visual Studio for MacOS got updated once again. After that, there was a separated Download initiated for the Xcode Command Line Tools. Two days later, Visual Studio started to greet me with this little message:

Xcode missing message VS Mac

Of course, I checked first that my installed version of Xcode is still working – it stopped already for me some time ago and I had to reinstall it. As you can see, that was not the case:

Xcode 12.5 about window

After doing some research on the web, others had similar issues. The problem was that the installation of the Xcode CLI tools has overridden the location of Xcode in Preferences – as you can see in the

The fix is easy, just paste /Applications/Xcode.app/ into the location field. Please note that the trailing slash is also important:

The dialog will immediately verify the existence of Xcode (at least in version 8.9.10). Just hit that restart button and you are once again good to go.

As always, I hope this short post will be helpful for some of you.

Until the next post – happy coding, everyone.

Posted by msicc in Dev Stories, iOS, Xamarin, 1 comment
Workaround to force Xamarin.Forms WebView to use a dark mode CSS for local content on Android

Workaround to force Xamarin.Forms WebView to use a dark mode CSS for local content on Android

Recently I updated my blog reader app to support the dark mode newer iOS and Android version support. While everything went smooth on iOS and the update is already live in the App Store, I had some more work to do on Android. One of the bigger problems: the WebView I use to view posts does not automatically switch to dark mode with Xamarin.Forms.

What’s causing this problem?

On part of the problem is that the WebView does not support the CSS query “prefers-color-scheme“. This works as intended on iOS however and is a problem specific to Android. You can refer to this issue on the Xamarin.Forms repository on Github.

Workaround

I am not sure if this problem will ever get solved by the Xamarin.Forms team. I tried to play around with some Javascript solutions that are floating around the web to keep just one CSS file. In the end however, I went with a Xamarin.Forms only approach following the KISS principle.

Xamarin.Forms has a working theme detection mechanism. Based on the return value of the Application.Current.RequestedTheme property, I am loading either the dark mode CSS file or the light mode CSS file (which is default in my case).

Shipping the CSS files is easy, we just need to add them to the Assets folder and set the Build action to AndroidAsset. This results in the following structure within the Android project:

All files that are shipped that way are accessible via the android_asset file uri:

<link rel="stylesheet" href="file:///android_asset/dummycss_light.css">

Now that everything is set up in the Android project, let’s head over to the Xamarin.Forms project. In the sample for this post, I am loading a local html file, while I generate the html dynamically in my blog reader app. The idea works the same way in both cases:

private async Task SetThemeAndLoadSource()
{
    _html = await LoadHtmlFromFileAsync();

    _html = Application.Current.RequestedTheme == OSAppTheme.Dark ?
            _html.Replace("light", "dark") :
            _html.Replace("dark", "light");

    this.TestWebView.Source = new HtmlWebViewSource() { Html = _html };
}

As you can see, I just override the light and dark part of the CSS file name I load into the HTML. That’s all the “magic” that needs to happen here. Just one little thing left to add – what if the user changes the theme while the app is running? Xamarin.Forms has the solution built in as well – just handle the RequestedThemeChanged event and override the file name again, followed by setting the HtmlWebViewSource again:

private async void Current_RequestedThemeChanged(object sender, AppThemeChangedEventArgs e)
{
    await SetThemeAndLoadSource();
}

Conclusion

As most of us are already used to, we sometimes need to find some workarounds when dealing with Xamarin.Forms. While this problem could have been solved with a bunch of Javascript and a custom CSS in a WebViewRenderer as well (I tried that, but didn’t like the complexity), you can achieve reliable results with the workaround above just in Xamarin.Forms.

You can find a working sample here on Github. As always, I hope this post will be helpful for some of you.

Until the next post, happy coding, everyone!
Posted by msicc in Android, Dev Stories, Xamarin, 1 comment
Extending glidex.forms on Android to load a placeholder for images that fail to load

Extending glidex.forms on Android to load a placeholder for images that fail to load

What is glidex.forms?

The glidex.forms library is a Xamarin.Forms implementation of Glide, which is one of the quasi standards for imaging on Android (it is even recommended by Google). Luckily, Jonathan Peppers from Microsoft has a passion to improve Xamarin.Android, and Xamarin.Forms takes a big advantage from that as well. He made the Xamarin.Android Binding library as well as the Xamarin.Forms implementation. Like before with Xamarin.Forms.Nuke, I learned about that library because I am substituting my former image caching solution with Akavache.

Why do we need to extend the library?

If you want to load a placeholder that is stored in the resources of your Android project – there is no need. You could just implement a custom hook into the GlideExtensions class of glidex.forms (I’ll show you that one as well). But if you want to load an image from a Xamarin.Forms resource or even a from a font, we’ll need to extend the GlideExtensions class a little bit.

On a side note, I tried to use the existing mechanism of implementing an IGlideHandler for these purposes, but due to timing issues I never was able to load these kinds of placeholders and I moved on by extending the GlideExtensions class.

Show me some code!

Use Android resource

Let’s have a look at how to load an Android resource as a placeholder first (because it is the easiest way). To do so, we just need to create a custom implementation of an IGlideHandler in the Android project, which will then be called by the GlideExtensions implementation:

public class GlideWithAndroidResourcePlaceholder : IGlideHandler
{
    public GlideWithAndroidResourcePlaceholder()
    {
    }

    public bool Build(ImageView imageView, ImageSource source, RequestBuilder builder, CancellationToken token)
    {
        if (builder != null)
        {
            //easiest way - add the image to Android resources ....
            //general placeholder:
            //builder.Placeholder(Resource.Drawable.MSicc_Logo_Base_Blue_1024px_pad25).Into(imageView);

            //error placeholder:
            builder.Error(Resource.Drawable.MSicc_Logo_Base_Blue_1024px_pad25).Into(imageView);

            return true;
        }
        else
            return false;
    }
}

As you can see, the RequestBuilder has already a placeholder mechanism in place. We just hook into that. If you want a general placeholder (shows the image also during download), use the Placeholder method. For failed image loading only, use the Error method. That’s it.

Use Xamarin.Forms resouce/FontImageSource

As we want to be able to load FontImageSource and Xamarin.Forms resources as well however, we need to go another route. Like we did on iOS, we need to add a placeholder property to the Forms class:

public static ImageSource? PlaceholderImageSource { get; private set; }

To fill our ImageSource with either a Xamarin.Forms resource or a FontImageSource, add these two methods as well:

public static void PlaceholderFromResource (string resourceName, Assembly assembly) =>
	PlaceholderImageSource = ImageSource.FromResource (resourceName, assembly);

public static void PlaceholderFromFontImageSource (FontImageSource fontImageSource) =>
	PlaceholderImageSource = fontImageSource;

Now that we have the PlaceholderImageSource in place, we need to extend the GlideExtensions class. First, we implement a Handler for FontImageSource. The Xamarin.Forms handler for FontImageSource provides us a bitmap, which we are going to use as a placeholder. I only got this working with the AsDrawable method, the AsBitmap method always threw an exception because it couldn’t cast the Bitmap to Drawable (I did not investigate that further).

private static async Task<RequestBuilder?> HandleFontImageSource (RequestManager request, Context? context, FontImageSource fontImageSource, CancellationToken token, Func<bool> cancelled)
{
	if (context == null)
		return null;

	var defaultHandler = new Xamarin.Forms.Platform.Android.FontImageSourceHandler ();

	var bitmap = await defaultHandler.LoadImageAsync (fontImageSource, context, token);

	if (token.IsCancellationRequested || cancelled())
		return null;

	if (bitmap == null)
		return null;

	return request.AsDrawable().Load (bitmap);
}

As for the HandleFontImageSource method, I also needed to change the return value of the HandleStreamImageSource method to use the AsDrawable method, otherwise we would get the same exception as with the FontImageSource:

static async Task<RequestBuilder?> HandleStreamImageSource (RequestManager request, StreamImageSource source, CancellationToken token, Func<bool> cancelled)
{ 
        //code omitted for readability

	return request.AsDrawable().Load (memoryStream.ToArray ());
}

The final steps to make it all work are done in the LoadViaGlide method. First, add another RequestBuilder? variable and name it errorBuilder:

RequestBuilder? errorBuilder = null;

After the switch that handles the source parameter, add these lines of code:

switch(Forms.PlaceholderImageSource) {
	case StreamImageSource streamSource:
		errorBuilder = await HandleStreamImageSource (request, streamSource, token, () => !IsActivityAlive (imageView, Forms.PlaceholderImageSource));
		break;
	case FontImageSource fontImageSource:
		errorBuilder = await HandleFontImageSource(request, imageView.Context, fontImageSource, token, () => !IsActivityAlive (imageView, Forms.PlaceholderImageSource));
		break;
	default:
		errorBuilder = null;
		break;
}

if (errorBuilder != null)
	builder?.Error (errorBuilder);

We are handling our PlaceholderImageSource like we do with the ImageSource that we intend to load. If we have a valid errorBuilder, we pass that into the entire process. With that, we have already everything in place. Let’s see how to use it in your app.

How to use it in your Xamarin.Forms – Android project

Head over to the MainActivity class in your Android project and add the following method:

private void AttachGlide()
{
    Android.Glide.Forms.Init(this, null, false);

    //recommended way of loading resource images=>
    //Android.Glide.Forms.Init(this, new GlideWithAndroidResourcePlaceholder(), false);

    //Xamarin Forms resource image
    //Android.Glide.Forms.PlaceholderFromResource("CachedImageTest.MSicc_Logo_Base_Blue_1024px_pad25.png", Assembly.GetAssembly(typeof(MainViewModel)));

    //FontImageSource
    Android.Glide.Forms.PlaceholderFromFontImageSource(new FontImageSource
    {
        Glyph = XfNativeCachedImages.Resources.MaterialDesignIcons.ImageBroken,
        FontFamily = "MaterialDesignIcons",
        Color = Xamarin.Forms.Color.Red
    });
}

The Glide library needs to be initialized. Depending on the method you are using, there are separate ways to do so. The method above shows them all, you just need to change the commented code to play around with it in the sample (link at the end of the post). The mechanism is like the one I used for iOS and the Nuke package.

If you followed along (or downloaded the sample), you should see similar result to this:

Placeholder_Sample_Android_Title
Left: Single image with placeholder, Right: CollectionView placeholder

Conclusion

As we did on iOS, we now also use native caching and image handling on Android. It took me quite some time to get it up and running, but it was worth the effort. The sample has more than five hundred remote images loaded into a CollectionView. Check how smooth the scrolling is (even with DataBinding!).

You can find the sample here on Github, while the modified version of glidex.forms is available here. As always, I hope this post will be helpful for some of you.

Until the next post, happy coding, everyone!

Posted by msicc in Android, Dev Stories, Xamarin, 1 comment
Extending Xamarin.Forms.Nuke on iOS to load a placeholder for images that fail to load

Extending Xamarin.Forms.Nuke on iOS to load a placeholder for images that fail to load

What is Xamarin.Forms.Nuke?

Xamarin.Forms.Nuke is a Xamarin.Forms implementation of Nuke, one of the most advanced image libraries on iOS today. The Xamarin.Forms implementation focuses heavily on caching only, while the original library has a bunch of more features. I learned about this library when I started to look for an alternative to cache images via Akavache which I used before (I never blogged about that part because it wasn’t ready for that, tbh).

Why do we need to extend the library?

The library currently does only one thing (pretty well) – handling the caching of web images. It uses the default settings of the native Nuke library. The Xamarin.Forms implementation overwrites the ImageSourceHandler for UriImageSource and FileImageSource (optionally), but the case of placeholder loading is not intended in the original version. As I have multiple scenarios where a placeholder comes in handy, I decided to extend the library – and maintain my own fork of it from now on. (Maybe there will be a pull request to the original source, too).

Show me some code, finally!

For our extension, we modify the FormsHandler class as well as the ImageSourceHandler class. Let’s have a look at the FormsHandler class first. We are adding a new property for the placeholder:

public static ImageSource PlaceholderImageSource { get; private set; }

With that property in place, let’s add two methods. One method is for loading a placeholder image from an embedded resource file, while the second one is for specifying a FontImageSource.

public static void PlaceholderFromResource(string resourceName, Assembly assembly) =>
    PlaceholderImageSource = ImageSource.FromResource(resourceName, assembly);

public static void PlaceholderFromFontImageSource(FontImageSource fontImageSource) =>
    PlaceholderImageSource = fontImageSource;

I have chosen the FormsHandler class because setting the placeholder is a global thing (in my scenarios, your mileage may vary). That’s already everything in takes in the FormsHandler class, so let’s have a look at the ImageSourceHandler class.

As we are using the default Xamarin.Forms ImageSourceHandler for the resource image (which is a StreamImageSource) and the FontImageSource, we need to add the static fields for them first:

private static readonly StreamImagesourceHandler DefaultStreamImageSourceHandler = new StreamImagesourceHandler();

private static readonly FontImageSourceHandler DefaultFontImageSourcehandler = new FontImageSourceHandler();

Now let’s implement the loading of the placeholder in a separate method:

private static Task<UIImage> LoadPlaceholderAsync()
{
    switch (FormsHandler.PlaceholderImageSource)
    {
        case StreamImageSource streamImageSource:
            FormsHandler.Warn($"loading placeholder from resource");
            return DefaultStreamImageSourceHandler.LoadImageAsync(streamImageSource);
                    
        case FontImageSource fontImageSource:
            FormsHandler.Warn($"loading placeholder from Font");
            return DefaultFontImageSourcehandler.LoadImageAsync(fontImageSource);
        default:
            FormsHandler.Warn($"no valid placeholder found");
            return null;
    }
}

As you can see, there is nothing overly complicated in this method. Based on the type of the placeholder set in the FormsHandler class, we are calling the default Xamarin.Forms implementation for the placeholder image. Let’s take this code into action by changing the LoadImageAsync method of the ImageSourceHandler:

public async Task<UIImage> LoadImageAsync(
    ImageSource imageSource,
    CancellationToken cancellationToken = new CancellationToken(),
    float scale = 1)
{
    var result = await NukeHelper.LoadViaNuke(imageSource, cancellationToken, scale);
    if (result == null)
        result = await LoadPlaceholderAsync();

    return result;
}

As we need to know if the Nukehelper class is able to load the image, we are already running the code by awaiting it at this level. If the result is null, we are loading the placeholder image via our prior implemented method. That’s all we need to do in our forked Xamarin.Forms.Nuke repository.

How to use it in your Xamarin.Forms – iOS project

First, clone my fork (or fork it if you want) of the Xamarin.Forms.Nuke repository and import it into your Xamarin.Forms solution and reference it in your iOS project. Once that is done, we need to initialize the Nuke library (like in the original source) in the AppDelegate‘s FinishedLaunching method:

Xamarin.Forms.Nuke.FormsHandler.Init(true, false);

The second step is to define the placeholder image source. The FontImageSource should be defined after the LoadApplication method. This way, you can the Xamarin.Forms way of loading the font as a resource.

//Resource image
Xamarin.Forms.Nuke.FormsHandler.PlaceholderFromResource("CachedImageTest.MSicc_Logo_Base_Blue_1024px_pad25.png", Assembly.GetAssembly(typeof(MainViewModel)));

//FontImageSource
Xamarin.Forms.Nuke.FormsHandler.PlaceholderFromFontImageSource(new FontImageSource
{
    Glyph = CachedImageTest.Resources.MaterialDesignIcons.ImageBroken,
    FontFamily = "MaterialDesignIcons",
    Color = Color.Red
});

Now use the Xamarin.Forms Image control like you always do. If the image from the web cannot be loaded, you will see the placeholder, like in these two examples:

cached image placeholder sample
Left: Single image failed loading, right image in CollectionView failed loading

With a few additions to the Xamarin.Forms.Nuke library, we have implemented a placeholder mechanism for images that can’t be loaded. As always, I hope this post will be useful for some of you. Now that I have the iOS implementation of a fast cached image with placeholder loading in place, I will turn to Android, where I will try to achieve the same using the Glidex.Forms library and extend it to load a placeholder. There will be a full sample once that is implemented as well. Stay tuned for that one!

Until the next post, happy coding, everyone!
Posted by msicc in Dev Stories, iOS, Xamarin, 2 comments
Goodbye, 2020!

Goodbye, 2020!

In the beginning of 2020, I was polishing up the app for my personal blog as well as my WordPress reader library. I started to write a series about my experience on implementing push notifications with Azure which I still must finish.

During the spring lockdown, I also started a new project, which is now in the MVP (minimum viable product) state. I started to improve the overall performance by moving parts of the application to the cloud (ongoing process). I hope I will be able to share more on this project soon, but here’s already a screen shot:

TwistReader

Besides working on my personal projects and trying to get some fruit/vegetables from our garden, I was contacted by my new employer (dormakaba AG, starting 2021) in summer on StackOverflow. As I haven’t done any interview for close to 6 years at that time, I decided to “play the game” to gain some refreshing experience. I went through the entire process (which was also different due to COVID-19) and was offered the job – in the end, I accepted it.

Since I am changing my employer, I was quite busy in the last three months of the years to finish the work I started in my daytime job – which is the reason I was so quiet during that time.

2020 was a challenging year (mostly due to COVID-19). Overall, my family and I went through it and did handle most challenges quite well. My biggest personal achievement in 2020: I finally freed myself from the slavery of nicotine and became a non-smoker. Besides that, Santa did an excellent job again this year and upgraded my computer to a MacBook Pro:

2021 will still be a challenging year due to COVID-19. We will still need to keep distance, wear masks, and wash our hands (and stay at home as much as possible). I am sure there will be other challenges and hopefully plenty of chances as well.

Let me close this post by wishing you all a Happy New Year and more important: stay safe and healthy!


Title Image by iXimus from Pixabay

Posted by msicc in Editorials, 0 comments
Some helpful extensions when dealing with types in .NET

Some helpful extensions when dealing with types in .NET

If you are writing reusable code, chances are high that you will write quite some code that deals with types, generics, and interfaces. Over the years, the collection of my helper extensions for that have grown. As some of my upcoming posts use them, I share them (also) for future reference.

1. Check if a Type is deriving from another Type

Deriving types is a common practice. To some extent, you can use pattern matching. Sometimes, that isn’t enough, though (especially if you have a multi-level derivation path). This is when I use one of these two extensions:

        public static bool IsDerivingFrom(this Type type, Type searchType)
        {
            if (type == null) throw new NullReferenceException();

            return
                type.BaseType != null &&
                (type.BaseType == searchType ||
                type.BaseType.IsDerivingFrom(searchType));
        }

        public static bool IsDerivingFromGenericType(this Type type, Type searchGenericType)
        {
            if (type == null) throw new ArgumentNullException(nameof(type));
            if (searchGenericType == null) throw new ArgumentNullException(nameof(searchGenericType));

            return
                type != typeof(object) &&
                (type.IsGenericType &&
                searchGenericType.GetGenericTypeDefinition() == searchGenericType ||
                IsDerivingFromGenericType(type.BaseType, searchGenericType));
        }

Update 1: Type.IsSubclassOf will give you the same result as IsDerivingFrom. The main purpose was (is) to use my implementation when having multiple levels of derivation and being able to debug the whole detection process.

2. Get type of T from IEnumerable<T>

Sometimes, one needs to know the item type of an IEnumerable<T>. These two extensions will help you in this case:

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Extension method")]
        public static Type GetItemType<T>(this IEnumerable<T> enumerable) => typeof(T);

        public static Type? GetItemType(this object enumerable)
            => enumerable == null ? null :
            (enumerable.GetType().GetInterface(typeof(IEnumerable<>).Name)?.GetGenericArguments()[0]);

3. Check if a type implements a certain interface

Interfaces are supposed to make the life of a developer easier. Like with the type derivation, sometimes we need to know if a type implements a certain interface. This extension answers the question for you:

        public static bool ImplementsInterface(this Type? type, Type? @interface)
        {
            bool result = false;

            if (type == null || @interface == null)
                return result;

            var interfaces = type.GetInterfaces();
            if (@interface.IsGenericTypeDefinition)
            {
                foreach (var item in interfaces)
                {
                    if (item.IsConstructedGenericType && item.GetGenericTypeDefinition() == @interface)
                        result = true;
                }
            }
            else
            {
                foreach (var item in interfaces)
                {
                    if (item == @interface)
                        result = true;
                }
            }

            return result;
        }

Update 2: Type.IsAssignableFrom will also tell you if a type implements an interface. As for the IsDerivingFrom method, I wanted to be able to debug the detection, which is – besides from having an explicit implementation – the main reason for this method.

4. Find a Type in an external assembly

If you need a type that lives in an external assembly but you only have it’s Name (or FullName, it’s easy to adapt), this one will resolve the Type for you as long as its assembly is loaded into your AppDomain:

        public static Type? FindType(this string name)
        {
            Type? result = null;
            var nonDynamicAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic);
            try
            {
                result = nonDynamicAssemblies.
                     SelectMany(a => a.GetExportedTypes()).
                     FirstOrDefault(t => t.Name == name);
            }
            catch
            {
                result = nonDynamicAssemblies.
                     SelectMany(a => a.GetTypes()).
                     FirstOrDefault(t => t.Name == name);
            }

            return result;
        }

Conclusion

Like I said in the beginning, this post will be used for future reference. These extensions made a lot of controls, MVVM implementations and business logic I wrote in the past (both for work and my private projects) a whole lot easier. Like always, I hope this post will be helpful for some of you.

Please find the full class in this Gist.

Until the next post, happy coding!

Title Image by Tim Hill from Pixabay

Posted by msicc in Dev Stories, 3 comments
Create scrollable tabs in Xamarin.Forms with CollectionView and CarouselView

Create scrollable tabs in Xamarin.Forms with CollectionView and CarouselView

When it comes to navigation patterns in mobile apps, the tabbed interface is one of the most popular options. While Xamarin.Forms has the TabbedPage (and Shell) to fulfill that need, it lacks one essential feature: scrollable tabs. After studying some of the samples floating around the web and some of the packages that provide such functionality, I tried find an easier solution.

The View

Let’s have a look at the View first. Like you may have guessed from the title, we are using a CollectionView for the tabs and a CarouselView for the Content. This combination makes it quite easy to implement tabs that cover a whole page size or smaller ones within a page.

Here’s the XAML:

<Grid x:DataType="{x:Null}" RowSpacing="0">
    <Grid.RowDefinitions>
        <RowDefinition Height="45" />
        <RowDefinition Height="45" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <CollectionView
        x:Name="CustomTabsView"
        Grid.Row="1"
        HorizontalScrollBarVisibility="Never"
        ItemSizingStrategy="MeasureAllItems"
        ItemsSource="{Binding TabVms}"
        ItemsUpdatingScrollMode="KeepItemsInView"
        SelectedItem="{Binding CurrentTabVm, Mode=TwoWay}"
        SelectionMode="Single"
        VerticalScrollBarVisibility="Never">
        <CollectionView.ItemsLayout>
            <LinearItemsLayout Orientation="Horizontal" />
        </CollectionView.ItemsLayout>
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="local:TabViewModel">
                <Grid RowSpacing="0">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="3" />
                    </Grid.RowDefinitions>
                    <Label
                        x:Name="TitleLabel"
                        Grid.Row="0"
                        Padding="15,0"
                        FontAttributes="Bold"
                        FontSize="Small"
                        HeightRequest="50"
                        HorizontalTextAlignment="Center"
                        Text="{Binding Title}"
                        TextColor="White"
                        VerticalTextAlignment="Center" />
                    <BoxView
                        x:Name="ActiveIndicator"
                        Grid.Row="1"
                        BackgroundColor="Red"
                        IsVisible="{Binding IsSelected, Mode=TwoWay}" />
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

    <CarouselView
        Grid.Row="2"
        CurrentItem="{Binding CurrentTabVm, Mode=TwoWay}"
        CurrentItemChanged="CarouselView_CurrentItemChanged"
        HorizontalScrollBarVisibility="Never"
        IsScrollAnimated="True"
        IsSwipeEnabled="True"
        ItemsSource="{Binding TabVms}"
        VerticalScrollBarVisibility="Never">
        <CarouselView.ItemTemplate>
            <DataTemplate x:DataType="local:TabViewModel">
                <Grid Margin="10">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <Label
                        Grid.Row="0"
                        Margin="10"
                        LineBreakMode="WordWrap"
                        Text="{Binding Content}"
                        VerticalTextAlignment="Center" />
                </Grid>
            </DataTemplate>
        </CarouselView.ItemTemplate>
    </CarouselView>
</Grid>

Let me break that piece down. First, I wrapped everything in a Grid for this sample. The CollectionView of course should be horizontally scrolling but should not show any scroll bar. The tab item template is not a complex one – it is just a Label and a BoxView below it to help with indication of the selection. You are free to make the tab looking whatever you want because of the CollectionView, however.

Below that, we put a CarouselView. For this sample, I just made a simple one with a Lorem Ipsum Label in it on every item.

The ViewModels

Most of you know that I absolutely love the MVVM pattern. And this sample proves me right once again. We need just need two ViewModels to handle scrolling and synchronizing.

The first ViewModel is the TabViewModel:

Snippet

public class TabViewModel : ObservableObject
{
    private string _title;
    private string _content;
    private bool _isSelected;

    public TabViewModel(string title)
    {
        this.Title = title;
        this.Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tempor id eu nisl nunc mi ipsum faucibus vitae aliquet. Turpis egestas integer eget aliquet nibh praesent tristique magna. In fermentum posuere urna nec tincidunt. Vitae congue eu consequat ac felis donec et odio pellentesque. Augue lacus viverra vitae congue. Viverra vitae congue eu consequat. Orci nulla pellentesque dignissim enim sit amet venenatis urna. Et ultrices neque ornare aenean euismod elementum nisi. Id consectetur purus ut faucibus pulvinar. In cursus turpis massa tincidunt. Egestas pretium aenean pharetra magna. Et pharetra pharetra massa massa ultricies mi quis. Nunc sed blandit libero volutpat. Purus viverra accumsan in nisl nisi scelerisque eu ultrices vitae.";
    }

    public string Title { get => _title; set => Set(ref _title, value); }

    public string Content { get => _content; set => Set(ref _content, value); }

    public bool IsSelected { get => _isSelected; set =>Set(ref _isSelected, value); }
}

The TabViewModel in this sample just has the bare minimum, namely the Title, the Content and the IsSelectedFlag to control the Visibility of the Indicator-BoxView. Nothing dramatic so far.

The MainViewModel glues everything together, so let’s have a look:

Snippet

public class MainViewModel : ObservableObject
{
    private TabViewModel _currentTabVm;

    public MainViewModel()
    {

        this.TabVms = new ObservableCollection<TabViewModel>();
        this.TabVms.Add(new TabViewModel("Short Title"));
        this.TabVms.Add(new TabViewModel("A Little Longer Title"));
        this.TabVms.Add(new TabViewModel("An Even Longer Title Than Before"));
        this.TabVms.Add(new TabViewModel("Again Short Title"));
        this.TabVms.Add(new TabViewModel("Mini Title"));
        this.TabVms.Add(new TabViewModel("Different Title"));

        this.CurrentTabVm = this.TabVms.FirstOrDefault();
    }


    public ObservableCollection<TabViewModel> TabVms { get; set; } 

    public TabViewModel CurrentTabVm 
    { 
        get => _currentTabVm;
        set
        {
            Set(ref _currentTabVm, value);
            SetSelection();
        }
    }

    private void SetSelection()
    {
        this.TabVms.ForEach(vm => vm.IsSelected = false);
        this.CurrentTabVm.IsSelected = true;
    }
}

Once again, there is nothing complex in it. We are mocking a collection of TabViewModel and handle the tab selection via Binding. After the current item got selected, we are setting the IsSelected property on it to true to show the Indicator in the CollectionView.

For this sample, I didn’t use a fully blown MVVM framework, so I am setting the BindingContext in the MainPage‘s constructor. The Binding engine in Xamarin.Forms already does almost everything to make this work.

The only thing left is to handle the positioning of the tabs if we are swiping the CarouselView. As this is purely View related, I am using the CurrentItemChanged event in code behind to center the CollectionView‘s selected item:

Snippet

private void CarouselView_CurrentItemChanged(object sender, CurrentItemChangedEventArgs e)
{
    this.CustomTabsView.ScrollTo(e.CurrentItem, null, ScrollToPosition.Center, true);
}

The result of this setup looks like this:

Conclusion

Xamarin.Forms provides a lot of solutions out of the box. Sometimes, however, these are not enough. Luckily, we can combine some of the solutions the framework provides to create fresh solutions within our apps. This post showed one of these. The additional bonus you get with this implementation is the ability to style the tabs in whatever way you want. As always, I hope this post will be helpful for some of you.

Of course, there is also sample for this post on Github.

Until the next post, happy coding, everyone!
Posted by msicc in Dev Stories, Xamarin, 2 comments
Scroll to any item in your Xamarin.Forms CollectionView from your ViewModel

Scroll to any item in your Xamarin.Forms CollectionView from your ViewModel

If you are working with collections in your app, chances are high you are going to want (or need) to scroll to a specific item at some point. CollectionView has the ScrollTo method that allows you to do so. If you are using MVVM in your app however, there is no built-in support to call this method.

My solution

My solution for this challenge consists of following parts:

  • a BindableProperty in an extended CollectionView class to bind the item we want to scroll to
  • a configuration class to control the scrolling behavior
  • a base interface with the configuration and two variants derived from it (one for ungrouped items, one for grouped ones)

Let’s have a look at the ScrollConfiguration class:

public class ScrollToConfiguration
{
    public bool Animated { get; set; } = true;

    public ScrollToPosition ScrollToPosition { get; set; } = ScrollToPosition.Center;
}

These two properties are used to tell our extended CollectionView how the scrolling to the item will behave. The above default values are my preferred ones, feel free to change them in your implementation.

Next, let us have a look at the base interface:

public interface IConfigurableScrollItem
{
    ScrollToConfiguration Config { get; set; }
}

Then we will define two additional interfaces which we are going to use later in our ViewModel:

    public interface IScrollItem : IConfigurableScrollItem
    {
    }

    public interface IGroupScrollItem : IConfigurableScrollItem
    {
        object GroupValue { get; set; }
    }

For a non-grouped CollectionView, we just need to implement IScrollItem. If we have groups, we’ll use IGroupScrollItem to add an object that identifies the group (following the Xamarin.Forms API here).

Extending CollectionView

Let’s connect the dots and implement an extended version of the CollectionView – to do so, create a new class and derive from it. I named mine CollectionViewEx (ingenious, right?).

To wrap things up, we now add a BindableProperty with a PropertyChanged handler to our CollectionViewEx that we can bind against, and which is, most importantly, calling the ScrollTo method of CollectionView.

Here is the full class:

public class CollectionViewEx : CollectionView
{
    public static BindableProperty ScrollToItemWithConfigProperty = BindableProperty.Create(nameof(ScrollToItemWithConfig), typeof(IConfigurableScrollItem), typeof(CollectionViewEx), default(IConfigurableScrollItem), BindingMode.Default, propertyChanged: OnScrollToItemWithConfigPropertyChanged);

    public IConfigurableScrollItem ScrollToItemWithConfig
    {
        get => (IConfigurableScrollItem)GetValue(ScrollToItemWithConfigProperty);
        set => SetValue(ScrollToItemWithConfigProperty, value);
    }

    private static void OnScrollToItemWithConfigPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if (newValue == null)
            return;

        if (bindable is CollectionViewEx current)
        {
            if (newValue is IGroupScrollItem scrollToItemWithGroup)
            {
                if (scrollToItemWithGroup.Config == null)
                    scrollToItemWithGroup.Config = new ScrollToConfiguration();

                    current.ScrollTo(scrollToItemWithGroup, scrollToItemWithGroup.GroupValue, scrollToItemWithGroup.Config.ScrollToPosition, scrollToItemWithGroup.Config.Animated);

            }
            else if (newValue is IScrollItem scrollToItem)
            {
                if (scrollToItem.Config == null)
                    scrollToItem.Config = new ScrollToConfiguration();

                    current.ScrollTo(scrollToItem, null, scrollToItem.Config.ScrollToPosition, scrollToItem.Config.Animated);
            }
        }
    }
}

Let’s go through the code. The BindableProperty implementation should be common to most of us (if not, read up the docs). The most important part happens in the PropertyChanged handler.

By allowing the value of the BindableProperty to be null, we can reset the item and scroll to the same item again if necessary. Because IScrollItem as well as IGroupScrollItem derive from IConfigurableScrollItem, we can handle them both in one method. To make sure there is a default ScrollToConfiguration, I am checking the Config property for null – in case it is (because I forgot it), there is at least the default. In the end, I am scrolling to the Item in the CollectionView using the ScrollTo method.

The ViewModel(s) and Binding

Here is one of the (simple) ViewModels from the sample application for this post:

public class ItemViewModel : ViewModelBase, IScrollItem
{
    public ItemViewModel()
    {
        this.Config = new ScrollToConfiguration();
    }

    public string Text { get; set; }

    public int Number { get; set; }

    public ScrollToConfiguration Config { get; set; }
}

Now in the parent ViewModel, we just add another property that we can use to bind against the CollectionViewEx‘s ScrollToItemWithConfig property. The Binding is straight forward:

<controls:CollectionViewEx
    Grid.Row="3"
    Margin="6"
    ItemsSource="{Binding ScrollableItems}"
    ScrollToItemWithConfig="{Binding ScrollToVm}"
    SelectedItem="{Binding SelectedItemVm, Mode=TwoWay}"
    SelectionMode="Single">
    <controls:CollectionViewEx.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Label Margin="5,10" Text="{Binding Text}" />
            </Grid>
        </DataTemplate>
    </controls:CollectionViewEx.ItemTemplate>
</controls:CollectionViewEx>

The result of this whole exercise looks like this:

Conclusion

Even if the CollectionView control in Xamarin.Forms provides a whole bunch of optimized functionalities over ListView, there are some scenarios that require additional work. Luckily, it isn’t that hard to extend the CollectionView. Scrolling to a precise ViewModel is easy with the code above. Of course, I created also a sample Github repo.

As always, I hope this post will be helpful for some of you.

Until the next post, happy coding, everyone!
Posted by msicc in Dev Stories, Xamarin, 1 comment
Code Snippets for Xamarin.Forms BindableProperty

Code Snippets for Xamarin.Forms BindableProperty

If you haven’t heard about the #XamarinMonth before, you should either click on the hashtag or read Luis’ blog post where he introduces the topic. At the end of his post, you will also find a link to all the contributions.

Why Code Snippets?

Code snippets make it easier to reuse code you write repeatedly during your dev life. For Xamarin Forms, there are no “built-in” snippets, so I decided to start creating my own snippets some time ago. If you want to get started, have a look at the docs.

The Snippets

If you ever wrote a custom control or an Effect for Xamarin Forms, chances are high you also used the BindableProperty functionality. I got tired of remembering the syntax, so I decided to write some snippets for it:

  • BindableProperty (bindp)
  • BindableProperty with PropertyChanged handler (bindppc)
  • Attached BindableProperty (bindpa)
  • Attached BindableProperty with PropertyChanged handler (bindpapc)

You can download all of them from my Github repo.

Once you insert (write shortcut, Tab, Tab) the snippet, you just need to define the name of the property as well as its type and hit enter – that’s it.

Tip: To make sure that the snippets show up with IntelliSense, go to Tools/Options, find the Text Editor section followed by the C# entry. Under IntelliSense, find the option for ‘Snippet behavior‘ and choose ‘Always include snippets‘.

Conclusion

Snippets can save a lot of time. Luckily, the implementation is not that difficult (see docs link above). As always, I hope this post is helpful for some of you.

Until the next post, happy coding, everyone!
Posted by msicc in Dev Stories, Xamarin, 0 comments
Sending push notifications to your Xamarin app from WordPress with Azure, Part II – the Function

Sending push notifications to your Xamarin app from WordPress with Azure, Part II – the Function

First, let’s have a look at the lineup of this series once again:

  • Preparing your WordPress (blog/site)
  • Preparing the Azure Function and connect the Webhook (this post)
  • Preparing the Notification Hub
  • Send the notification to Android
  • Send the notification to iOS
  • Adding in Xamarin.Forms

Creating a new Azure Function in Visual Studio

The most simple approach to create a new Azure Function (if you already have an Azure account) is adding a new project to your Xamarin solution:

After the project is loaded, double click on the .csproj file in the Solution Explorer to open the file for editing it. Make sure you have the following two PropertyGroup entries:

  <PropertyGroup>
    <TargetFramework>net461</TargetFramework>
    <AzureFunctionsVersion>v1</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <!--DO NOT UPDATE THE AZURE PACKAGES, IT WILL BREAK EVERYTHING!!!!-->
    <PackageReference Include="Microsoft.Azure.NotificationHubs" Version="1.0.9" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.NotificationHubs" Version="1.3.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.31" />
    <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
  </ItemGroup>

You may notice that I made an all caps comment into the second PropertyGroup entry. As I am using a v1 Function, these are the latest packages that I am able to use. They are doing their job, and allow us to use an easy way to bind the Function to the Azure NotificationHub , which we are going to implement in the next post. I delayed updating the whole setup to use a v2 function intentionally at this point.

Processing the Webhook payload

In order to be able to process the payload (remember, we are getting a JSON string) from our WordPress Webhook, we need to deserialize it. Let’s create the class that holds all information about it:

using Newtonsoft.Json;

namespace NewPostHandler
{
    public class PublishedPostNotification
    {
        [JsonProperty("id")]
        [JsonConverter(typeof(StringToLongConverter))]
        public long Id { get; set; }

        [JsonProperty("title")]
        public string Title { get; set; }

        [JsonProperty("status")]
        public string Status { get; set; }

        [JsonProperty("featured_media")]
        public string FeaturedMedia { get; set; }
    }
}

The class gets it pretty straight forward, we will use this implementation as-is for the payload we are sending to Android later on. The use of the StringToLongConverter is optional. For completeness, here is the implementation:

using Newtonsoft.Json;
using System;

namespace NewPostHandler
{
    public class StringToLongConverter : JsonConverter
    {
        public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);

        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null) return default(long);
            var value = serializer.Deserialize<string>(reader);
            if (long.TryParse(value, out var l))
            {
                return l;
            }

            return default(long);
        }

        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
        {
            if (untypedValue == null)
            {
                serializer.Serialize(writer, null);
                return;
            }
            var value = (long)untypedValue;
            serializer.Serialize(writer, value.ToString());
            return;
        }

        public static readonly StringToLongConverter Instance = new StringToLongConverter();
    }
}

Now that we prepared our data transferring object, it is time to finally have a look at the processor code.

[FunctionName("HandleNewPostHook")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, TraceWriter log)
{
    _log = log;
    _log.Info("arrived at 'HandleNewPostHook' function trigger.");

    //ignoring any query parameters, only using POST body

    PublishedPostNotification result = null;

    try
    {
        _jsonSerializerSettings = new JsonSerializerSettings()
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal },
                StringToLongConverter.Instance
            }
        };

        _jsonSerializer = JsonSerializer.Create(_jsonSerializerSettings);

        using (var stream = await req.Content.ReadAsStreamAsync())
        {
            using (var reader = new StreamReader(stream))
            {
                using (var jsonReader = new JsonTextReader(reader))
                {
                    result = _jsonSerializer.Deserialize<PublishedPostNotification>(jsonReader);
                }
            }
        }

        if (result == null)
        {
            _log.Error("There was an error processing the request (serialization result is NULL)");
            return req.CreateResponse(HttpStatusCode.BadRequest, "There was an error processing the post body");
        }

       //subject of the next post
      //await TriggerPushNotificationAsync(result);
    }
    catch (Exception ex)
    {
        _log.Error("There was an error processing the request", ex);
        return req.CreateResponse(HttpStatusCode.BadRequest, "There was an error processing the post body");
    }

    if (result.Id != default)
    {
        _log.Info($"initiated processing of published post with id {result.Id}");
        return req.CreateResponse(HttpStatusCode.OK, "Processing new published post...");
    }
    else
    {
        _log.Error("There was an error processing the request (cannot process result Id with default value)");
        return req.CreateResponse(HttpStatusCode.BadRequest, "There was an error processing (postId not valid)");
    }
}

Let’s go through the code. The first thing I want to know is if we ever enter the Function, so I log the entrance. The second step is setting up the JsonSerializer to deserialize the payload into the DTO class I created before.

There are several scenarios that I am handling and returning different responses. Ideally, we would run through and arrive at the TriggerPushNotificationAsync call, followed by a jump the ‘OK‘- response if the post id received from our Webhook is valid. During testing, however, I ran into other situations as well, where I return a ‘Bad Request‘ response with a hint that something went wrong.

The implementation of the TriggerPushNotificationAsync method is not shown in this post as it will be subject of the next post in this series.

Testing the code locally

One of the reasons I chose to start the Function in Visual Studio is its ability to debug it locally. If you don’t have the necessary tools installed, Visual Studio will prompt you to do so. After installing them, you’ll be able to follow along.

Once the service is running, we will be able to test our function. If you haven’t already heard about it, Postman will be the easiest tool for that. Copy the function url and paste it into the url field in Postman. Next, add a sample JSON payload to the body (settings: raw, JSON) and hit the ‘Send’ button:

If all goes well, Postman will give you a success response:

The Azure CLI will also write some output:

As you can see, all of our log entries were written to the CLI, plus some additional information from Azure itself. Don’t worry for the moment about the anonymous authorization state, this is just because we are running locally. In theory, we could already publish the function to Azure now. As we know that we will extend the Function in the next post, however, we will not do this right now.

Conclusion

As you can see, writing an Azure Function isn’t as complicated as it sounds. Visual Studio brings all the tools you need to get started pretty fast. The ability to test the Function code locally is another big advantage that comes with Visual Studio.

In the next post, we will configure the NotificationHub on Azure and extend our Function to call into it and fire the notifications.

Until the next post, happy coding, everyone!
Posted by msicc in Android, Azure, Dev Stories, iOS, Xamarin, 1 comment