Monday, 7 October 2019

Xamarin iOS 13 App Crash Resolution

Coming back to wanting to build the iOS version of an application, I ran into an issue where the application crashed on startup. Before this the following occurred :-

  • Visual Studio 2019 on the Mac was upgraded
  • Visual Studio 2017 on the PC no longer built the application
    • Wanting to downgrade what was on the Mac in terms of Xamarin.iOS version
  • Visual Studio 2019 on the PC was installed
  • iPhone 7 was upgraded to iOS 13
From Debugging, it seemed to be related to prompting for permission of the Location services, which sent me down a certain path, which then lead me to the following thread :-


A post on this thread by sschmidTU pointed me in the direction of viewing the console from the iOS device via XCode :-


"Also, to get console output for your crash on a release version on device:
connect your device to your Mac
open XCode
go to Window -> Devices and Simulators
click Open Console for your device
in the Console, type your app name in the search window to filter the output."

Having filtered the console output using the application name, I found that the application was crashing because the Bluetooth Permission was being prompted for however I didn't have the NSBluetoothAlwaysUsageDescription key in my Info.plist.

Looking at the documentation for this key, it is new in iOS 13 :-


Once the NSBluetoothAlwaysUsageDescription key was added, the application no longer crashes on startup.

Thursday, 1 March 2018

How do I automatically version Xamarin.Android Library projects?

I had run into this issue when trying to build NuGet packages for Android projects before but had forgotten the solution.

The following thread details the resolution :-

https://forums.xamarin.com/discussion/48765/how-do-i-automatically-version-xamarin-android-library-projects

In summary, ensure the appropriate Mono.Android.dll version is copied to the \bin\Debug folder for your project and then the various details will be picked up from the AssemblyInfo.cs, including the Version number.

Thursday, 7 September 2017

iOS P12 Creation

When exporting a P12 from Key Chain Access, you should right click on the certificate and click Export and not export against the Private Key.

Tuesday, 9 May 2017

iOS App Package Creation

We had a requirement to create .app packages of our Xamarin Forms application for submission to a third party. The requirement was to create this for a iPhone 6 iOS 10.2 Simulator.

Initially I thought rebuilding the solution in Visual Studio 2015 would be enough as this would create what looked like the .app package however when using the following command line :-

xcrun simctl install booted /users/[username]/desktop/certificates/[username]/[packagename].app 

This resulted in a "Failed to chmod : No such file or directory" error.

 To resolve this issue I found that along with rebuilding the solution in Visual Studio, you need to deploy the application to the simulator, which inflates the .app package file by ~50MB, and on inspection of the before and after .app packages, the DLLs and EXE are included which allows the .app package file to be deployed to the simulator successfully, using the command line above.

Friday, 10 April 2015

StringToColorConverter for Xamarin.Forms

You may have a requirement to bind a string property to a Color property, such as TextColor. If this is the case then you will need to create a converter to perform the conversion from string to Color. The following is a sample of such a converter :-

Firstly, the converter :-

using System;
using System.Globalization;
using Xamarin.Forms;
namespace LabelTextColorSample
{
    public class StringToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string valueAsString = value.ToString();
            switch (valueAsString)
            {
                case (""):
                    {
                        return Color.Default;
                    }
                case ("Accent"):
                    {
                        return Color.Accent;
                    }
                default:
                    {
                        return Color.FromHex(value.ToString());
                    }
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
}

Then the XAML which consumes it :-


    
        
            
        
    
    
Then the setting of the BindingContext :-

using Xamarin.Forms;
namespace LabelTextColorSample
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            this.BindingContext = MyViewModel.Instance;
        }
    }
}

And finally the ViewModel :-

namespace LabelTextColorSample
{
    public class MyViewModel
    {
        private static MyViewModel _instance;
        public static MyViewModel Instance
        {
            get { return _instance ?? (_instance = new MyViewModel()); }
        }
        public string MyTextColor
        {
            get { return "#00FF00"; }
        }
    }
}

Hope this is helpful.

Wednesday, 8 April 2015

Range Slider Renderer for Xamarin.Forms

Based on the Range Slider component in the Xamarin Components store, I have created a renderer so that the Range Slider can be used in Xamarin.Forms.

Firstly, I created a RangeSlider control in the Xamarin.Forms PCL, as follows :-
using Xamarin.Forms;

namespace RangeSliderSample
{
 public class RangeSlider : View
 {
  public static readonly BindableProperty LeftValueProperty =
   BindableProperty.Create(p => p.LeftValue, 0f);

