Website Links

Monday 4 September 2017

C# - Automapper vs Factory Methods

When converting data from one model to another, there is often the thought over whether it would be beneficial to use automapper or whether factory methods should be used to explicitly convert between models. I'm going to explain what each of these is, and explain a couple of advantages and disadvantages of each.

Automapper

Automapper is a NuGet package that allows you to "get rid of code that mapped one object to another". It is convention based, and if there are a large number of properties that are identical on 2 classes it can save a lot of developer time converting between objects. It also means that less code can be written for this conversion... Yay! However, there are a couple of disadvantages that come with convention based as opposed to explicit programming, and Automapper is no exception!

If you are using Automapper with default mappings and refactor the name of the source/target model, then you won't necessarily know until runtime because it won't cause a compile time error. The issue is that if there is a rename of the property, automapper will no longer be able to map correctly. Whereas if you were to explicitly code the conversion, there would be a compile time error so you can identify the error earlier. The risk of this failed mapping occurring can be mitigated by unit testing the mapping.

A similar issue to this is that there is a lack of static analysis. For example, if you find all references of a property it may look like nothing is referencing that property so you may be tempted to remove it. However, automapper could be mapping to this property without you even realising.

Overall, Automapper is a well tested library that can save you time writing uninspiring conversion code, but there are downsides and different scenarios may mean that it is beneficial or not.

Factory Methods

Factory methods allow you to explicitly convert between objects. Due to the explicit conversion, it is easy for developers working on the same project to see where values are coming from. This is because it is not hidden behind a library that the developer may or may not be familiar with. It is also easier to debug. If mapping is done incorrectly there will also be compile time errors which can help catch issues earlier.

Of course, there is a reason the Automapper NuGet package exists and this is because the manual conversion is tedious and takes time that could be spent on other things. The manual conversion also means that there is more code sitting in your project. Additionally, with anything manual there is the chance of human error and 2 properties that don't actually align with each other could potentially be mapped. Your unit tests should pick this up though.

When trying to choose between Automapper and Factory methods, think about your code and how well the objects will map automatically without configuration. Secondly, consider the important of static analysis and compile time errors in your code. This isn't a one-size fits all comparison, it's case by case as to which will be beneficial!

Friday 1 September 2017

C# - Extension Methods

Extension methods allow you to extend functionality of a specific type. It is a special kind of static method that you can call as if it were an instance method on the object of the specified type. Extension methods are simple to define and you can define them as follows:

  using System;
     
  public class Program
  {
    public static void Main()
    {
      string message = "Hello World";
      Console.WriteLine(message.GetDatedMessage());
    }
  }

  // Extension methods must be contained within a non-generic static class
  public static class StringExtensions 
  {
    // Extension methods must be static
    // Extended object must be prefixed with this
    public static string GetDatedMessage(this string message) {
      return String.Format("{0}: {1}", DateTime.Now, message);
    }
  }

Visual Studio - How to generate a NuGet package on build

NuGet packages are extremely useful way to add libraries/components to your code base. This is similar to the traditional way of referencing DLLs except that you get notifications when there are updates.

You may find that if your code lives in separate Git repositories that if someone wants to use a project from one Git repo in another Git repo that they would need to download both. However, NuGet packages can be stored in a common location e.g. the NuGet Package Gallery which is available to all, or on a centralised private NuGet server. If you want to use a private NuGet server, you will need to add a package source in the NuGet package manager. You can do this by clicking the little cog next to "Package source".

Now for actually generating the NuGet package you can do this automatically on build, by opening a right clicking on a project and selecting properties. Then navigate to the "Package" tab and check "Generate NuGet package on build"

Tuesday 15 August 2017

iTunes Connect - Tracking Financials

Payments and Financial Reports

You can go here to review your confirmed sales for closed months. It will give you a breakdown by currency and an estimated conversion.

Sales and Trends

This will show you a graph of your sales. You can see which apps have sold, and roughly how many proceeds you have.

When will I get paid?

Payments for a lot of countries will be after you've earned $10 USD. Some countries require a minimum payment threshold of $150 USD. The payment will happen approximately 30-45 days after the financial reports for the month in which you reached the minimum payment threshold. The payment will be made to your designated bank. You can read more about it on Apple's "Getting Paid" Resources and Help page. If you meet these criteria and you haven't received a payment, you may want to check that your bank account details have been supplied under "Agreements, Tax, and Banking". You should also check that you have a valid contract with Apple as this will also cause payments to be held.

