diff --git a/AideDeJeu/AideDeJeu.iOS/AideDeJeu.iOS.csproj b/AideDeJeu/AideDeJeu.iOS/AideDeJeu.iOS.csproj
index d47ba378..a1dcfc0a 100644
--- a/AideDeJeu/AideDeJeu.iOS/AideDeJeu.iOS.csproj
+++ b/AideDeJeu/AideDeJeu.iOS/AideDeJeu.iOS.csproj
@@ -151,23 +151,57 @@
     
   
   
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
+    
+      false
+    
   
   
     
diff --git a/AideDeJeu/AideDeJeu/Services/ItemDatabaseHelper.cs b/AideDeJeu/AideDeJeu/Services/ItemDatabaseHelper.cs
index 2e3f9eb9..16081fb1 100644
--- a/AideDeJeu/AideDeJeu/Services/ItemDatabaseHelper.cs
+++ b/AideDeJeu/AideDeJeu/Services/ItemDatabaseHelper.cs
@@ -1,4 +1,5 @@
-using AideDeJeuLib.Spells;
+using AideDeJeuLib.Monsters;
+using AideDeJeuLib.Spells;
 using Microsoft.EntityFrameworkCore;
 using System;
 using System.Collections.Generic;
@@ -42,5 +43,30 @@ namespace AideDeJeu.Services
                 await context.SaveChangesAsync();
             }
         }
+
+        public async Task> GetMonstersAsync()
+        {
+            using (var context = CreateContext())
+            {
+                //We use OrderByDescending because Posts are generally displayed from most recent to oldest
+                return await context.Monsters
+                                    .AsNoTracking()
+                                    .OrderByDescending(monster => monster.Id)
+                                    .ToListAsync();
+            }
+        }
+
+        public async Task AddOrUpdateMonstersAsync(IEnumerable monsters)
+        {
+            using (var context = CreateContext())
+            {
+                // add posts that do not exist in the database
+                var newMonsters = monsters.Where(
+                    monster => context.Monsters.Any(dbMonster => dbMonster.Id == monster.Id) == false
+                );
+                await context.Monsters.AddRangeAsync(newMonsters);
+                await context.SaveChangesAsync();
+            }
+        }
     }
 }
diff --git a/AideDeJeu/AideDeJeu/ViewModels/AboutViewModel.cs b/AideDeJeu/AideDeJeu/ViewModels/AboutViewModel.cs
index ece38a10..1a712382 100644
--- a/AideDeJeu/AideDeJeu/ViewModels/AboutViewModel.cs
+++ b/AideDeJeu/AideDeJeu/ViewModels/AboutViewModel.cs
@@ -1,5 +1,10 @@
-using AideDeJeu.Tools;
+using AideDeJeu.Services;
+using AideDeJeu.Tools;
+using AideDeJeuLib.Monsters;
+using AideDeJeuLib.Spells;
 using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
 using System.Windows.Input;
 
 using Xamarin.Forms;
@@ -13,9 +18,11 @@ namespace AideDeJeu.ViewModels
             Title = "À propos de ...";
 
             OpenWebCommand = new Command(() => Device.OpenUri(new Uri("https://nioux.github.io/AideDeJeu/")));
+            UpdateDataCommand = new Command(async() => await ExecuteUpdateDataCommandAsync());
         }
 
         public ICommand OpenWebCommand { get; }
+        public ICommand UpdateDataCommand { get; }
 
         public string Version {
             get
@@ -23,5 +30,40 @@ namespace AideDeJeu.ViewModels
                 return DependencyService.Get().GetVersion();
             }
         }
