Tuesday, December 23, 2014

Mailing using Device.OpenUri on iOS in Xamarin Forms

Short version

Device.OpenUri will not work if passing it a mailto-uri on iOS that contains spaces or escaped spaces. Check out work around at the bottom.

Long version

The "issues" are iOS specific since Android seems to swallow all that comes its way.

The starting point is these two lines of code placed somewhere in the shared code (PCL or shared) in a Xamarin Forms solution.

    var uri = "mailto:info@johankarlsson.net?subject=subject&body=body";
    Device.OpenUri(new Uri(uri));


This works fine!

Adding spaces, not working

    var uri = "mailto:info@johankarlsson.net?subject=more in subject&body=body";
    Device.OpenUri(new Uri(uri));


This gives you an "System.Exception: Could not initialize an instance of the type 'MonoTouch.Foundation.NSUrl': the native 'initWithString:' method returned nil."

Alright, so we URI encode it to

    var uri = "mailto:info@johankarlsson.net?subject=more%20in%20subject&body=body";
    Device.OpenUri(new Uri(uri));


Same issue... And that's a bit weird since Apples own documentation states that this is the way to do it. (https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MailLinks/MailLinks.html#//apple_ref/doc/uid/TP40007899-CH4-SW1)

Trying Apples own example Uri

With a copy of the example Uri from Apples documentation it should work.

    var uri = "mailto:foo@example.com?cc=bar@example.com&subject=Greetings%20from%20Cupertino!&body=Wish%20you%20were%20";
    Device.OpenUri(new Uri(uri));
  

It does not.

Conclusion

This seems to be a bug for Bugzilla to handle... (https://bugzilla.xamarin.com/show_bug.cgi?id=25584)

Workaround


Friday, December 19, 2014

FilesWrittenAbsolute.txt

Another short tip

When cloning a project for use on Mac and Xamarin Studio that was originally created in Visual Studio on PC, you might encounter a "Could not find part of the path" build error.

It's simply just some missing folders.

For example, if the error looks something like this:

Error: Could not find a part of the path "/Users/johankarlsson/Projects/TheProject/TheProject.Core/obj/Debug/TheProject.Core.csproj.FilesWrittenAbsolute.txt".

Simply create the obj/Debug folder missing and the build will succeed.

Thursday, December 18, 2014

"The memory needed by this VM exceeds the driver limit"

Short tip!

If you run into the error message "The memory needed by this VM exceeds the driver limit." when running a x86 emulator from intel and Android 5 (API level 21), just reinstall HAXM and assign more memory. About 3GB should do it.




Download Intels HAXM from

https://software.intel.com/en-us/android/articles/intel-hardware-accelerated-execution-manager

For more info on setting up HAXM in Parallells, check out Daniels blogpost.

http://danielhindrikes.se/tag/parallels/ 

Friday, November 21, 2014

Mvvm done right

I attended Microsoft TechDays in Stockholm a couple of days ago and went to a session called "MVVM done right". I must say that I was kind of disappointed since it was just a show on how to set up Caliburn.Micro really. 

This leads me thinking about writing my own article shortly. Perhaps titled "MVVM really done right"! But it might be a little bold to challenge a Windows Phone MVP on the matter.

Any one out there that has a good resource on what MVVM really should look like? Don't point on a framework, give me a real article that explains the architecture instead!

Tuesday, November 4, 2014

Updating to live Office 365 tools

The API tools for Office 365 have been released. Check out http://chakkaradeep.com/index.php/update-to-office-365-api-tools-and-client-libraries/ to download.

A few things could be good to know about this release.

Please correct me if I'm wrong about any of these points. I'm not an Office developer at all. :)

Reauthentication if using multiple services

At least if you're using the tools in an Xamarin Ios app. As long as you're using a single service, you're fine. BUT if you decide to use, let's say Contacts and My Files in the same app then you will have to reauthenticate each time you switch between them.

Getting a folder structure in My Files

Nope, doesn't work. In the preview you could rebuild the structure by using part of the Id of each item returned. This has been changed and there is no way to retrieve the folders in a structured way. You get all folders without them being related.

