Monday, 12 November 2018

Sharing JS Code Across BitBucket Repositories

Recently, I have been writing APIs in node.js with the express framework, a React website and a React Native app that have some shared code. These are spread across several repositories, so I needed a way to share code across the repositories. So I created a node package in another repository.

Then I needed to figure out how to access the repository and install my package via npm. Fortunately, this proved to be relatively easy… Go to your account's BitBucket Settings > App Passwords. From here, you can create an app password and grant read access to your repositories. Then all you need to do is go to your package.json and add to your dependencies e.g.

  {
    …
    dependencies: {
      …,
      "[PACKAGE_NAME]": "git+https://[BITBUCKET_USERNAME]:
               [APP_PASSWORD]@bitbucket.org/PROJECT_NAME/
               REPOSITORY_NAME.git#BRANCH_NAME"
    },
    …
  }


If you then execute the "npm install" command this should install the repo to your node_modules folder.

But what happens when you push changes to the common repository? How do I run the code with the latest commits? Simply add an additional line to your package.json scripts:

  {
    …
    scripts: {
      …,
      "clean-start": "rm -rf -- node_modules/[PACKAGE_NAME]; 
                      npm install; npm start;"
    },
    …
  }


Then when you want to run with the latest changes use
npm run clean-start
instead of
npm start

Friday, 2 November 2018

How to create a VERY basic (and useless) Node Package

This is just the absolute basics of a node package so that you can install it via npm, whether it be a private or publicly accessible repo. See my follow up post about how to install a package that's in a private bitbucket repo.

Firstly, setup a basic package.json as follows:

    {
        "name": "tripwiretech-common",
        "version": "1.0.0",
        "description": "Tripwiretech common code",
        "main": "index.js",
        "author": "Tripwiretech",
        "license": "ISC",
        "scripts": {
            "start": "node index.js"
        }
    }


The name is one of the key properties in the package.json as it will represent your node package name. Any repo with a package.json can be published to npm. It is also recommended that your repo contains a readme.md in the root of the repo, this will be the documentation displayed on the npm website, if you choose to publish it there.

Next you will need some content exported in your index.js that other code can import and use. For the purposes of this example, I've kept it quite simple:

    module.exports = {
        Countries: ["Australia", "New Zealand", "South Africa"],
        Sports: ["Rugby", "Cricket"]
    }


Then you can import it and use it in your code. If you're struggling with more complicated node packages, then I recommend taking a look at one of the many existing and much more practical open source node packages that already exist on npm.

Monday, 26 March 2018

Swift 4 - Adding Admob Interstitial Ads to your iOS App

  1. Sign up for or sign in to Admob
  2. Add an App in Admob
  3. Add an Ad unit in Admob - Choose Interstitial. You can set ad type, frequency capping and eCPM floor under advanced settings
  4. You should now have an Ad Unit ID and App Id which will be used in displaying interstitial ads to the user
  5. In your code, create a file InterstitialAd.swift, it should have the following code:
    
      let adController = InterstitialAd()
      import GoogleMobileAds
    
      class InterstitialAd : NSObject, GADInterstitialDelegate {
        var testAdId = "ca-app-pub-3940256099942544/4411468910"
        var adId = "[YOUR AD UNIT ID GOES HERE]"
        var interstitial : GADInterstitial!
        
        func createAndLoadInterstitial() {
            interstitial = GADInterstitial(adUnitID: testAdId)
            interstitial.delegate = self
            interstitial.load(GADRequest())
        }
        
        // Load new interstitial on close so that adController 
        // is ready for the next time showAd is called
        func interstitialDidDismissScreen(_ ad: GADInterstitial) {
            createAndLoadInterstitial()
        }
    
        func showAd(_ viewController: UIViewController) {
          if interstitial.isReady {
            interstitial.present(fromRootViewController: viewController)
          }
        }
      }
    
    
  6. Add the following to your AppDelegate.swift file, it will configure the app for Admob ads and load the first interstitial so that it is ready to be displayed when you try to display the interstitial:
    
      ...
      import GoogleMobileAds
    
      @UIApplicationMain
      class AppDelegate: UIResponder, UIApplicationDelegate {
    
        ...
        var appId = "[YOUR ADMOB APP ID GOES HERE]"
    
        func application(_ application: UIApplication, 
            didFinishLaunchingWithOptions launchOptions: 
            [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
          GADMobileAds.configure(withApplicationID: appId)
          adController.createAndLoadInterstitial()
    
          ...
        }
    
        ...
    
      }
    
    
  7. From the view controller where you want to show your interstitial ad, make the following call:
    
      adController.showAd(self)
    
    

Note:

For testing, you should use the testAdId as the adUnitID in InterstitialAd.swift, this is so that real ads are not displayed during testing. For release, switch to using adId.

... included for brevity in ApplicationDelegate.swift code above

Swift 4 - How to share messages and images

There are many benefits of enabling sharing within your application:
  • Free advertising for your app if users share from it on social media
  • Better user experience
  • Using recent iOS features to make the app feel more modern
The code for this is simple, when an event occurs that you would like to share on, you can call the following method:

  func share(_ message: String , shareImage: UIImage) {
    let share = [message, shareImage] as [Any]
    let activityViewController = UIActivityViewController(
      activityItems: share, applicationActivities: nil)
    activityViewController.popoverPresentationController?
      .sourceView = self.view
    self.present(activityViewController, animated: true, 
      completion: nil)
  }

Friday, 23 March 2018

Swift 4 - The app's Info.plist must contain an NSCameraUsageDescription key

As of iOS 10, some features require an entry in the Info.plist before access will be allowed. This is for privacy purposes.

You can read more about this setting on Apple's developer website.

To solve this issue add the following to your Info.plist:
 <key>NSCameraUsageDescription</key>
 <string>[why you need camera access]</string>

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);
    }
  }