Visual Studio, Xamarin Forms and Intellisense Errors

This is a bit of an odd one … I was working away on a Xamarin Forms project and suddenly started getting dozens of the red squigglies in the code editor. I could compile the project, but intellisense kept showing all of these errors.

I tried cleaning the solution, manually deleting all the bin and obj folders in all the projects, reloading projects, re-referencing projects. It didn’t matter, whatever I did still showed all kinds of errors, most of them being of the type “the type or namespance name could not be found”.

Finally I was able to track it down. The solution was to find the offending project in the solution (i.e. the one that contains the types that are throwing the errors) and remove it as a reference from the other projects. Then add the removed reference back in to each of the projects (Note you only have to do this for the projects that are showing the errors). After that, the intellisense is reset and all of the squigglies are gone!

 

Google Play Services on Marshmallow

When it comes to working on Android apps, I really feel like I am starting completely from scratch … or maybe even a bit less than that. And I end up running across weird problems that end up causing me all kinds of issues. This post will talk about one of those problems and how I combined the posts of two others (who I am sure know much more than I about Android) to address my issue.

I am working on an app that uses maps. I am planning on targeting Marshmallow at a minimum. I am also using the Visual Studio Android Emulator. If you don’t already know, the Visual Studio emulator doesn’t come with the Google Play Services, which are required if you want to use maps in your app.

In a previous app, I was able to spin up an emulator, go to http://teamandroid.com/gapps, download the appropriate zip file and drag and drop to the emulator to install. This worked great for me on both KitKat and Lollipop emulators. On Marshmallow … not so much.

I started surfing … I mean researching. And in my research I came across an article from Cheesebaron which you can see here. In a nutshell, he recommends (with references) two different gapps packages to download. The only problem was that when I tried his method of downloading and drag and drop installing, my emulator just started an endless loop of optimizing packages and rebooting.

I then found another article from Rob Prouse about how to do a low level install of gapps packages from the SD card. When I tried his method, which used the gapps package from teamandroid.com, that failed as well. But at least it seemed to install without any obvious errors.

I finally deleted my emulator, started up a new one and combined the two articles. I downloaded the two packages recommended by Cheesebaron. I installed the first one in the manner recommended by Rob Prouse and after installation, was able to setup my Google account on the emulator. I then installed the second package from Cheesebaron using the same SD card installation method. After rebooting the emulator, I was able to deploy my app and run it. I am not sure if this is normal behavior, but I had to go into the app settings on the emulator and enable location for it. In the past, I seem to remember it asking me on first install, but I could be mistaken.

My new Marshmallow emulator setup is as follows:

  • Download gapps packages from Cheesebaron’s article:
  • Install the first package via the emulator SD card as per Rob Prouse
  • Create your google account in the settings/accounts
  • Install the second package via the emulator SD card as per Rob Prouse.

Hopefully this helps someone else and if not, writing it down will help me.

 

Xamarin Dev Days Lab – Prism Step 3

Introduction

In our last post, we set up the view model for the SpeakersPage and made use of the built in view model functionality included in Prism. We setup a base view model for our app to contain common functionality. The SpeakersViewModel class has the implementation code for retrieving the list of speakers embedded in the view model itself. Fine for a demo, but in a real app, we would be better served by moving this functionality out and using it via an interface. By implementing the functionality as an interface, we will be able to reuse the code in other view models. Since the SpeakersPageViewModel only knows it via the interface, we will also be able to mock the service with known values for use in unit tests, without changing the view model. And we can use the Prism framework and the dependency injection that is built in to make this easier. So lets take a look at this.

The Interface

The first thing we want to do is look at the functionality that is currently in our view model class. All it is doing is calling a web api to return a list of speakers. That seems pretty straight forward. Let’s start our interface with that:


public interface ISpeakersService
{
    Task<List<Speaker> GetAllSpeakersAsync();
}

Implementing will be easy: we already have all the code that we need in the view model from the demo app:


public class SpeakersService : ISpeakersService
{
    public async Task<List<Speaker>> GetAllSpeakersAsync()
    {
        using (var client = new HttpClient())
        {
            //grab json from server
            var json = await client.GetStringAsync(
                "http://demo4404797.mockable.io/speakers");

             //Deserialize json
             var items =
                JsonConvert.DeserializeObject<List<Speaker>>(json);
             return items;
        }
    }
}

//

From above, you can see that we have just moved all of the implementation code from the view model into a separate service object. So how do we start using this new code in our SpeakersViewModel?
The first thing we need to do is register this service in our App object. Remember that we are registering via an interface: this means we can change out the implementation at any time.
Here is the RegisterTypes function in the App object updated to register the service:


protected override void RegisterTypes()
{
    Container.RegisterType
        <Services.ISpeakersService, Services.SpeakersService>();
    Container.RegisterTypeForNavigation
        <View.SpeakersPage, ViewModel.SpeakersViewModel>();
}

