# DeviceAtlas Device Detection API Upgrade # This document is intended for users of APIs prior to version 2.1. It has three main sections: 1. Why Upgrade? 2. Upgrading From 2.0.x to 2.1 3. Upgrading From 1.x to 2.x ## Why Upgrade? ## Version 2.1 of the API has higher detection speed, reduced memory and improved detection capabilities. It is a recommended upgrade for all users. The API is compatible with all existing DeviceAtlas data files. Version 2.1 adds support for additional improvements to the data file format. To enable these improvements please follow the below steps: 1. Login into your account at deviceatlas.com 2. Go to "Data File Options" under "MY ACCOUNT" page 3. Un-tick the "API 2.0 compatible JSON file" option 4. Save Options 5. Download the new data file 6. Use new data file with the API. Note: It is recommended to only use the updated data file with APIs of version 2.1 and above. ## Upgrading From 2.0.x To 2.1 ## The 2.1 API is a drop-in replacement for the 2.0.x APIs. It should not cause any compatibility issues except for two minor cases described below. To upgrade to version 2.1 replace all DeviceAtlas DLL files currently in use with the updated versions. ## API Behavior Changes ## API changes between 2.0.x and 2.1 APIs are as follows: ### Examples Of Change ### In 2.0.1 ```csharp Properties properties = deviceApi.GetProperties(userAgent); // result is 0 or 1 when used as String Object isMobile = properties["mobileDevice"].Value(); // result is 0 or 1 when used as String ``` In 2.1 ```csharp Properties properties = deviceApi.GetProperties(userAgent); // result is 0 or 1 when used as String Object isMobile = properties["mobileDevice"].Value(); // result is 'false' or 'true' when used as String ``` The **recommended** way to get a property value in both 2.0.x and 2.1: ```csharp Properties properties = deviceApi.GetProperties(userAgent); bool isMobile = properties["mobileDevice"].AsBoolean(); int yearReleased = properties["yearReleased"].AsInteger(); string model = properties["model"].AsString(); ``` ## Upgrading From 1.x To 2.x ## Version 2.x of the API introduces a new better interface and improved performance. The following sections detail upgrading from v1.x versions. Version 1.x of the API has been deprecated. There are three options: ### 1. Do Nothing ### The new data file delivered as part of the 2.x upgrade will work with API versions 1.5, 1.6 and 1.7. Please see section "Why upgrade?". ### 2. Adopt New API, Utilizing The Deprecated 1.x API Interface ### This option has the benefit of avoiding any interface changes, but does not deliver the benefits of the 2.x API. ### 3. Adopt New API, Utilizing New Interface ### This is the recommended approach, and it delivers improved accuracy of detection for third party browsers. It is an improved architecture and will form the basis of future API evolutions. ### 1.x API Interface ### The interface used in the DeviceAtlas Device Detection API versions prior to 2.x is marked as deprecated. It is highly recommended to upgrade your source code to work with the new interface instead. As it may be inconvenient for some current users to upgrade their source code to use the new interface, the old interface is supported by DeviceAtlas but limited to bug fixes. The new libraries include the old interface (marked as deprecated) as "mobi.mtld.da.Api". Existing source code will work without the need to be changed simply by replacing the old jar file with the three new jar files. However, new users should avoid using the 1.x interface and current users are encouraged to upgrade to the new interface. ### Upgrading To 2.x ### The DeviceAtlas Device Detection API version 2.x and higher is shipped with a different interface than previous versions. This section shows the steps to upgrade a system which is currently using a DeviceAtlas Device Detection API prior to version 2.x. 1. Replace the previous DeviceAtlas Device Detection API DLL file with the three DLL files shipped in this package. 2. Package name changes. The previous imports must be replaced with the ones shown below. ```csharp // this package contains common DeviceAtlas classes such as Properties // and Property which are required by the classes wrapping the properties using Mobi.Mtld.DA; using Mobi.Mtld.DA.Device; // if you want to handle DeviceAtlas exceptions, use this import. See the // API documentation to see the exceptions being thrown using Mobi.Mtld.DA.Exception; // the API class // import DeviceApi when outside web context using Mobi.Mtld.DA.Device.DeviceApi; // import DeviceApiWeb when inside web context using Mobi.Mtld.DA.Device.DeviceApiWeb; // if you want to change the default API configs import Config using Mobi.Mtld.DA.Device.Config; ``` 3. Creating an instance. Unlike the 1.x interface, which was a set of static methods, accessing the methods of the new interface requires an instance. ```csharp // in web context DeviceApiWeb deviceApi = new DeviceApiWeb(); ``` ```csharp // outside web context DeviceApi deviceApi = new DeviceApi(); ``` You can also change the default API configs: ```csharp // in a web context Config configWeb = new Config(); // in case there is another package has a class named "Config": // Mobi.Mtld.DA.Device.Config configWeb = new Mobi.Mtld.DA.Device.Config(); // configure the api with the "configWeb" object // find the available configs in the API documentations DeviceApiWeb deviceApi = new DeviceApiWeb(configWeb); ``` ```csharp // outside a web context Config config = new Config(); // configure the api with the "config" object // find the available configs in the API documentations DeviceApi deviceApi = new DeviceApi(config); ``` 4. Loading the data. In the 1.x interface it was necessary to load the data and get the tree (as a HashMap) from the loadTreeFromFile() or loadTreeFromstring() and manually pass it to all the other related methods, however this is not the case in the new interface. The data may be loaded into the API instance from a file, input stream or class path and no tree will be returned and the tree does not have to be passed to other methods. This interface keeps the tree encapsulated. ```csharp deviceApi.LoadDataFromFile("/path/to/datafile.json"); ``` 5. Getting properties. There is only one GetProperties() method for getting the properties. The GetPropertiesAsTyped(), and GetProperty() calls must be replaced with the code shown below: ```csharp // Previously Hashtable properties = Api.GetProperties(tree, userAgent); if (properties.ContainsKey("model")) { object value = properties["model"]; } ``` to: ```csharp // Now Properties properties = deviceApi.GetProperties(userAgent); if (properties.ContainsKey("model")) { object value = properties["model"].Value(); } ``` ```csharp // Previously Hashtable properties = Api.GetPropertiesAsTyped(tree, userAgent); if (properties.ContainsKey("isMobile")) { bool value = properties["isMobile"]; } ``` to: ```csharp // Now Properties properties = deviceApi.GetProperties(userAgent); if (properties.ContainsKey("isMobile")) { bool value = properties["isMobile"].AsBoolean(); } ``` ```csharp // Previously try { bool isMobile = Api.GetProperty(tree, userAgent, "isMobile"); if (isMobile) { } } catch (... ``` to: ```csharp // Now Properties properties = deviceApi.GetProperties(userAgent); if (properties.ContainsKey("isMobile")) { bool isMobile = properties["isMobile"].AsBoolean(); if (isMobile) { } } ``` or ```csharp // Now Properties properties = deviceApi.GetProperties(userAgent); if (properties.Contains("isMobile", true)) { } ``` ### API Instantiation ### The DotNet API before version 2.0 kept a static variable with the tree loaded inside the API but. Version 2.0 puts more control in your hands in terms of how the tree is loaded in memory. The caveat is that multiple calls to LoadDataFromFile() will reload the datafile and slow down the application. The solution is to only load the datafile once before you need it. #### DeviceApiWeb Instantiation In Application State #### It is highly recommended to create only one DeviceApiWeb instance inside the Application state and load the datafile only once, then use the instance as an object in the application and shared across the requests. ```csharp // for example put this in Global.asax.cs Application_Start() try { // create a DeviceApiWeb instance deviceApi = new DeviceApiWeb(); // load the device atlas JSON data file deviceApi.LoadDataFromFile("/path/to/datafile.json"); // store the DeviceApiWeb instance on the Application state Application.Lock(); Application["DeviceApiWeb"] = deviceApi; Application.UnLock(); } // catch datafile loading errors catch (Exception e) { // handle the exceptions related to loading the data file } ``` ```csharp // get the instance if a DeviceApiWeb instance exists in the Application state DeviceApiWeb deviceApi = (DeviceApiWeb)Application["DeviceApiWeb"]; ``` Note! as the datafile is only loaded once, replacing the datafile with a new one (e.g. new datafile downloaded from http://deviceatlas.com) will not take effect unless the new data file is reloaded into the API, this can be done easily as shown below: ```csharp // this lines can be put inside an admin page to run after datafile updates DeviceApiWeb deviceApi = (DeviceApiWeb)Application["DeviceApiWeb"]; if (deviceApi != null) { deviceApi.LoadDataFromFile("/path/to/datafile.json"); } ``` #### DeviceApi Instantiation In A Wrapper #### Create a wrapper to restrict the instantiation of DeviceApi to one object. The datafile is loaded into the API immediately after creating the instance. ```csharp public class DeviceApiWrapper { private static DeviceApi deviceApi = null; public static DeviceApi GetApi(string filePath) { if (deviceApi == null) { deviceApi = new DeviceApi(); deviceApi.LoadDataFromFile(filePath); } return deviceApi; } public static DeviceApi ReloadApi(string filePath) { deviceApi = new DeviceApi(); deviceApi.LoadDataFromFile(filePath); return deviceApi; } } ``` The DeviceApi instance can be accessed in the application sources as show below: ```csharp // if a DeviceApi instance already exists there wont be another // instantiation and datafile loading string dataFile = "/path/to/datafile.json"; DeviceApi deviceApi = DeviceApiWrapper.GetApi("/path/to/datafile.json"); // use the api . . . Properties properties = deviceApi.GetProperties(); ``` Note! this will not always be useful. For example this will not help a web application because each request will independently create a separated instance and load the datafile while we need a single shared instance across the threads. Note! as the datafile is only loaded only once when creating an instance, replacing the datafile with a new one (e.g. new datafile downloaded from http://deviceatlas.com) will not have effect on the instance. In a situation like this calling "DeviceApiWrapper.ReloadApi("/path/to/datafile.json");" will reload the datafile into the API. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _ Copyright (c) DeviceAtlas Limited 2021. All Rights Reserved. https://deviceatlas.com _ <!-- HTML+JS for document formatting when opened in browser --> <div class="btn-group" id="main-menu" style="float:right"><a class="btn dropdown-toggle" data-toggle="dropdown" href="#">Menu<span class="caret"></span></a><ul class="dropdown-menu"><li><a href="README.html">Main</a></li><li><a href="README.DeviceApi-Web.html">Device Detection for Web</a></li><li><a href="README.DeviceApi-Apps.html">Device Detection for Apps</a></li><li><a href="README.DeviceApi-Config.html">Device Detection API Config</a></li><li><a href="./DeviceApiDocs/classes.html">Device API Docs</a></li><li class="divider"></li><li><a href="README.CarrierApi.html">Carrier Identification API</a></li><li><a href="./CarrierApiDocs/classes.html">Carrier API Docs</a></li><li class="divider"></li><li><a href="README.ClientSide.html">Client-side Component</a></li><li><a href="README.ConnectivityAnalyser.html">Connectivity Analyser</a></li></ul></div>