  public float LeftValue
  {
   get { return (float) GetValue(LeftValueProperty); }
   set { SetValue(LeftValueProperty, value); }
  }

  public static readonly BindableProperty RightValueProperty =
   BindableProperty.Create(p => p.RightValue, 0f);

  public float RightValue
  {
   get { return (float) GetValue(RightValueProperty); }
   set { SetValue(RightValueProperty, value); }
  }

  public static readonly BindableProperty MaxValueProperty =
   BindableProperty.Create(p => p.MaxValue, 1f);

  public float MaxValue
  {
   get { return (float) GetValue(MaxValueProperty); }
   set { SetValue(MaxValueProperty, value); }
  }

  public static readonly BindableProperty MinValueProperty =
   BindableProperty.Create(p => p.MinValue, 0f);

  public float MinValue
  {
   get { return (float) GetValue(MinValueProperty); }
   set { SetValue(MinValueProperty, value); }
  }

  public static readonly BindableProperty StepProperty =
   BindableProperty.Create(p => p.Step, 0f);

  public float Step
  {
   get { return (float) GetValue(StepProperty); }
   set { SetValue(StepProperty, value); }
  }
 }
}

I then placed this control on a XAML page :-

 
  
  
  
 



I then created a Custom Renderer in the Android project :-
using RangeSlider;
using RangeSliderSample.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(RangeSliderSample.RangeSlider), typeof(RangeSliderRenderer))]
namespace RangeSliderSample.Droid
{
 public class RangeSliderRenderer : ViewRenderer
 {
  private RangeSliderView _slider;
  
  protected override void OnElementChanged(ElementChangedEventArgs e)
  {
   base.OnElementChanged(e);

   var rangeSlider = e.NewElement as RangeSlider;

   if (rangeSlider != null)
   {
    _slider = new RangeSliderView(Context, rangeSlider.MinValue, rangeSlider.MaxValue, rangeSlider.Step);

    _slider.LeftValueChanged += value =>
    {
     rangeSlider.LeftValue = _slider.LeftValue;
    };

    _slider.RightValueChanged += value =>
    {
     rangeSlider.RightValue = _slider.RightValue;
    };

    SetNativeControl(_slider);
   }
  }
 }
}

The complete solution is here :-
http://www.smartmobiledevice.co.uk/Samples/Xamarin/RangeSliderSample.zip

Xamarin Android Player and McAfee

I normally use a device for all my debugging in Xamarin however I thought I would try the Xamarin Android Player.

After installing and downloading an emulator image I tried starting the emulator however I was present with the following error :-

 OpenGL server is unreachable. Please check that Xamarin Android Player is allowed through your firewall on public networks.

 As I use McAfee, my firewall settings are handled by McAfee rather than the Windows Firewall. I viewed the Firewall settings for the Xamarin Android Player (AndroidPlayer) under "View firewall and anti-spam settings > Firewall > Internet Connections for Programs", and it was set to use "Designated Ports". Editing this entry and setting Incoming and Outgoing to "Open ports to Work and Home networks" now allows me to use the Xamarin Android Player.

Wednesday, 4 March 2015

Setting Color as HSLA using XAML Extension for Xamarin.Forms

The following shows how to set a Color to a HSLA value using a XAML Extension.

Firstly, define a new class called ColorAsHslaExtension.cs :-

[ContentProperty("ColorAsHsla")]
public class ColorAsHslaExtension : IMarkupExtension
{
 public string ColorAsHsla { get; set; }

 public object ProvideValue(IServiceProvider serviceProvider)
 {
  var elements = ColorAsHsla.Split(',');

  double h = double.Parse(elements[0]);
  double s = double.Parse(elements[1]);
  double l = double.Parse(elements[2]);
  double a = double.Parse(elements[3]);

  return Color.FromHsla(h, s, l, a);
 }
}

Next, define the XAML that you make use of the Extension :-


 

Hope this helps.

Update

After reading page 146 of the following :-

https://download.xamarin.com/developer/xamarin-forms-book/BookPreview2-Ch08-Rel0203.pdf

It seems there is a much simpler way of achieving this :-


    
       
          
             0.67
             1.0
             0.5
             1.0
          
       
    

Friday, 20 February 2015

Xamarin.Forms ListView Drag and Drop to Reorder

We are currently looking at ways to add some UX improvements to our application so I thought I would investigate drag and drop on ListView.

There doesn't seem to be anything out of the box yet in Xamarin.Forms so I did a search and found the following :-