Next we need to refactor the SpeakersViewModel: we will add the interface to the view model constructor and change the GetSpeakersAsync to call the interface to retrieve the speakers data:


public class SpeakersViewModel : BaseViewModel
{
    private Services.ISpeakersService _speakersService = null;

    public SpeakersViewModel(Services.ISpeakersService speakersService)
        : base()
    {
        _speakersService = speakersService;
    }

    /// other parts of the view model go here
    /// now lets look at GetSpeakers ...
    private async Task GetSpeakers()
    {
        if (IsBusy)
            return;

        Exception error = null;
        try
        {
            IsBusy = true;

            var items =
                await _speakersService.GetAllSpeakersAsync();
            Speakers.Clear();

            foreach (var item in items)
                Speakers.Add(item);
        }
        catch (Exception ex)
        {
            error = ex;
        }
        finally
        {
            IsBusy = false;
        }

        if (error != null)
            await Application.Current.MainPage.DisplayAlert(
                "Error!",
                error.Message,
                "OK");
    }

}

So what do we have above? All of a sudden the ViewModel has a dependency on ISpeakersService. But we weren’t creating the view model in the first place: instead, Prism and the AutoWireViewModel attached property (see the previous blog post) are creating the view model for us and attaching it to the page. When Prism does this, it uses the container that was selected (step 01 blog) to create the view model and all the dependencies that are required for the view model, and it does this via reflection and then looking at what you specified in the App.RegisterTypes method. I hope that you can see that you can change up the implementation details of the interface without ever affecting the view model itself. You can even unit test your view model by mocking the service.

Now the view model just makes a call to retrieve the speakers. It has no idea if the speaker are read from a web api, a database, a file or even from memory! It just knows to make the call and it will get the data.

I really want to emphasize this: the view model knows nothing. It has no dependency on any implementation and you can change that around as you see fit! In fact, I am going to change the code of the SpeakersService implementation. I captured the json payload that was returned from the web api and saved it as a constant in the implementation. Now instead of calling out to the web api, I just return the json payload directly, and now for testing, everything is much quicker. And as mentioned earlier, using these known values, I can use this implementation for unit testing of the view model.


public class SpeakersService : ISpeakersService
{
    /// you can see this actual string value in the GitHub repo
    /// under step 03
    private const string JsonResponse =
        "...json response string captured from web api";

    public async Task<List<Speaker>> GetAllSpeakersAsync()
    {
        var items =
            JsonConvert.DeserializeObject<List<Speaker>>(JsonResponse);
        return items;
    }
}

Recap

We have taken the next step in making the dev days app a little more production worthy. We took out the implementation of our speakers service away from the view model, defined it as an interface and injected that into our view model. We used the dependency injection that is built into Prism to inject the implementation of the service into the view model. And then for fun (and quicker testing), we changed the implementation of the interface to serve up the results from a json payload that had been captured previously. Now we can do testing much quicker.

All of this code can be found in the Step03 portion of the repository. Make sure you check out the two different implementations of ISpeakersService contained in the SpeakersService.cs file and how they could be registered in App.cs.

The next step will be to add navigation to the app so we can see the details of a selected speaker.

XF – Setup your App and Emulator

My computer was having some issues and I had to rebuild it. Luckily with Windows 10, this has never been a faster process. I make heavy use of Visual Studio team services, GitHub and OneDrive so backups are pretty easy too.

One thing I was struggling restoring was the capability of debugging my Android Xamarin Forms app in the Visual Studio emulator. Every time I started it up, it would immediately stop. Looking at the error messages in the debug output showed messages around the mscorlib.dll.so library.

All credit to this fix goes to Joost van Schaik and his post. As luck would have it, this is how I fixed it the first time, I just couldn’t remember it!

First thing is change your android options. Right click on your “droid” project and select “Properties”. Click on “Android Options” and make sure that “Use Fast Deployment (debug mode only)” is unchecked.

fastdeployment

Next you need to go into your emulator settings and fix up the processor settings. Click on the start menu button and type “hyper” and select “Hyper-V Manager”.

Right-click on the desired emulator and select settings:

hypervmanager

It’s a little hard to see, but under the context menu, you can see KitKat which is the emulator that I have been using. Settings should give you the following screen. Expand the processor node, click on “Compatibility” and make sure “Migrate to a physical computer with a different processor version” is checked. Note that you will only be able to do this if the emulator isn’t running.

emulator-processor-compat

And that was it. Once I made these two changes, I was able to debug in Visual Studio once again.

Hope you find this helpful and that by doing this post, I will remember the next time I need to rebuild my dev environment! For links to more information on these settings, I would suggest checking out Joost’s post on this subject.