Updating from preview to live

1. Uninstall all the nuget-packages
2. Add the new packages by right clicking your project, select Add and then select Connected Service.
3. Remove all the permissions or it will fail when you hit OK.
4. Click OK (nothing will happen)
5. Add Connected Services again and reset all your permissions.

Sunday, October 19, 2014

IOS 8 breaks MonoGame

It seems like IOS 8 breaks the way touches are handled in MonoGame for IOS. After updating the active touch area seems to be flipped in portrait mode even though the game is landscape. If you touch the right side of the screen, you'll get this error:

unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: ; layer = >
2

Looking at the frame, it's clearly expecting touch in the bounds of a portrait layout.

The nuget packages are not updated yet. It seems that some work has been done to address this though.

Hopefully the nuget-packages will be updated soon.

Resource

Tuesday, September 9, 2014

Setting up MonoGame for iOS in Xamarin Studio

This is a walk-through for setting up MonoGame on an iOS device in Xamarin Studio.

NOTE: The nuget-packages currently does not support 64-bit. I'm sure it will be updated soon.

Create a new iOS project

Create a new solution and add an empty Universal iOS project.

Add the MonoGame nuget package

Right-click the iOS project and select Add -> Add Packages..


Search for MonoGame and select the first package that contains the project Templates.

Rereference the binaries

For some reason, the binaries isn't references correctly. If you build now it will not find any Xna/MonoGame related stuff.

Right-click the iOS project and select Edit References. Navigate back to the projects root folder and then down to Packages/MonoGame.Binaries.3.2.0/build/MonoTouch. Select both assemblies and click the Add button.

Delete the old startup stuff

Remove/delete AppDelegate.cs and Main.cs.

Build and run

The app will hopefully start up with the standard cornflower blue shade of nothingness.



All you have to do now is create a game and get rich!



Wednesday, September 3, 2014

Navigation from ViewModel using Xamarin.Forms

I'm probably going to get shot for this post by MVVM-purists but I'll write it anyway. :) Worth noting is that the guys over at Xamarin Forms Labs extends stuff to let you navigate easier. This is the vanilla approach.

I described the basic of MVVM using Xamarin.Forms in a previous post and I'd like to extend it a little bit to allow for navigation from the ViewModel.

The example app was dead simple and allowed for a name to be updated in a fake repository. The command defined in the ViewModel looked like this:

      public ICommand Save
        {
            get {
                return new Command (() => {

                    // Perform some logic
                    Updated = DateTime.Now.ToString();

                    // Store data to back end
                    var person = _repository.GetPerson(42);
                    person.Name = _name;
                    person.Updated = _updated;
                    _repository.Update(person);
                });
            }
        }


I would now like to extend this so that I can navigate to a thank you page. The problem is that the Navigation stuff is part of the base classes that our pages inherit from. After all, the ViewModel is just a POCO that implements INotifyPropertyChanged and nothing else.

Step 1 - We need some references

We need a reference to an object implementing the INavigation interface. This is where some people get nervous that we pollute the ViewModel with stuff from the View. Well, so be it. This could also be moved to a ViewModel base class if you'd like.

   public class MainPageViewModel : INotifyPropertyChanged
    {
        private PersonRepository _repository;
        private INavigation _navigation; // HERE

        public MainPageViewModel (INavigation navigation) // HERE
        {
            _navigation = navigation; // AND HERE

            // This should be injected
            _repository = new PersonRepository();

            // Populate the ViewModel
            var person = _repository.GetPerson(42);
            Name = person.Name;
            Updated = person.Updated;
        }
    }

We created a private field and assigned by using a reference passed to us in the constructor.

Step 2 - Pass the reference

We need to pass the reference to the Navigation object from the page. 

    public partial class MainPage : ContentPage
    {    
        public MainPage ()
        {
            InitializeComponent ();
            BindingContext = new MainPageViewModel (this.Navigation); // HERE
        }
    }

Step 3 - Modify the app startup to allow for navigation