Friday 21 July 2017

C# - Encrypting the App.config

Sometimes when you are storing sensitive information in the App.config e.g. API keys or database connection strings, you don't want to store them in plain text. Fortunately, visual studio provides a command line tool that enables you to encrypt sections of your App.config. These are automatically decrypted by the ConfigurationManager when you try to access the settings.
  1. Create a copy of your App.config called web.config. This is because the command line tool you will use to encrypt your settings will look for a web.config.
  2. Open the Developer Command Prompt for VS
  3. Enter the following command:
    aspnet_regiis -pef [section to encrypt] [path containing web.config]
  4. Copy the contents of the web.config into the App.config.

It is best that you have a separate section from appSettings for your encrypted settings as this will mean you will be able to change plain-text settings e.g. API URLs or retry attempts, without having to go through the encryption process. To create this section your App.config before encryption could look as follows:

  <?xml version="1.0" encoding="utf-8" ?>
  <configuration>
    <configSections>
      <section name="EncryptedSettings" 
               type="System.Configuration.NameValueSectionHandler" />
    </configSections>
    <startup>
      <supportedRuntime version="v4.0" 
                        sku=".NETFramework,Version=v4.5" />
    </startup>
    <appSettings>
      <add key="RetryAttempts" value="3" />
    </appSettings>
    <EncryptedSettings>
      <add key="username" value="username" />
      <add key="password" value="password" />
    </EncryptedSettings>
  </configuration>


If your web.config existed in your C:\Encryption directory, it could be encrypted using the command:
aspnet_regiis -pef "EncryptedSettings" C:\Encryption
This section of the App.config can be accessed from the code as follows:

  string devUrl = string.Empty;
  var settings = ConfigurationManager.GetSection("EncryptedSettings") 
                 as NameValueCollection;
  var username = settings["username"];

Thursday 18 May 2017

C# - Asynchronicity and the Main Thread

When you call an asynchronous method from your Main method of a console application in C#, you may experience the situation where your program runs to completion without hitting breakpoints following an await. An example of this is below:


  namespace ConsoleTests
  {
      class Program
      {
          static void Main(string[] args)
          {
              var content = Get(args[0]);
          }

          public static async Task Get(string url)
          {
              using (HttpClient client = new HttpClient()) {
                  HttpResponseMessage response = await client.GetAsync(url);

                  //Breakpoint set here
              }
          }
      }
  }


The reason for this is that when Main exits the program exists, and any outstanding async operations are cancelled along with it. This can be solved by changing
 var content = Get(args[0]); 
to
 var content = Get(args[0]).Wait(); 
to block Main from exiting.

Tuesday 9 May 2017

C# - Polling Service

The Code

Polling services can be incredibly useful for picking up when something has changed and performing some actions. This post will cover how to set one up in C#. Firstly, you will want to create a new project with type Windows Service in Visual Studio:


You will then want to rename Service1.cs and all its references to be something more representative of your polling service. You will also want to update the name the polling service will appear with by clicking on Service1.cs to open the designer, and then right click within the designer and choose "Properties", then update ServiceName in the Properties view.


In order to view the code backing the polling service you can click on "click here to switch to code view" from within the designer. This code should look something like this:

    using System.ServiceProcess;
    using System.Timers;

    public partial class Service1 : ServiceBase
    {
        private Timer _timer;

        public Service1()
        {
            InitializeComponent();

            // Instantiating timer with 1000ms 
            // Every 1000ms the handler specified against _timer.Elapsed
            /// will be called. 
            _timer = new Timer(1000);
            _timer.Elapsed += ProcessThings;
        }

        private void ProcessThings(object sender, ElapsedEventArgs e)
        {
            // What you want to poll for 
        }

        protected override void OnStart(string[] args)
        {
            _timer.Start();
        }

        protected override void OnStop()
        {
            _timer.Stop();
        }
    }
 

You can put whatever you want in ProcessThings but personally, I add a console application project to the solution that handles all of the processing. This way I can debug it at will without the need to install the polling service/wait for the polling period.

Installation

Click on Service1.cs, then right click and choose "Add Installer", you can name serviceProcessInstaller1 and serviceInstaller1 whatever you like. Click on serviceProcessInstaller1 and select what account you would like the polling service to run with, I chose Local System which is quite common, and means that it is using the local user's account. After this you can build your project. To install it open the Developer Command Prompt for VS 2017 as an administrator and then navigate to where the .exe of your project is.

