torsdag den 12. oktober 2017

Visual Studio Prism snippets

The Prism template package is great, but I decided to change the "cmd" snippet to this:


<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets
    xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Prism Async DelegateCommand</Title>
      <Shortcut>cmdasync</Shortcut>
      <Author>Mikkel Jensen</Author>
      <Description>Creates an async DelegateCommand property</Description>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>fieldName</ID>
          <ToolTip>Replace with the field name</ToolTip>
          <Default>fieldName</Default>
        </Literal>
        <Literal>
          <ID>CommandName</ID>
          <ToolTip>Replace with the command name</ToolTip>
          <Default>CommandName</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[private DelegateCommand $fieldName$Command;
        public DelegateCommand $CommandName$Command
        {
            get
            {
                $fieldName$Command = $fieldName$Command ?? new DelegateCommand(async () => await Do$CommandName$Command()).ObservesCanExecute(() => CanExecute$CommandName$Command);
                return $fieldName$Command;
            }
        }

        private bool _canExecute$CommandName$Command = true;
        public bool CanExecute$CommandName$Command
        {
            get { return _canExecute$CommandName$Command; }
            set { SetProperty(ref _canExecute$CommandName$Command, value); }
        }

        private async Task Do$CommandName$Command()
        {
        }
        $end$]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>


onsdag den 10. maj 2017

Visual Studio Xamarin MvvmCross Code Snippets

Visual Studio Xamarin MvvmCross Code Snippets

Introduction

This post is based on this StackOverflow question which contains visual studio code snippets to help with MvvmCross development.

Updated

We have updated the mvxprop snippet as well as added "mvxasynccom" to let you easily add async commands to your viewmodels.

Install

Save the following code in a file called updated-mvx.snippet

In visual studio:
Tools -> Code Snippets Manager -> Click "My Code Snippets" and click the "Import..." button.
Select the file and hit okay. You should now be able to use "mvxprop", "mvxcom", "mvxasynccom" and "mvxset" in your code.

File: updated-mvx.snippet