To be able to navigate, we must wrap out MainPage in a NavigationPage as such:

    public class App
    {
        public static Page GetMainPage ()
        {    
            return new NavigationPage (new MainPage());
        }
    }

Step 4 - Navigate on Command

Update our Save command to navigate to the ThanksPage!

        public ICommand Save
        {
            get {
                return new Command (async () => { // HERE

                    // Perform some logic
                    Updated = DateTime.Now.ToString();

                    // Store data to back end
                    var person = _repository.GetPerson(42);
                    person.Name = _name;
                    person.Updated = _updated;
                    _repository.Update(person);

                    await _navigation.PushAsync(new ThanksPage()); // HERE
                });
            }
        }

Conclusion

Why do we do this? The reason is to avoid writing code in the views code behind and define all logic and navigation in the ViewModel. Since the navigation is exposed as an interface, I'd say this is a valid way to do it.

It also seems like the Navigation object is a new instance on each page, so don't save a global reference since that might break something later on.

Tuesday, September 2, 2014

Updating Xamarin.Forms.Labs to beta6 broke my project

I updated Xamarin.Forms to 1.2.2.6243 and also updated Xamarin.Forms.Labs to beta6. This broke my app at runtime with the following error.

2014-09-02 08:14:06.189 FormsTemplateiOS[4440:70b] Could not register the assembly 'Xamarin.Forms.Labs.iOS': System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.

Simple solution though, just check your project file for the iOS project and make sure the hintpath points to the correct package.

   
      ..\..\packages\Xamarin.Forms.Labs.1.1.1-beta6\lib\MonoTouch\Xamarin.Forms.Labs.dll
   

   
      ..\..\packages\Xamarin.Forms.Labs.1.1.1-beta6\lib\MonoTouch\Xamarin.Forms.Labs.iOS.dll
   

Monday, August 18, 2014

Multiple networks in Parallels

Spent a good hour trying to get multiple networks to work in Parallels. The solution was quite simple. My setup is common for mobile developers.

I have a local cable bound network that is connected to the internet at work. I also have a wireless router setup just to enable my mobile devices to be able to connect to my computer. I tried to create two networks in on my virtual machine, but that failed of course.

The solution was to just add one network and set it as Shared Network. It magically exposes both networks to my virtual machine.


Tuesday, July 29, 2014

MVVM in Xamarin Forms

Ah, another pattern to learn. But this one actually fits my way of thinking. I'm going to explain MVVM as it is used in Xamarin Forms. I'll start with a brief definition of some key terms and finish off with a walk-through and then a quick "what to do next" section.

There are other MVVM frameworks, like MvvmCross and some work in progress by the guys at Xamarin Forms Labs. This post is just about the bare metal, without third party involvement. We're going to keep it clean.

So MVVM you say

I can think of several cool things about MVVM. The first is that it's a rare FOUR (4) letter abbreviation instead of the IT industri standard of three. Don't get confused by this, it is a real pattern anyhow. If I know my IT history correctly I think it was Microsoft who first coined the expression. To be specific it was John Gossman in 2005, while working on WPF.

MVVM stands for Model-View-ViewModel. A quick definition of each component below.

Model

The model is your data... A domain model, a text-file or your data access layer. The most important point is that the data has no knowledge about the View or the ViewModel. It lives its own life. There are two different approaches.

  • The data-centric where the model is a text-file or a data access layer. 
  • The object-centric where the model is a domain model.

View

The view just renders the data. In Xamarin Forms this is a Page. The data is bound using data binding. If you use Xaml, it would look something like this:

<Label Text="{Binding Title}" VerticalOptions="Center" HorizontalOptions="Center" />

The view is like, I don't care what I'm bound to, except that it needs to have a property called Title that is a string. Binding can also be more complex, like two-way that updates when the ViewModel changes. The ViewModel-class would then have to implement the INotifyPropertyChanged interface so that the view would be aware of the change. Most other MVVM-frameworks have base classes that helps you do this. We're not going to bother with those in this post.

The view also generates a code behind file that in its best form should look something like this

using MvvmSample.ViewModels;
using Xamarin.Forms;