You can install using the following command:
installutil /i WindowsService1.exe

Alternatively, you can uninstall using the following command:
installutil /u WindowsService1.exe

Monday 8 May 2017

React Native #9 - Babel

Babel is a dependency that React Native has. Babel lets you write ES2016/ES6 and then it converts this to JavaScript (ES5) that will run on your browser. This is because at the current point in time, the latest version of all major browsers have interpreters that can interpret ES5.

ES2015 adds syntactic sugar to ES5, that can result in faster JavaScript development. It can also result in tidier more readable source code, although of course readability is heavily opinion based so ES6 syntax may not be for everyone. It aims to tackle some of JavaScript's shortcomings addressed by TypeScript/CoffeeScript. This means you can write lambda expressions, JSX, and other syntax available in ES2015.

To write ES2015 in React Native apps you don't need to do any additional work as it is configured by default. However, you can write straight JavaScript if you want to.

References

Try Babel
JSX
JavaScript and ECMAScript

Tuesday 4 April 2017

CORS & Preflight Requests

When you make a cross domain request from your website you may have your request fail. One of the potential causes for this is that the API you're calling does not handle preflight requests. You will know that this is the case because you will see an OPTIONS request to the API you made the call to, but this call will fail and no subsequent GET/POST/PUT or whatever other HTTP call you were trying to make will be made.

What's the point?

Preflight requests arose as CORS made it possible to specify more headers and requests methods in a request than was previously possible to make cross origin. This meant that some servers were developed under the assumption that they would not receive these cross-origin requests and would thus be protected from them. A preflight request provides a way for the server to opt into receiving these requests, as the server must respond to the OPTIONS request with the types of methods, headers, and origins that it accepts. This protects the server (particularly older servers), without the need for the server to change as if it doesn't respond to the OPTIONS request with headers that match the request, then the subsequent request will not be made.

Note: not all HTTP requests will have a preflight request. If the request was possible cross-origin prior to CORS, then a preflight request will not be made as older servers should have handled any security around these requests themselves.

How to get the preflight request to succeed?

Assuming that the server responds to the OPTIONS request successfully, the website should not need to make any further changes as the further requests will be handled by the browser. So if you are using a publicly exposed API and your request is failing on the OPTIONS request, you will need to confirm that the API is accepting your domain, headers and method you submitted the request with. You can do this by checking the OPTIONS response meets the following criteria:
  • Access-Control-Allow-Headers header with comma-separated list of headers you made your request with
  • Access-Control-Allow-Origin header with * or domain matching that which you are making the request from
  • Access-Control-Allow-Methods header with comma-separated list of methods you can access the endpoint with
  • Status is 200

If you want to enable your API to handle preflight requests, then you will need to be able to accept and OPTIONS request and respond to the requester with the above headers/status. The actually implementation of this will be down to the technologies you have developed your APIs using but there will commonly be APIs available to enable CORS. Note: your API that is available due cross-domain will also need to have GET/PUT/POST etc, with these headers.

References

CORS Access Control

Monday 3 April 2017

React Native #8 - State

Previously, we discussed how we can make reusable components by passing data to a component using props. State can also be used to help us provide data to a component. However, the difference is that state is used to hold values that change, and when it changes it will trigger updates to the components that reference it. State should generally be initialised in the constructor, and set state should be used to update it.

As a simple example, consider a UI that has a text input for the users name and then a text component that greets them, it would appear as follows:

  // Import necessary components
  import React, { Component } from 'react';
  import { Text, View, TextInput, StyleSheet } from 'react-native';
  import { Constants } from 'expo';
  
  export default class App extends Component {
 
    // Initialise state to avoid state being undefined
    // state is just a javascript object with properties
    // want to keep track of the state of
    constructor(props) {
      super(props);
      this.state = { text: '' };
    }
    
    render() {
      return (
        <View style={styles.container}>
          // Render text input and when text changes
          // update state
          <TextInput
            placeholder='Name'
            style={styles.textInput}
            onChangeText={(text) => this.setState({text})}
            value={this.state.text}
          />
        
          // Render text when text changes for input
          // the hello message should update to match
          // the new state
          <Text style={styles.paragraph}>
            Hello {this.state.text}
          </Text>
        </View>
      );
    }
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
      paddingTop: Constants.statusBarHeight,
      backgroundColor: '#ecf0f1',
    },
    paragraph: {
      margin: 24,
      fontSize: 18,
      fontWeight: 'bold',
      textAlign: 'center',
      color: '#34495e',
    },
    textInput: {
      height: 40,
      borderColor: 'gray', 
      borderWidth: 1
    }
  });

