Skip navigation
All Places > AppStudio for ArcGIS > Blog > 2018 > June
2018

1. Introduction

 

This AppStudio blog describes how we can use the Networking component to detect for network connectivity and classify the type of network (LAN, WIFI, Mobile Data). This allows you to build apps that can react differently dependent on what type of network they're on, e.g. ask the user whether they want to download content whilst on an expensive mobile data network.

 

2. Minimal App - All Network Configurations

Let's start with a minimal app that shows all Network connections whether active or inactive:

 

import QtQuick 2.7
import QtQuick.Controls 2.1
import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Networking 1.0

App {
    width: 640 * AppFramework.displayScaleFactor
    height: 480 * AppFramework.displayScaleFactor

    Flickable {
        anchors.fill: parent
        contentWidth: textArea.width
        contentHeight: textArea.height
        TextArea {
            id: textArea
            text: JSON.stringify(Networking.configurations, undefined, 2)
        }
    }
}

 

On my Windows machine, I get:

 

{
  "0": {
    "objectName": "",
    "valid": true,
    "name": "vEthernet (Internal Ethernet Port Windows Phone Emulator Internal Switch) 2",
    "identifier": "312537767",
    "bearerType": 1,
    "bearerTypeFamily": 1,
    "bearerTypeName": "Ethernet",
    "configurationType": 0,
    "connectTimeout": 30000,
    "purpose": 0,
    "roamingAvailable": false,
    "state": 14
  },
  "1": {
    "objectName": "",
    "valid": true,
    "name": "vEthernet (VMware Virtual Ethernet Adapter for VMnet8 Virtual Switch)",
    "identifier": "287176532",
    "bearerType": 1,
    "bearerTypeFamily": 1,
    "bearerTypeName": "Ethernet",
    "configurationType": 0,
    "connectTimeout": 30000,
    "purpose": 0,
    "roamingAvailable": false,
    "state": 14
  },
  "2": {
    "objectName": "",
    "valid": true,
    "name": "vEthernet (Default Switch)",
    "identifier": "287176527",
    "bearerType": 1,
    "bearerTypeFamily": 1,
    "bearerTypeName": "Ethernet",
    "configurationType": 0,
    "connectTimeout": 30000,
    "purpose": 0,
    "roamingAvailable": false,
    "state": 14
  },
  "3": {
    "objectName": "",
    "valid": true,
    "name": "vEthernet (VMware Virtual Ethernet Adapter for VMnet1 Virtual Switch)",
    "identifier": "312537825",
    "bearerType": 1,
    "bearerTypeFamily": 1,
    "bearerTypeName": "Ethernet",
    "configurationType": 0,
    "connectTimeout": 30000,
    "purpose": 0,
    "roamingAvailable": false,
    "state": 14
  },
  "4": {
    "objectName": "",
    "valid": true,
    "name": "Bluetooth Network Connection",
    "identifier": "312537798",
    "bearerType": 1,
    "bearerTypeFamily": 1,
    "bearerTypeName": "Ethernet",
    "configurationType": 0,
    "connectTimeout": 30000,
    "purpose": 0,
    "roamingAvailable": false,
    "state": 2
  },
  "5": {
    "objectName": "",
    "valid": true,
    "name": "vEthernet (Intel(R) 82579LM Gigabit Network Connection Virtual Switch)",
    "identifier": "312537802",
    "bearerType": 1,
    "bearerTypeFamily": 1,
    "bearerTypeName": "Ethernet",
    "configurationType": 0,
    "connectTimeout": 30000,
    "purpose": 0,
    "roamingAvailable": false,
    "state": 14
  }
}

 

The things we observed about Networking.configurations are:

 

  1. it's an object, not an array,
  2. every connection is listed (both active and inactive)
  3. there are signals on Network.configurations so you can use it in property binding scenarios (i.e. the moment the network changes, e.g. device is put in airplane mode, your app automatically updates)

 

3. Active Network Configurations

 

In order to filter the list down quickly, we transform the object to an array, then filter the results using Array.prototype.filter:

 

import QtQuick 2.7
import QtQuick.Controls 2.1
import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Networking 1.0

App {
    width: 640 * AppFramework.displayScaleFactor
    height: 480 * AppFramework.displayScaleFactor

    Flickable {
        anchors.fill: parent
        contentWidth: textArea.width
        contentHeight: textArea.height
        TextArea {
            id: textArea
            text: JSON.stringify(
                toArray(Networking.configurations)
                    .filter(isConfigActive)
                    .map(summary),
            undefined, 2)
        }
    }

    function toArray(o) {
        return Object.keys(o).map(function (e) { return o[e]; } );
    }

    function isConfigActive(c) {
        return (c.state & NetworkConfiguration.StateActive) === NetworkConfiguration.StateActive;
    }

    function summary(c) {
        return {
            name: c.name,
            bearerType: c.bearerType
        };
    }
}

 

On my Windows machine, this reduces to an easier to read list:

 

