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