<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>MvvMCross Property</Title>
      <Description>Insert a property block with a backing field and property change notification</Description>
      <Shortcut>mvxprop</Shortcut>
      <Author>Mikkel Jensen (based on Andrew Coates and Aboo's SO answers</Author>
      <HelpUrl>http://stackoverflow.com/questions/18200679/mvvmcross-code-snippets-for-visual-studio</HelpUrl>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>backingfield</ID>
          <ToolTip></ToolTip>
          <Default>propertyName</Default>
        </Literal>
        <Literal>
          <ID>property</ID>
          <ToolTip></ToolTip>
          <Default>PropertyName</Default>
        </Literal>
        <Literal>
          <ID>propertyType</ID>
          <ToolTip></ToolTip>
          <Default>int</Default>
        </Literal>
      </Declarations>
      <Code Language="CSharp">
        <![CDATA[private $propertyType$ $backingfield$;
        public $propertyType$ $property$
        {
          get { return $backingfield$; }
          set { SetProperty(ref $backingfield$, value, "$property$"); }
        }
        $end$]]>
      </Code>
    </Snippet>
  </CodeSnippet>
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>MvvMCross Command</Title>
      <Description>Insert a Command declaration for an MvvMCross View Model</Description>
      <Shortcut>mvxcom</Shortcut>
      <Author>Mikkel Jensen (based on Andrew Coates and Aboo's SO answers</Author>
      <HelpUrl>http://stackoverflow.com/questions/18200679/mvvmcross-code-snippets-for-visual-studio</HelpUrl>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>backingfield</ID>
          <ToolTip></ToolTip>
          <Default>commandName</Default>
        </Literal>
        <Literal>
          <ID>Name</ID>
          <ToolTip></ToolTip>
          <Default>CommandName</Default>
        </Literal>
      </Declarations>
      <Code Language="CSharp">
        <![CDATA[private MvxCommand $backingfield$Command;

        public MvxCommand $Name$Command
        {
          get
          {
            $backingfield$Command = $backingfield$Command ?? new MvxCommand(Do$Name$Command);
            return $backingfield$Command;
          }
        }

        private void Do$Name$Command()
        {
          $end$
        }

        ]]>
      </Code>
    </Snippet>
  </CodeSnippet>
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>MvvMCross Async Command</Title>
      <Description>Insert a Command declaration for an MvvMCross View Model</Description>
      <Shortcut>mvxasynccom</Shortcut>
      <Author>Mikkel Jensen (based on Andrew Coates and Aboo's SO answers</Author>
      <HelpUrl>http://stackoverflow.com/questions/18200679/mvvmcross-code-snippets-for-visual-studio</HelpUrl>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>backingfield</ID>
          <ToolTip></ToolTip>
          <Default>commandName</Default>
        </Literal>
        <Literal>
          <ID>Name</ID>
          <ToolTip></ToolTip>
          <Default>CommandName</Default>
        </Literal>
      </Declarations>
      <Code Language="CSharp">
        <![CDATA[private MvxAsyncCommand $backingfield$CommandAsync;

        public MvxAsyncCommand $Name$CommandAsync
        {
          get
          {
            $backingfield$CommandAsync = $backingfield$CommandAsync ?? new MvxAsyncCommand(Do$Name$CommandAsync);
            return $backingfield$CommandAsync;
          }
        }

        private void Do$Name$CommandAsync()
        {
          $end$
        }

        ]]>
      </Code>
    </Snippet>
  </CodeSnippet>
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>MvvMCross Binding Set</Title>
      <Description>Create a binding set and bind an element</Description>
      <Shortcut>mvxset</Shortcut>
      <Author>Mikkel Jensen (based on Andrew Coates and Aboo's SO answers</Author>
      <HelpUrl>http://stackoverflow.com/questions/18200679/mvvmcross-code-snippets-for-visual-studio</HelpUrl>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>viewName</ID>
          <ToolTip></ToolTip>
          <Default>viewName</Default>
        </Literal>
        <Literal>
          <ID>element</ID>
          <ToolTip></ToolTip>
          <Default>element</Default>
        </Literal>
      </Declarations>
      <Code Language="CSharp">
        <![CDATA[var set = this.CreateBindingSet<$viewName$View, $viewName$ViewModel>();
        set.Bind($element$).To(vm => vm$end$);
        set.Apply();
        ]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

lørdag den 6. maj 2017

Artm Fetcher - A simple network layer library

Network layer in Xamarin apps


Introduction

Doing network such as downloading a JSON file from a webserver can be, perhaps surprisingly, difficult on mobile devices
  • You need to ensure you're using the platform-specific optimized network api calls to get SPDY, GZIP, HTTP/2, etc.
  • You need to have a retry mechanism if the server is unresponsive
  • You need to have a caching layer to
    • Minimize network usage, as connections are often metered
    • Improve performance
    • Handle unresponive servers / endpoints / no internet connection
  • You need to handle the Cold Start problem: the very first time an app is started and there is no valid internet available. You should be able to ship your app with preloaded data for a given url.

Example time!

Artm Fetcher solves this in a simple and easy to use manner. Use the following code in both your Android and iOS project:
IFetcherRepositoryStoragePathService path = new FetcherRepositoryStoragePathService();
IFetcherRepositoryService repository = new FetcherRepositoryService(path);
IFetcherWebService web = new FetcherWebService();

// Primary interface you should use
IFetcherService fetcher = new FetcherService(web, repository);

var url = new System.Uri("https://www.google.com");

// (Optional) Cold start: You can ship with preloaded data, and thus avoid
// an initial requirement for an active internet connection
fetcher.Preload(url, "<html>Hello world!</html>");

// Try our hardest to give you *some* response for a given url. 
// If an url has been recently created or updated we get the response from the local cache.
// If an url has NOT recently been created or updated we try to update 
// the response from the network. 
// If we cannot get the url from the network, and no cached data is available, we try to use preloaded data.
IUrlCacheInfo response = await fetcher.Fetch(url); 

Implementation details

Artm Fetcher uses SQLite for storing its cache. The file is called "fetcher.db3" by default and is stored in the apps internal storage.

Artm Fetcher implements an exponential backoff retry mechanism using Polly . Retries 5 times by default.

Get it here

NuGet: https://www.nuget.org/packages/artm.fetcher/

MvvmCross Plugin GitHub: https://github.com/mgj/MvvmCross-Plugins
MvvmCross Plugin NuGet: https://www.nuget.org/packages/artm.mvxplugins.fetcher/