[
  {
    "bearerType": 1,
    "name": "vEthernet (Internal Ethernet Port Windows Phone Emulator Internal Switch) 2"
  },
  {
    "bearerType": 1,
    "name": "vEthernet (VMware Virtual Ethernet Adapter for VMnet1 Virtual Switch)"
  },
  {
    "bearerType": 1,
    "name": "vEthernet (Default Switch)"
  },
  {
    "bearerType": 1,
    "name": "vEthernet (Intel(R) 82579LM Gigabit Network Connection Virtual Switch)"
  },
  {
    "bearerType": 1,
    "name": "vEthernet (VMware Virtual Ethernet Adapter for VMnet8 Virtual Switch)"
  }
]

 

On my Android device, when WIFI is enabled:

 

[
  {
    "bearerType": 2,
    "name": "WIFI"
  }
]

 

or, when Mobile Data is enabled:

 

[
  {
    "bearerType": 10,
    "name": "Mobile"
  }
]

 

On my iOS device, when WIFI is enabled:

 

[
  {
    "bearerType": 0,
    "name": "en0"
  },
  {
    "bearerType": 0,
    "name": "awdl0"
  },
  {
    "bearerType": 0,
    "name": "utun0"
  }
]

 

4. Determining if the Network is LAN, WIFI or MobileData

 

On Windows, Android and Linux the bearerType can be used to classify the network connection, e.g.

 

  • NetworkConfiguration.BearerEthernet
  • NetworkConfiguration.BearerWLAN
  • NetworkConfiguraiton.Bearer3G

 

Whilst on iOS and macOS, the bearerType may not be provided by the operating system resulting in NetworkConfiguration.BearerUnknown. To cover iOS and macOS, we note that the name of the configuration instead:

 

  • en0
  • awdl0
  • pdp_ip0

 

    function isConfigLAN(c) {
        if (c.bearerType === NetworkConfiguration.BearerEthernet) {
            return true;
        }

        if (Qt.platform.os === "osx") {
            return c.name === "en0";
        }

        return false;
    }
   
    function isConfigWIFI(c) {
        if (c.bearerType === NetworkConfiguration.BearerWLAN) {
            return true;
        }

        if (Qt.platform.os === "ios") {
            return c.name === "en0";
        }
       
        if (Qt.platform.os === "osx") {
            return c.name === "awdl0";
        }

        return false;
    }

    function isConfigMobileData(c) {
        switch (c.bearerType) {
        case NetworkConfiguration.Bearer2G:
        case NetworkConfiguration.BearerCDMA2000:
        case NetworkConfiguration.BearerWCDMA:
        case NetworkConfiguration.BearerHSPA:
        case NetworkConfiguration.BearerWiMAX:
        case NetworkConfiguration.BearerEVDO:
        case NetworkConfiguration.BearerLTE:
        case NetworkConfiguration.Bearer3G:
        case NetworkConfiguration.Bearer4G:
            return true;
        }

        if (Qt.platform.os === "ios") {
            return c.name === "pdp_ip0";
        }

        return false;
    }

    function isConfigActiveLAN(c) {
        return isConfigActive(c) && isConfigLAN(c);
    }

    function isConfigActiveWIFI(c) {
        return isConfigActive(c) && isConfigWIFI(c);
    }

    function isConfigActiveMobileData(c) {
        return isConfigActive(c) && isConfigMobileData(c);
    }

 

Now that we have these useful functions, we can quickly chain them together to determine whether we're on WIFI or MobileData. Because we convert the object to an array, we can make use of Array.prototype.some to quickly lookup a network configuration of a particular type:

 

    property var config: toArray(Networking.configurations)
    property bool isOnline: isLAN || isWIFI || isMobileData
    property bool isLAN: config.some(isConfigActiveLAN)
    property bool isWIFI: config.some(isConfigActiveWIFI)
    property bool isMobileData: config.some(isConfigActiveMobileData)
    property bool isMobileDataOnly: isMobileData && !isWIFI && !isLAN

 

 

5. Network Check Sample

 

The "Network Check" app is available for you to try which demonstrates all of the above points. You can find "Network Check" app in AppStudio.

 

  1. Launch AppStudio
  2. Select New App
  3. Click Search Icon
  4. Type: Network Check

 

Network Check

 

The "Network Check" source code is also avilable at arcgis-appstudio-samples GitHub.

AppStudio Player for ArcGIS allows you instantly run and test your AppStudio apps on a real device without build requirements. As of 3.0 release, we have identified two issues: 
  • Level 1 named users cannot sign into AppStudio Player 
  • Launching apps within AppStudio Player using Custom URL scheme on iOS devices is not working 
 
We believe these two issues are critical to the usage of Player and we are happy to inform you that an update is available to be downloaded on the platform of your choice.
  
The Player for your devices with the latest fixes (3.0.14) is now available at Apple App StoreGoogle Play Store, and Amazon Appstore. The desktop version (Windows, Mac, Linux) of AppStudio Player is also available and can be downloaded from http://doc.arcgis.com/en/appstudio/download/