Friday 27 January 2017

React Native #7 - React vs React Native

When developing using React Native, we reference two separate libraries (both React and React Native).

React

React is more generic and also used on the web, essentially it ensures all the components work together. It is also responsible for understanding how components should behave. Any components you define will extend Component which is defined by React.

React Native

Provides the default core components that translate to native components. It can take a component and place it on the mobile phone's screen. It is basically the link between your Javascript and the mobile device.

Thursday 26 January 2017

ESLint

ESLint is a tool that analyses your JavaScript for potential errors and can be installed into many common text editors. This can help you pick up errors in your JavaScript without reloading your website or react native app, which can help you increase your productivity... YAY!

ESLint has a few setup layers - this is split into editor specific config and project specific config. This means we can configure which ESLint rules to validate our code using on a project by project basis. There are some preset configurations for this so that as a developer you don't need to add rules one by one.

Setting up ESLint in Sublime

  • Install eslint globally using npm:
    npm install -g eslint
  • Install Package Control
  • Do per project setup:
    • Install a set of rules that you want eslint to use to validate your code (there are other ones out there but here's an example)!
      npm install --save-dev eslint-config-rallycoding
    • Create a file in your project's root directory called .eslintrc
    • Tell eslint which rules to use by adding the following to the file:
        {
          "extends": "rallycoding"
        }
      
      Noting that it is important that these are double quoted.
  • Use Package Control to install linter and eslint to Sublime Text
    • Open up the command palette (Tools > Command Palette or command + shift + P)
    • Search for install and click on install package
    • Once this has loaded, search and click on SublimeLinter
    • Repeat for the package SublimeLinter-contrib-eslint
  • Exit out of Sublime Text, and reopen
  • Delete a semi-colon and save to confirm eslint is setup correctly. If this doesn't show errors, then move your cursor around a bit.

Tuesday 24 January 2017

React Native #6 - Navigator

In React Native, to add navigation to your app you can use the Navigator component. You can have as many navigators as you want in your app e.g. you may have one for your whole app or multiple if you are using tabs with different navigation stacks for each tab. This tutorial will explain how to add a single navigator to your react native app. Firstly, add the navigator as the base for your application so specify it in the index.ios.js and the index.android.js:

  // Import the Navigator from React Native 
  import React, { Component } from 'react';
  import {
    AppRegistry,
    Navigator
  } from 'react-native';

  import MainScene from './app/scenes/mainScene'
  import AddGoalScene from './app/scenes/addGoalScene'

  export default class Goalie extends Component {
    renderScene(route, navigator) {
      // Specify the properties to pass to the scene you will 
      // render. It is useful to pass the navigator around the
      // scenes so that you can push and pop to the navigation
      // stack. 
      var globalNavigatorProps = {
        navigator: navigator,
        goal: route.goal
      };

      // Based on the route passed to the navigator you can
      // determine which scene to render.
      switch(route.ident) {
        case "MainScene":
          return ( <MainScene {...globalNavigatorProps} />);
        case "AddGoalScene":
          return ( <AddGoalScene {...globalNavigatorProps} />);
        default:
          return ( <MainScene {...globalNavigatorProps}  />);
      }

    }

    render() {
      return (
        // Render your navigator
        // You must specify an initial route, which will become
        // your root view for the app. The initialRoute is just 
        // an object with an identifier you can use to define 
        // which screen should be displayed, and whatever other
        // info you would like to pass in.
        // You must also specify a renderScene function which
        // has the args route and navigator, this must return
        // what you would like to render on the navigation stack.
        <Navigator 
          initialRoute={{ident: "MainScene", goal: "MainScene" }} 
          renderScene={this.renderScene} />
      );
    }
  }

  AppRegistry.registerComponent('Goalie', () => Goalie);


The next step is to be able to add and remove from the navigation stack. For simplicity, I will demonstrate this using back and forward buttons:

  import React, { Component } from 'react';
  import {
    Button
  } from 'react-native';

  import ViewContainer from 
    '../components/viewContainer/ViewContainer'

  export default class MainScene extends Component {

    // Passes new route to the navigator, the scene
    // with the corresponding identifier will get rendered.
    navigateToAddGoal() {
      this.props.navigator.push({
        ident: "AddGoalScene",
        goal: this.props.goal
      });
    }

    // Removes the current scene from the navigator's
    // stack, and goes back to the previous scene. 
    goBack() {
      this.props.navigator.pop();
    }

    render() {
      return (
        <ViewContainer>
          <Button title= "Back" 
            onPress = { (event) => this.goBack() }/>
          <Button title= "Forward" 
            onPress = { (event) => this.navigateToAddGoal() }/>
        </ViewContainer>
      );
    }
  }

C# - Lambda Expressions

Lambda expressions are anonymous methods that have:
  • No access modifier
  • No name
  • No return statement

We use them for convenience so that we can write less code to achieve the same result. We also use them to make our code more readable. You can define a lambda expression as follows:

    // The generic types defined within the < and > represent the input
    // and output values, the first x types being the inputs
    // and the last type being the output 
    Func increment = number => number++;

    // You can call a lambda expression like this: 
    int incrementedNumber = increment(1);

    // A lambda expression with no arguments is defined like this: 
    Func greeting = () => "Hello world!";

    // A lambda expression with multiple arguments is defined like this: 
    Func add = (x, y) => x + y;

    // A lambda expression can also access variables in scope: 
    var name = "Chelsea";
    Func greetPerson = () => "Hello " + name;

    // This would print out "Hello Chelsea":   
    Console.WriteLine(greetPerson());

    // This would print out "Hello Tessa":   
    name = "Tessa";
    Console.WriteLine(greetPerson());



References

C# Lambda Expressions on YouTube https://youtu.be/SLPJ2GqF2Ts?t=5m14s

Monday 16 January 2017

React Native #5 - Installing/Uninstalling Modules using npm

One awesome thing about React Native is that you can use the npm to install packages which allow you to reuse JavaScript code that someone else has written(see here for list of packages)! This post will take you through how to install/uninstall packages.

Installing Packages

First, you will need to find a package you would like to install on the npm website. Once you find a package, go to your react native project's folder in the terminal and type:
npm install react-native-checkbox-field --save
--save means that the module you are installing will be automatically added to your package.json's dependencies. If you don't want your package.json to update, leave off the --save. After completing the install and updating your package.json, you can then use your new package as described on the packages page on the npm website, e.g:
import { CheckboxField, Checkbox} from 'react-native-checkbox-field';

Uninstalling Packages

Uninstalling packages is similar to installing packages. Go to your react native project's folder in the terminal and type:
npm uninstall react-native-checkbox-field --save
--save means that the module you are uninstalling will be automatically removed from your package.json's dependencies. If you don't want your package.json to update, leave off the --save. After completing the uninstall and updating your package.json, you will no longer have access to the package you have uninstalled so you should remove all references to it.

Friday 13 January 2017

React Native #4 - Props

Props allow you to make a component with that is reused throughout your app with slightly different properties. This can be referred to from your custom component's render function:

  import React, { Component } from 'react';
  import { Text } from 'react-native';

  class MessageView extends Component {
    render() {
      return (
        {this.props.message}
      );
    }
  }


Note: {this.props.message} is surrounded by braces to embed it into JSX.
You could then utilise your reusable component by importing and adding the following to another component:
<MessageView message="Hello World! />

Thursday 12 January 2017

React Native #3 - Flexbox Basics

Laying out components in React Native is done using flexbox, the key difference though is that style names are written camelcase e.g. background-color would be backgroundColor when defining it as part of a React Native Stylesheet. Today, I'll take you through the key ways you can layout your components using flexbox:

Parent Properties

display: flex;

In web dev, if you want to layout your page using flexbox you will need to specify "display: flex;" in your style for that HTML element. However, in react native this is unnecessary.

flexDirection

  • row (default): layout child components left to right
  • row-reverse: layout child components right to left
  • column: layout child components top to bottom
  • column-reverse: layout child components bottom to top


flexWrap

  • nowrap (default): components try to fit on one line
  • wrap: components can wrap onto new line (left to right)
  • wrap-reverse: components can wrap onto new line (right to left)


flexFlow

Shorthand for flexDirection and flexWrap e.g. column wrap

justifyContent

Distributes space left over once all the child items have been rendered.
  • flex-start: components are rendered at the start of the parent
  • flex-end: components are rendered at the end of the parent
  • center: components are rendered at the center of the parent
  • space-between: components are rendered equidistant apart, with a component aligned with both the start and end of the parent component
  • space-around: components are rendered equidistant apart, with a space at before the first and last component


alignItems

How components are aligned vertically for row layout or horizontally for column layout:
  • flex-start: aligned with the top of the parent layout for row, and with the left of the parent for column
  • flex-end: aligned with the bottom of the parent layout for row, and with the right of the parent for column
  • center: centered within the parent element
  • stretch: components stretch to fill the parent element (respects min/max width/height)
  • baseline: components are aligned along their baselines


alignContent

Similar to justifyContent but vertically for row and horizontally for column. It has the same potential values as justifyContent.

Child Properties

order

Takes an integer value, and defines the order components appear in the container. By default, this is based off the components order in the HTML.

flexGrow

A unitless number that dictates what amount of space an item should take up in a flex container as a proportion.

flexShrink

Similar to flexGrow except it specifies the items ability to shrink if necessary.

flex

Combination of flexGrow, flexShrink and flexBasis (in that order e.g. 0 1 auto). flexShrink and flexBasis are optional.

alignSelf

Allows the alignment specified by alignItems to be overridden for the specific child item. It shares the same potential values as alignContent.

References

Comprehensive Flexbox Tutorial

Wednesday 11 January 2017

React Native #2 - Creating Components

In this post, I will take you through how to create a component that is reusable in iOS/Android. First off, we will make a folder where we place all our reusable code, I have called it app and created it under the folder that was created when using the react-native command to initialise your app. There will be a few different things that go in this folder, so I have created another folder under app called components.

ViewContainer Component

I have chosen a simple component for the purpose of this tutorial, and it is a ViewContainer component. It is effectively a react native view, with specified styling applied and will form the base of all the screens you add to your app. Under app/components I add a new folder called viewContainer with 2 new files, the first file defines how the component is rendered and is called viewContainer.js:

  'use strict';

  import React, { Component } from 'react';
  import { View } from 'react-native';
  import styles from './style';

  class ViewContainer extends Component {
      render() {
          return (
              <View style={styles.viewContainer}>
                  {this.props.children}
              </View>
          );
      }
  }

  module.exports = ViewContainer;


The first file imports React and Component, React is a default export (see here for explanation) and so doesn't need to be in {}. We import Component so that we can define a new component and how it is rendered, this is defined in the render function. We also import View from react native, as this is the type of existing component we want to base our custom component off. And finally, we also import the style for the view container which is called style.js:

  'use strict';
  import { StyleSheet } from 'react-native';

  const styles = StyleSheet.create({
      viewContainer: {
          flex: 1,
          flexDirection: "column",
          justifyContent: "center",
          alignItems: "stretch"
      }
  });

  module.exports = styles;


The second file imports StyleSheet from react native, which can be used to define the style of the view component using flexbox CSS.

Using the ViewContainer Component

Your ViewContainer component can be used by either Android or iOS, so in either your index.ios.js or index.android.js or both, you can change the file to be:

  import React, { Component } from 'react';
  import {
    AppRegistry,
    StyleSheet,
    Text
  } from 'react-native';

  import ViewContainer from 
    './app/components/viewContainer/ViewContainer';

  export default class Goalie extends Component {
    render() {
      return (
        <ViewContainer>
          <Text style={styles.welcome}>
            Welcome to React Native!
          </Text>
          <Text style={styles.instructions}>
            To get started, edit index.ios.js
          </Text>
          <Text style={styles.instructions}>
            Press Cmd+R to reload,{'\n'}
            Cmd+D or shake for dev menu
          </Text>
        </ViewContainer>
      );
    }
  }

  const styles = StyleSheet.create({
    welcome: {
      fontSize: 20,
      textAlign: 'center',
      margin: 10
    },
    instructions: {
      textAlign: 'center',
      color: '#333333',
      marginBottom: 5
    },
  });

  AppRegistry.registerComponent('Goalie', () => Goalie);

Monday 9 January 2017

React Native #1 - Getting Started!

Hi everyone, React Native is a cool framework I've been learning about lately that lets you build mobile apps using Javascript. So over the next few weeks I will document my efforts with developing apps in React Native!

Getting Started

Just follow the React Native Getting Started guide to download everything you require. Note: iOS apps can only be developed on a Mac. I will be developing an app for both Android and iOS over this series so will be using a Mac. If you get errors, you may need to update node/npm if you have previously installed these.

Initialising the App

  1. In your terminal, change to your development directory or where you want your react native project to be saved.
  2. Enter the command
    react-native init [project_name]
    This will setup your React Native project
  3. Enter the command
    cd [project_name]
  4. Enter the command
    react-native run-ios
    from inside your React Native project directory to see the base iOS output
  5. To see the base Android output:
    1. Open the android folder in Android studio
    2. Go to Tools > Android > AVD Manager and setup a device, this will handle installing anything you need for the emulator to run
    3. Run the virtual device you created
    4. Enter the command
      react-native run-android
      from inside your React Native project directory to see the base Android output


Editing the view

You can edit the view displayed in the index.android.js and index.ios.js files in your preferred text editor.

Swift - Adding a Leaderboard to an App with GameKit

GameKit makes it really easy to add global scoreboards to an app, where you can compare yourself to Game Center friends or everyone who has played on the all time scoreboard. This article will take you through how to add it to your apps.

Initial Setup

First, go to iTunes Connect and select your app, and then click features. It should look something like this:



Then click on the plus next to leaderboards and select "Single Leaderboard". You should now be at a page that looks like this:



Fill out the fields, the Leaderboard Id will be how you reference it in the code. Ensure you also add a language, the name here will be the name that appears to users viewing your scoreboard:



Once you are done click save, and ensure that Game Center is enabled for your app against the build you are setting up. Then you will need to also enable it via Xcode. Open Xcode and ensure that GameKit is added as a Linked Framework/Library:



Finally, check the capabilities to ensure Game Center is successfully enabled:



Coding a Leaderboard

First, ensure the user is logged in when they first open the application by authenticating the player in the viewDidLoad function on one of the initial ViewController's presented by the application. Ensure the state of whether game center is enabled or not is saved, as this will allow you whether to show the option to view leaderboard after a user has played your game. For convenience and code simplicity, gameCenterEnabled is a global variable in this example.

  import UIKit
  import GameKit

  class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        score = 1
        // Do any additional setup after loading the view,
        // typically from a nib.
        authenticateLocalPlayer()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func authenticateLocalPlayer() {
        let localPlayer = GKLocalPlayer.localPlayer()
    
        localPlayer.authenticateHandler = {(ViewController, error) 
          -> Void in
            if((ViewController) != nil) {
                // 1 Show login if player is not logged in
                self.present(ViewController!, animated: true, 
                             completion: nil)
            } else if (localPlayer.isAuthenticated) {
                // 2 Player is already authenticated & logged in
                gameCenterEnabled = true
            } else {
                // 3 Game center is not enabled on the users device
                gameCenterEnabled = false
            }
    
        }
    }
  }