namespace MvvmSample
{    
    public partial class MainPage : ContentPage
    {    
        public MainPage ()
        {
            InitializeComponent ();
            BindingContext = new MainPageViewModel ();
        }
    }
}


It should in my perfect world only call InitalizeComponent cause it needs to and then directly set the BindingContext. Any logic should be handled by the ViewModel. If you start writing code in the code behind for the View, your a bad person... Simple as that...

There are many other ways to instantiate the ViewModel, for example via a Factory or Inversion of Control. Most likely you would want to defer the instantiation of the ViewModel away from the view itself.

ViewModel

This is the part I love the most about MVVM. The ViewModel is a smart class that feeds the View with data and listens to events (commands) raised by the view. It contains properties and commands that the view binds to. It mediates between the view and the model. This way we can keep the view and the model totally unaware of each other without gettings stuck in architectural hell.

For MVVM to really shine you need to implement INotifyPropertyChanged on the ViewModel. This lets the View know and respond to the fact that the underlaying data changed. The interface is very simple

Commands

Let's say we have a button in our view defined as below.

<Button Command="{Binding Click}" 
            Text="Click me!" 
            VerticalOptions="Center" 
            HorizontalOptions="Center"  />

The binding of the Command-property specifies that the ViewModel exposes an property that returns an instance of an object that implements ICommand. A very simple implementation of this could look like this.

        public ICommand Click
        {
            get {
                return new Command (() => {
                    Debug.WriteLine ("Click");
                });
            }
        }

Worth noting is that the constructor of the Command-object has four overloads. Two of them requires a Func that gets called by the view to determine if the button can be clicked or not. The cool thing is that the code to determine this is in the ViewModel, not the view.

       public Command (Action execute, Func canExecute)

Binder

The Binder is the thingy that makes sure the data and events gets passed between the View and the ViewModel. It can bind one-way or two-ways. An example of a two-way binding is when a property in the ViewModel changes, the bound element in the View also updates. In Xamarin, the binder is a property on the BindableObject class this is a base class deep down for all page types. You set bindings as showed in Xaml above or with code within your view (Page) like below.

  var label = new Label ();
  label.SetBinding (Label.TextProperty, new Binding ("Title"));

This binds the text property to a property called Title on the BoundingContext (your ViewModel that is). I find the Xaml-way easier to deal with since you don't get any code in your code behind. The code is does the same thing as the Xaml-sample earlier.

A walk-through


Initial project setup

Create a new Blank App under C#/Mobile Apps. I prefer the PCL template, but you could go with shared if it suits you better.


Add three folders called Views, ViewModels and Models. This structure is just a preferens of my own liking and you could organize your project anyway you'd like.

Add a page (view)

In the View-Folder, add a page called MainPage.xaml and add the following Xaml.

xml version="1.0" encoding="UTF-8"?>
<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="MvvmSample.MainPage">

    <StackLayout VerticalOptions="Start"
        HorizontalOptions="Center" 
        Padding="0,30,0,0" >
        
        <Label Text="Name" />
        <Entry Text= "{Binding Name}" />

        <Label Text="Last updated" />
        <Label Text="{Binding Updated}" />

        <Button Command="{Binding Save}" 
            Text="Save my name" 
            VerticalOptions="Center" 
            HorizontalOptions="Center"  />

    </StackLayout>
</ContentPage>


In the code-behind, add this:

using MvvmSample.ViewModels;
using Xamarin.Forms;

namespace MvvmSample
{    
    public partial class MainPage : ContentPage
    {    
        public MainPage ()
        {
            InitializeComponent ();
            BindingContext = new MainPageViewModel ();
        }
    }
}


Add the ViewModel

The ViewModel is the glue between your view and your data. Add a class called MainPageViewModel in the ViewModels folder.

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Xamarin.Forms;

namespace MvvmSample.ViewModels
{    
    public class MainPageViewModel : INotifyPropertyChanged
    {
        public MainPageViewModel ()
        {
            Updated = DateTime.Now.ToString();
            Name = "Minecraft Steve";
        }