http://xamurais.com/drag-and-drop-entre-listview-en-xamarin-android/

This sample was written in classic Xamarin.Android, however I was looking for a Xamarin.Forms implementation. This sample however provided me with the ground work for the sample I propose below.

My sample is only targeting Android at the moment.

My implementation consists of a ViewCellRenderer, this allows you to define a ListView with an ItemTemplate, so that you can bind your ListView to more than a List.

MyViewCellRenderer.cs :-

using System.Collections;
using Android.Content;
using Android.Views;
using ListViewDragDropSample.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using View = Android.Views.View;

[assembly: ExportRenderer(typeof(ViewCell), typeof(MyViewCellRenderer))]
namespace ListViewDragDropSample.Droid
{
 public class MyViewCellRenderer : ViewCellRenderer
 {
  public ListView ParentListView { get; set; }

  public IList Items { get; set; }

  protected override View GetCellCore(Cell item, View convertView, ViewGroup parent, Context context)
  {
   ParentListView = item.ParentView as ListView;

   if (ParentListView != null)
   {
    Items = ParentListView.ItemsSource as IList;
   }

   var cellcore = base.GetCellCore(item, convertView, parent, context);

   cellcore.Drag -= CellcoreOnDrag;
   cellcore.Drag += CellcoreOnDrag;

   return cellcore;
  }

  private void CellcoreOnDrag(object sender, View.DragEventArgs args)
  {
   ViewGroup = sender as ViewGroup;

   if (ViewGroup != null)
   {
    ListView = ViewGroup.Parent.Parent as Android.Widget.ListView;
   }

   switch (args.Event.Action)
   {
    case DragAction.Started:
     args.Handled = true;
     break;

    case DragAction.Entered:
     args.Handled = true;

     if (ListView != null)
     {
      if (FirstIndex == -1)
      {
       FirstIndex = ListView.IndexOfChild(ViewGroup.Parent as View);
      }
     }

     break;

    case DragAction.Exited:
     args.Handled = true;
     break;

    case DragAction.Drop:
     args.Handled = true;

     if (SecondIndex == -1)
     {
      SecondIndex = ListView.IndexOfChild(ViewGroup.Parent as View);
     }

     if (FirstIndex != -1)
     {
      var firstItem = Items[FirstIndex];

      if (firstItem != null)
      {
       Items.RemoveAt(FirstIndex);
       Items.Insert(SecondIndex, firstItem);

       ParentListView.ItemsSource = null;
       ParentListView.ItemsSource = Items;
      }
     }

     FirstIndex = -1;
     SecondIndex = -1;

     break;
    case DragAction.Ended:
     args.Handled = true;
     break;
   }
  }

  public Android.Widget.ListView ListView { get; set; }

  public ViewGroup ViewGroup { get; set; }

  private static int _firstIndex = -1;
  private static int _secondIndex = -1;

  public static int FirstIndex
  {
   get { return _firstIndex; }
   set { _firstIndex = value; }
  }
  public static int SecondIndex
  {
   get { return _secondIndex; }
   set { _secondIndex = value; }
  }
 }
}

MyListViewRenderer.cs :-

using Android.Content;
using ListViewDragDropSample.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(ListView), typeof(MyListViewRenderer))]
namespace ListViewDragDropSample.Droid
{
 public class MyListViewRenderer : ListViewRenderer
 {
  protected override void OnElementChanged(ElementChangedEventArgs e)
  {
   base.OnElementChanged(e);

   Control.ItemLongClick += (s, args) =>
   {
    ClipData data = ClipData.NewPlainText("List", args.Position.ToString());
    MyDragShadowBuilder myShadownScreen = new MyDragShadowBuilder(args.View);
    args.View.StartDrag(data, myShadownScreen, null, 0);
   };
  }
 }
}

MainPage.xaml :-

 
  
   
    
     
      
    
   
  
 


MainPage.xaml.cs :-

using System.Collections.Generic;
using Xamarin.Forms;

namespace ListViewDragDropSample
{
 public partial class MainPage : ContentPage
 {
  public MainPage()
  {
   InitializeComponent();

   Items = new List();

   for (int i = 1; i < 11; i++)
   {
    Items.Add(new Item()
    {
     Title = "Title : " + i,
     Description = "Description : " + i,
    });
   }

   BindingContext = this;
  }

  public List Items { get; set; }
 }
}



MyDragShadowBuilder.cs :-
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.Views;