+
+        private int countUpdateData = 0;
+        private async Task ExecuteUpdateDataCommandAsync()
+        {
+            if (countUpdateData++ != 5) return;
+
+            IsBusy = true;
+            var helper = new ItemDatabaseHelper();
+
+            using (var spellsScrappers = new SpellsScrappers())
+            {
+                var partialSpells = await spellsScrappers.GetSpells();
+                var spells = new List();
+                foreach (var partialSpell in partialSpells)
+                {
+                    var spell = await spellsScrappers.GetSpell(partialSpell.Id);
+                    spells.Add(spell);
+                }
+                await helper.AddOrUpdateSpellsAsync(spells);
+            }
+
+            using (var monstersScrappers = new MonstersScrappers())
+            {
+                var partialMonsters = await monstersScrappers.GetMonsters();
+                var monsters = new List();
+                foreach (var partialMonster in partialMonsters)
+                {
+                    var monster = await monstersScrappers.GetMonster(partialMonster.Id);
+                    monsters.Add(monster);
+                }
+                await helper.AddOrUpdateMonstersAsync(monsters);
+            }
+
+            IsBusy = false;
+        }
     }
 }
\ No newline at end of file
diff --git a/AideDeJeu/AideDeJeu/ViewModels/BaseViewModel.cs b/AideDeJeu/AideDeJeu/ViewModels/BaseViewModel.cs
index f77b8e12..26d76dcb 100644
--- a/AideDeJeu/AideDeJeu/ViewModels/BaseViewModel.cs
+++ b/AideDeJeu/AideDeJeu/ViewModels/BaseViewModel.cs
@@ -12,8 +12,8 @@ namespace AideDeJeu.ViewModels
 {
     public class BaseViewModel : INotifyPropertyChanged
     {
-        public SpellsScrappers SpellsScrappers => DependencyService.Get() ?? new SpellsScrappers();
-        public MonstersScrappers MonsterScrappers => DependencyService.Get() ?? new MonstersScrappers();
+        //public SpellsScrappers SpellsScrappers => DependencyService.Get() ?? new SpellsScrappers();
+        //public MonstersScrappers MonstersScrappers => DependencyService.Get() ?? new MonstersScrappers();
 
         bool isBusy = false;
         public bool IsBusy
diff --git a/AideDeJeu/AideDeJeu/ViewModels/SpellDetailViewModel.cs b/AideDeJeu/AideDeJeu/ViewModels/SpellDetailViewModel.cs
index 1426c37b..1d947c24 100644
--- a/AideDeJeu/AideDeJeu/ViewModels/SpellDetailViewModel.cs
+++ b/AideDeJeu/AideDeJeu/ViewModels/SpellDetailViewModel.cs
@@ -120,8 +120,11 @@ namespace AideDeJeu.ViewModels
 
             try
             {
-                var item = await SpellsScrappers.GetSpell(Item.Id);
-                Item = item;
+                using (var spellsScrappers = new SpellsScrappers())
+                {
+                    var item = await spellsScrappers.GetSpell(Item.Id);
+                    Item = item;
+                }
             }
             catch (Exception ex)
             {
diff --git a/AideDeJeu/AideDeJeu/ViewModels/SpellsViewModel.cs b/AideDeJeu/AideDeJeu/ViewModels/SpellsViewModel.cs
index 834e0539..177a2165 100644
--- a/AideDeJeu/AideDeJeu/ViewModels/SpellsViewModel.cs
+++ b/AideDeJeu/AideDeJeu/ViewModels/SpellsViewModel.cs
@@ -170,7 +170,11 @@ namespace AideDeJeu.ViewModels
             try
             {
                 AllItems.Clear();
-                var items = await SpellsScrappers.GetSpells(classe: Classes[Classe].Key, niveauMin: Niveaux[NiveauMin].Key, niveauMax: Niveaux[NiveauMax].Key, ecole: Ecoles[Ecole].Key, rituel: Rituels[Rituel].Key, source: Sources[Source].Key);
+                IEnumerable items = null;
+                using (var spellsScrappers = new SpellsScrappers())
+                {
+                    items = await spellsScrappers.GetSpells(classe: Classes[Classe].Key, niveauMin: Niveaux[NiveauMin].Key, niveauMax: Niveaux[NiveauMax].Key, ecole: Ecoles[Ecole].Key, rituel: Rituels[Rituel].Key, source: Sources[Source].Key);
+                }
 
                 //try
                 //{
diff --git a/AideDeJeu/AideDeJeu/Views/AboutPage.xaml b/AideDeJeu/AideDeJeu/Views/AboutPage.xaml
index 0293f70b..47c268e1 100644
--- a/AideDeJeu/AideDeJeu/Views/AboutPage.xaml
+++ b/AideDeJeu/AideDeJeu/Views/AboutPage.xaml
@@ -3,7 +3,8 @@
              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
              x:Class="AideDeJeu.Views.AboutPage"
              xmlns:vm="clr-namespace:AideDeJeu.ViewModels;"
-             Title="{Binding Title}">
+             Title="{Binding Title}" 
+             IsBusy="{Binding IsBusy}">
     
         
     
@@ -21,7 +22,11 @@
         
         
             
-                
+                
                 
                 
                 
diff --git a/AideDeJeu/AideDeJeuLib/Monsters/MonstersScrappers.cs b/AideDeJeu/AideDeJeuLib/Monsters/MonstersScrappers.cs
index c2204e41..4359a921 100644
--- a/AideDeJeu/AideDeJeuLib/Monsters/MonstersScrappers.cs
+++ b/AideDeJeu/AideDeJeuLib/Monsters/MonstersScrappers.cs
@@ -9,28 +9,73 @@ using System.Threading.Tasks;
 
 namespace AideDeJeuLib.Monsters
 {
-    public class MonstersScrappers
+    public class MonstersScrappers : IDisposable
     {
+        private HttpClient _Client = null;
         public HttpClient GetHttpClient()
         {
-            var client = new HttpClient();
-            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
-            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
-            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
-            client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr"));
-            client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr-FR"));
-            return client;
+            if (_Client == null)
+            {
+                var client = new HttpClient();
+                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
+                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
+                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
+                client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr"));
+                client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr-FR"));
+                _Client = client;
+            }
+            return _Client;
         }
 
+        #region IDisposable Support
+        private bool disposedValue = false; // Pour détecter les appels redondants
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
+                    // TODO: supprimer l'état managé (objets managés).
+                    if (_Client != null)
+                    {
+                        _Client.Dispose();
+                        _Client = null;
+                    }
+                }
+
+                // TODO: libérer les ressources non managées (objets non managés) et remplacer un finaliseur ci-dessous.
+                // TODO: définir les champs de grande taille avec la valeur Null.
+
+                disposedValue = true;
+            }
+        }
+
+        // TODO: remplacer un finaliseur seulement si la fonction Dispose(bool disposing) ci-dessus a du code pour libérer les ressources non managées.
+        // ~SpellsScrappers() {
+        //   // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
+        //   Dispose(false);
+        // }
+
+        // Ce code est ajouté pour implémenter correctement le modèle supprimable.
+        public void Dispose()
+        {
+            // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
+            Dispose(true);
+            // TODO: supprimer les marques de commentaire pour la ligne suivante si le finaliseur est remplacé ci-dessus.
+            // GC.SuppressFinalize(this);
+        }
+        #endregion
+
+
         public async Task> GetMonsters(string category = "", string type = "", string minPower = "", string maxPower = "", string size = "", string legendary = "", string source = "srd")
         {
             string html = null;
-            using (var client = GetHttpClient())
-            {
-                // https://www.aidedd.org/regles/monstres/?min=.25&max=20&c=M&sz=TP&lg=si&t=Humano%C3%AFde&s=srd
+            var client = GetHttpClient();
+            // https://www.aidedd.org/regles/monstres/?min=.25&max=20&c=M&sz=TP&lg=si&t=Humano%C3%AFde&s=srd
+
+            html = await client.GetStringAsync(string.Format($"https://www.aidedd.org/regles/monstres/?c={category}&t={type}&min={minPower}&max={maxPower}&sz={size}&lg={legendary}&s={source}", category, type, minPower, maxPower, size, legendary, source));
 
-                html = await client.GetStringAsync(string.Format($"https://www.aidedd.org/regles/monstres/?c={category}&t={type}&min={minPower}&max={maxPower}&sz={size}&lg={legendary}&s={source}", category, type, minPower, maxPower, size, legendary, source));
-            }
             var pack = new HtmlDocument();
             pack.LoadHtml(html);
             var trs = pack.GetElementbyId("liste").Element("table").Elements("tr").ToList();
@@ -72,12 +117,11 @@ namespace AideDeJeuLib.Monsters
         public async Task GetMonster(string id)
         {
             string html = null;
-            using (var client = GetHttpClient())
-            {
-                // https://www.aidedd.org/dnd/monstres.php?vf=aarakocra
+            var client = GetHttpClient();
+            // https://www.aidedd.org/dnd/monstres.php?vf=aarakocra
+
+            html = await client.GetStringAsync(string.Format($"https://www.aidedd.org/dnd/monstres.php?vf={id}", id));
 
-                html = await client.GetStringAsync(string.Format($"https://www.aidedd.org/dnd/monstres.php?vf={id}", id));
-            }
             var pack = new HtmlDocument();
             pack.LoadHtml(html);
             var divBloc = pack.DocumentNode.SelectNodes("//div[contains(@class,'bloc')]").FirstOrDefault();
diff --git a/AideDeJeu/AideDeJeuLib/Spells/SpellsScrappers.cs b/AideDeJeu/AideDeJeuLib/Spells/SpellsScrappers.cs
index 5e1d6050..52cb0bb1 100644
--- a/AideDeJeu/AideDeJeuLib/Spells/SpellsScrappers.cs
+++ b/AideDeJeu/AideDeJeuLib/Spells/SpellsScrappers.cs
@@ -8,29 +8,73 @@ using System.Threading.Tasks;
 
 namespace AideDeJeuLib.Spells
 {
-    public class SpellsScrappers
+    public class SpellsScrappers : IDisposable
     {
+        private HttpClient _Client = null;
         public HttpClient GetHttpClient()
         {
-            var client = new HttpClient();
-            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
-            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
-            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
-            client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr"));
-            client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr-FR"));
-            return client;
+            if (_Client == null)
+            {
+                var client = new HttpClient();
+                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
+                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
+                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
+                client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr"));
+                client.DefaultRequestHeaders.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("fr-FR"));
+                _Client = client;
+            }
+            return _Client;
         }
 
+        #region IDisposable Support
+        private bool disposedValue = false; // Pour détecter les appels redondants
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
+                    // TODO: supprimer l'état managé (objets managés).
+                    if (_Client != null)
+                    {
+                        _Client.Dispose();
+                        _Client = null;
+                    }
+                }
+
+                // TODO: libérer les ressources non managées (objets non managés) et remplacer un finaliseur ci-dessous.
+                // TODO: définir les champs de grande taille avec la valeur Null.
+
+                disposedValue = true;
+            }
+        }
+
+        // TODO: remplacer un finaliseur seulement si la fonction Dispose(bool disposing) ci-dessus a du code pour libérer les ressources non managées.
+        // ~SpellsScrappers() {
+        //   // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
+        //   Dispose(false);
+        // }
+
+        // Ce code est ajouté pour implémenter correctement le modèle supprimable.
+        public void Dispose()
+        {
+            // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
+            Dispose(true);
+            // TODO: supprimer les marques de commentaire pour la ligne suivante si le finaliseur est remplacé ci-dessus.
+            // GC.SuppressFinalize(this);
+        }
+        #endregion
+
         public async Task> GetSpells(string classe = "", string niveauMin = "", string niveauMax = "", string ecole = "", string rituel = "", string source = "srd")
         {
             string html = null;
-            using (var client = GetHttpClient())
-            {
-                // https://www.aidedd.org/regles/sorts/
+            var client = GetHttpClient();
+            // https://www.aidedd.org/regles/sorts/
+
+            var url = string.Format("https://www.aidedd.org/regles/sorts/?c={0}&min={1}&max={2}&e={3}&r={4}&s={5}", classe, niveauMin, niveauMax, ecole, rituel, source);
+            html = await client.GetStringAsync(url);
 
-                var url = string.Format("https://www.aidedd.org/regles/sorts/?c={0}&min={1}&max={2}&e={3}&r={4}&s={5}", classe, niveauMin, niveauMax, ecole, rituel, source);
-                html = await client.GetStringAsync(url);
-            }
             var pack = new HtmlDocument();
             pack.LoadHtml(html);
             var tdssort = pack.GetElementbyId("liste").Element("table").Elements("tr").ToList();
@@ -71,13 +115,12 @@ namespace AideDeJeuLib.Spells
         public async Task GetSpell(string id)
         {
             string html = null;
-            using (var client = GetHttpClient())
-            {
-                // https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
-                // https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
+            var client = GetHttpClient();
+            // https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
+            // https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
+
+            html = await client.GetStringAsync(string.Format("https://www.aidedd.org/dnd/sorts.php?vf={0}", id));
 
-                html = await client.GetStringAsync(string.Format("https://www.aidedd.org/dnd/sorts.php?vf={0}", id));
-            }
             var pack = new HtmlDocument();
             pack.LoadHtml(html);
             var divSpell = pack.DocumentNode.SelectNodes("//div[contains(@class,'bloc')]").FirstOrDefault();
@@ -87,14 +130,13 @@ namespace AideDeJeuLib.Spells
         public async Task> GetSpellIds(string classe, string niveauMin = "Z", string niveauMax = "9")
         {
             string html = null;
-            using (var client = GetHttpClient())
-            {
-                // https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
-                // https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
-                // https://www.aidedd.org/regles/sorts/
+            var client = GetHttpClient();
+            // https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
+            // https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
+            // https://www.aidedd.org/regles/sorts/
+
+            html = await client.GetStringAsync(string.Format("https://www.aidedd.org/adj/livre-sorts/?c={0}&min={1}&max={2}", classe, niveauMin, niveauMax));
 
-                html = await client.GetStringAsync(string.Format("https://www.aidedd.org/adj/livre-sorts/?c={0}&min={1}&max={2}", classe, niveauMin, niveauMax));
-            }
             var pack = new HtmlDocument();
             pack.LoadHtml(html);
             return pack.DocumentNode.SelectNodes("//input[@name='select_sorts[]']").Select(node => node.GetAttributeValue("value", ""));
@@ -103,17 +145,16 @@ namespace AideDeJeuLib.Spells
         public async Task> GetSpells(IEnumerable spellIds)
         {
             string html = null;
-            using (var client = GetHttpClient())
+            var client = GetHttpClient();
+            var content = new MultipartFormDataContent();
+            content.Add(new StringContent("card"), "format");
+            foreach (var spellId in spellIds)
             {
-                var content = new MultipartFormDataContent();
-                content.Add(new StringContent("card"), "format");
-                foreach (var spellId in spellIds)
-                {
-                    content.Add(new StringContent(spellId), "select_sorts[]");
-                }
-                var response = await client.PostAsync("http://www.aidedd.org/dnd/sorts.php", content);
-                html = await response.Content.ReadAsStringAsync();
+                content.Add(new StringContent(spellId), "select_sorts[]");
             }
+            var response = await client.PostAsync("http://www.aidedd.org/dnd/sorts.php", content);
+            html = await response.Content.ReadAsStringAsync();
+
             var pack = new HtmlDocument();
             pack.LoadHtml(html);
             var newSpells = new List();