        private string _name;
        public string Name
        {
            get 
            { 
                return _name; 
            }
            set 
            {
                _name = value;
                OnPropertyChanged();
            }
        }

        private string _updated;
        public string Updated
        {
            get 
            {
                return _updated;
            }
            set 
            {
                _updated = value;
                OnPropertyChanged ();
            }
        }

        public ICommand Save
        {
            get {
                return new Command (() => {

                    // TODO - Save the data somewhere
                    Updated = DateTime.Now.ToString();
                });
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) 
            {
                handler(this, new PropertyChangedEventArgs (propertyName));
            }
        }
    }
}


This is where the bulk of our logic sits. The main points to focus at is the following:

  • The ViewModel implements INotifyPropertyChanged that defines an event called PropertyChanged. Simply raise this event every time a property changes.
  • The ViewModel is in charge of talking to the model. This is stubbed out in the Save command. Also notice that the save command updates the Updated property. This in turn leads to the event PropertyChanged being raised, which makes the View update (Courtesy of the binding mechanism in MVVM).
  • In the OnPropertyChanged function, notice the CallerMemberName attribute. It's syntactic sugar that tells the compiler to replace the argument with the name of the member who calls it. In this case, the property name. I makes your code look a little nicer, but it could be replaced with the actual name in each call from the properties setters. 

Tell the app where to begin

In App.cs, alter the GetMainPage method to return a new instance of the MainPage.

using System;
using Xamarin.Forms;

namespace MvvmSample
{
    public class App
    {
        public static Page GetMainPage ()
        {    
            return new MainPage ();
        }
    }
}

The finished app

Ok, this is pretty much the lamest app in the book, but here's the result. You can change the name and when you hit "Save my name" the ViewModel is updated resulting in the view rebinding to the new data.

What about the model?

Let's add a fake backend to this incredible app. Add the following code in the Models folder. Split it in two files if it makes you feel better.

using System;

namespace MvvmSample
{
    public class Person
    {
        public string Name {
            get;
            set;
        }

        public string Updated {
            get; 
            set;
        }
    }

    public class PersonRepository
    {
        private Person _theOnlyPerson;
    
        public PersonRepository ()
        {
            _theOnlyPerson = new Person () {
                Name = "Johan Karlsson",
                Updated = DateTime.Now.ToString()
            };
        }

        public Person GetPerson(int id)
        {
            return _theOnlyPerson;
        }

        public void Update(Person person)
        {
            _theOnlyPerson = person;
        }
    }
}

Open up the ViewModel again and replace it with the code below. This doesn't change the way the app works but it gives you a boiler plate for how to relate to the model. I prefer to let the ViewModel fetch the back end objects and map them to properties of the View Model and then refetch and update in the Save command. This way you get a single "transactable" call to the repository if you're using one.

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Xamarin.Forms;

namespace MvvmSample.ViewModels
{    
    public class MainPageViewModel : INotifyPropertyChanged
    {
        private PersonRepository _repository;

        public MainPageViewModel ()
        {
            // This should be injected
            _repository = new PersonRepository();

            // Populate the ViewModel
            var person = _repository.GetPerson(42);
            Name = person.Name;
            Updated = person.Updated;
        }

        private string _name;
        public string Name
        {
            get 
            { 
                return _name; 
            }
            set 
            {
                _name = value;
                OnPropertyChanged();
            }
        }

        private string _updated;
        public string Updated
        {
            get 
            {
                return _updated;
            }
            set 
            {
                _updated = value;
                OnPropertyChanged ();
            }
        }

        public ICommand Save
        {
            get {
                return new Command (() => {

                    // Perform some logic
                    Updated = DateTime.Now.ToString();

                    // Store data to back end
                    var person = _repository.GetPerson(42);
                    person.Name = _name;
                    person.Updated = _updated;
                    _repository.Update(person);
                });
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) 
            {
                handler(this, new PropertyChangedEventArgs (propertyName));
            }
        }
    }
}


What now?

When you feel comfortable with how the View, Model and ViewModel interact you should look at Inversion of Control. I think that is the next logical step to achieve a good base for your mobile app.