namespace ListViewDragDropSample.Droid
{
 public class MyDragShadowBuilder : View.DragShadowBuilder
 {
  private Drawable shadow;

  public MyDragShadowBuilder(View v)
   : base(v)
  {
   v.DrawingCacheEnabled = true;
   Bitmap bm = v.DrawingCache;
   shadow = new BitmapDrawable(bm);
   shadow.SetColorFilter(Color.ParseColor("#4EB1FB"), PorterDuff.Mode.Multiply);
  }

  public override void OnProvideShadowMetrics(Point size, Point touch)
  {
   int width = View.Width;
   int height = View.Height;
   shadow.SetBounds(0, 0, width, height);
   size.Set(width, height);
   touch.Set(width / 2, height / 2);
  }

  public override void OnDrawShadow(Canvas canvas)
  {
   base.OnDrawShadow(canvas);
   shadow.Draw(canvas);
  }
 }
}


And finally the Item.cs :-

namespace ListViewDragDropSample
{
 public class Item
 {
  public string Title { get; set; }
  public string Description { get; set; }
 }
}

The complete sample is here :-

http://www.smartmobiledevice.co.uk/Samples/Xamarin/ListViewDragDropSample.zip

Xamarin.Forms TabbedPage and Swipe

As of version 1.3.5-pre1 of Xamarin.Forms, there doesn't seem to be a way to swipe a TabbedPage on Android out of the box.

I first thought I could add the gesture via a GestureListener in a Custom Renderer, however this causes issues when trying to swipe while showing a full screen button or ListView, as these two controls consume the Gestures, so this wasn't an option.

I then had an idea about combining a CarouselPage and TabbedPage, hence this post.

This is very convoluted and will not perform very well when used in complex UI layouts, but it might be useful.

First the XAML :-

 
  
   
    
     
      
     
    
    
    
   
  
  
   
    
    
     
      
     
    
    
   
  
  
   
    
    
    
     
      
     
    
   
  
 


As you can see this layout won't work for Windows Phone and I haven't tested this on iOS however I am only really targeting Android at the moment.

Next is the C# :-

public partial class MainPage : TabbedPage
{
 public MainPage()
 {
  InitializeComponent();

  AttachCurrentPageChanged();
 }

 private void AttachCurrentPageChanged()
 {
  Page1.CurrentPageChanged += MultiPage_OnCurrentPageChanged;
  Page2.CurrentPageChanged += MultiPage_OnCurrentPageChanged;
  Page3.CurrentPageChanged += MultiPage_OnCurrentPageChanged;
 }

 private void DetachCurrentPageChanged()
 {
  Page1.CurrentPageChanged -= MultiPage_OnCurrentPageChanged;
  Page2.CurrentPageChanged -= MultiPage_OnCurrentPageChanged;
  Page3.CurrentPageChanged -= MultiPage_OnCurrentPageChanged;
 }

 private void MultiPage_OnCurrentPageChanged(object sender, EventArgs e)
 {
  DetachCurrentPageChanged();

  CarouselPage carouselPage = sender as CarouselPage;
  if (carouselPage != null)
  {
   int indexOf = carouselPage.Children.IndexOf(carouselPage.CurrentPage);

   var tabbedPage = carouselPage.ParentView as TabbedPage;

   if (tabbedPage != null)
   {
    tabbedPage.CurrentPage = tabbedPage.Children[indexOf];

    var newCarouselPage = tabbedPage.CurrentPage as CarouselPage;

    if (newCarouselPage != null)
    {
     newCarouselPage.CurrentPage = newCarouselPage.Children[indexOf];
    }
   }
  }

  AttachCurrentPageChanged();
 }
}
The OnCurrentPageChanged is used to track the Page Change of the CarouselPage, the index of this page is then used to set the CurrentPage of the next CarouselPage.

As this tracking needs to occur the number of child Pages in each of the CarouselPages needs to equal the numbwe of Tabs you would like to show.

If you want to add more Tabs, you add more CarouselPage's as children of the TabbedPage and then ensure that each CarouselPage is updated with the correct number of children.

This is by far an ideal solution but was interesting nevertheless.

The complete sample is here :-

http://www.smartmobiledevice.co.uk/Samples/Xamarin/SwipeTabbedPageSample.zip

Wednesday, 14 January 2015

Xamarin.Forms Samples

I have started posting Xamarin.Forms Samples to the following :-

http://www.smartmobiledevice.co.uk/Samples/

Please let me know if there are any samples you would like to see.

Friday, 6 September 2013