Next, you will want a view with a button to show the leaderboard , the view controller for this view should implement GKGameCenterControllerDelegate and handle dismissal and opening of the leaderboard. In this example saving of the score happens here as this view is displayed upon game completion. However, saving of the score can happen anywhere in your application.

  import UIKit
  import GameKit

  class ResultViewController: UIViewController, 
                              GKGameCenterControllerDelegate {
    @available(iOS 6.0, *)
    public func gameCenterViewControllerDidFinish(_ 
      gameCenterViewController: GKGameCenterViewController) {
        gameCenterViewController.dismiss(animated: false, 
                                         completion: nil)
    }
  
    override func viewDidLoad() {
        super.viewDidLoad()
        saveScore()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    // save score to leaderboard with matching id 
    func saveScore() {
        if (gameCenterEnabled) {
            let leaderboardID = "com.tripwire.memorymasterminds"
            let scoreToRecord = GKScore(leaderboardIdentifier: 
                                        leaderboardID)
            scoreToRecord.value = Int64(score)
            
            GKScore.report([scoreToRecord], 
                           withCompletionHandler: nil)
        }
    }
    
    // display leaderboard with matching id 
    @IBAction func showLeaderboardClicked(sender: AnyObject) {
        let gcVC = GKGameCenterViewController()
        gcVC.gameCenterDelegate = self
        gcVC.viewState = GKGameCenterViewControllerState
                             .leaderboards
        gcVC.leaderboardIdentifier = 
          "com.tripwire.memorymasterminds"
        self.present(gcVC, animated: false, completion: nil)
    }
    
  }