# 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 2022. All Rights Reserved. https://deviceatlas.com _