Win a Nokia Lumia 920 with SMDWP.co.uk

Visit the following link for a chance to Win a Nokia Lumia 920 with SMDWP.co.uk. All you need is a Twitter account :-

Win a Nokia Lumia 920 with SMDWP.co.uk

Good Luck!

Wednesday, 30 January 2013

Calling WCF REST Service from Jquery causes 405 method Not Allowed and Authorization

I was investigating how to call a REST web service using an Authorization header from jQuery but was running into a cross domain issue. I found the following blog post which detailed changes to the Global.asax :-

http://blog.weareon.net/calling-wcf-rest-service-from-jquery-causes-405-method-not-allowed/

After a bit of head scratching, I found that the above solution required an addition to support an Authorization header.

So from the above blog post, the following line :-

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");

Needed to read :-

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");

Friday, 3 August 2012

Win a Nokia Lumia 710 with SMDWP.co.uk

Visit the following link for a chance to Win a Nokia Lumia 710 with SMDWP.co.uk. All you need is a Twitter account :-

Win a Nokia Lumia 710 with SMDWP.co.uk

Good Luck!

Monday, 14 May 2012

IsolatedStorageFile Remove and Shared ShellContent

I have been working on a new feature of an application that is displaying some information on a custom Live tile. The source of the image used for the tile is stored in the Shared/ShellContent directory of the application's Isolated Storage. The application also has the ability to clear it's Isolated Storage for resetting purposes.

The issue then came about when the reset was performed this cleared the whole of the Isolated Storage including the Shared directory. The code I am using to then create the PNG in Isolated Storage failed with a "Operation not permitted on IsolatedStorageFileStream." exception.

The Shared directory seems to be created when the application is first deployed to the device so my Live tile was working fine until the reset was performed.

So if you are using a PNG from Isolated Storage for your Live tile, please make sure you don't remove the entire Isolated Storage for the application.

I used the Isolated Storage Explorer Tool to investigate this problem :-

http://msdn.microsoft.com/en-us/library/hh286408(v=vs.92).aspx

Tuesday, 24 April 2012

Windows Phone Performance Analysis Tool : Part 4 of n

My next observation is using the PhotoChooserTask.

The associated graph is as follows :-


As you can see, we have Storyboard start when the button is tapped to launch the task.

We then have a period of inactivity before the Image is loaded.

The Image loads has a flag dictating the Image is loaded into the Image control.

If you have any experiences to share with using the Performance Analysis Tool, I would be very interested to hear them.

More to follow...

Windows Phone Performance Analysis Tool : Part 3 of n

My next observation is adding a PerformanceProgressBar, from the Silverlight for Windows Phone Toolkit.

I added the PerformanceProgressBar and set IsIndeterminate to True, I then let the PerformanceProgressBar run for two cycles, the associated graph is as follows :-


As you can see, the Storyboard starts as soon as the application starts.

The CPU usage increases as the PerformanceProgressBar animates, it then reduces for around a second and then starts again.

You can also see the Frame rate increase when the PerformanceProgressBar is animating.

Could a performance issue be "masked" when using the PerformanceProgressBar? Or would we see a spike in the CPU usage?

If you have any experiences to share with using the Performance Analysis Tool, I would be very interested to hear them.

More to follow...

Windows Phone Performance Analysis Tool : Part 2 of n

My next observation is based on adding a button to the same solution as previously created, then implement a DispatcherTimer to increment a Count property, this Count property is data bound to the Content property of the Button control. Tapping the button starts the DispatcherTimer, the Dipatcher time then increments the Count property every 250ms, determining if the Count has reached 10, if it has then the DispatcherTimer.Stop method is called.

The associated graph is as follows :-


As you can see there is a regular frame rate increase as the Button Content is updated.

Also worth noting is the Start of a Storyboard which is inline with the tapping of the Button.

If you have any experiences to share with using the Performance Analysis Tool, I would be very interested to hear them.

More to follow...

Windows Phone Performance Analysis Tool : Part 1 of n

My second observation is related to the Keyboard appearing and disappearing. To the project I created in the previous post, I have added a TextBox control.

Here is the graph produced :-

As you can see the CPU usage relating to the startup and shutdown of the application still remains however now we have a section in the middle relating to the showing of the keyboard (applying focus to the textbox).

The showing of the keyboard has forced the Frame rate to shoot up, however this seems to be normal in the other applications I have tested.

If you have any experiences to share with using the Performance Analysis Tool, I would be very interested to hear them.

More to follow...