SYNC FRAMEWORK AVEC SQLITE POUR APPLICATIONS WINDOWS STORE (WINRT) ET WINDOWS PHONE 8 INTRODUCTION Bonjour à tous; Aujourd hui je publie une nouvelle version de l adaptation de la Sync Framework Toolkit, que j ai réalisée il y a quelque temps, pour WinRT. Cette nouvelle preview permet notamment de synchroniser vos données sur les deux plateformes WinRT XAML et Windows Phone 8. Vous pouvez récupérer les sources sur Codeplex à l adresse http://syncwinrt.codeplex.com Une des principales modifications (hormis le fait d avoir écrit le provider pour WP8) est le changement de fournisseur de données pour SQLite. Jusqu à présent j utilisais l excellent wrapper SQLite-net. Pour cette nouvelle version j ai décidé de retirer ce toolkit. Il rentrait trop souvent en conflit avec les projets clients. Le premier réflexe que l on a lorsqu on crée un projet WinRT (ou WP8) avec SQLite, c est de rajouter cette librairie. Il était donc indispensable que de mon côté, je m en passe, pour éviter les conflits. Je suis donc passé sur un wrapper plus bas niveau, plus simple, sans outil ORM. J ai utilisé la bibliothèque sqlwinrt.codeplex.com Vous trouverez un détail d utilisation concernant cette librairie sur le blog Windows Phone : http://blogs.windows.com/windows_phone/b/wpdev/archive/2013/05/30/sqlite-winrt-wrapper-forwindows-phone.aspx
J ai dû tout de même la modifier pour qu elle prenne en compte les types de données nécessaires à la synchronisation. Dans le projet vous trouverez un exemple complet permettant de synchroniser une application Windows Store Apps et Windows Phone sur un Backend SQL SERVER exposé par IIS. PROJET COMPLET D EXEMPLE Dans la suite de l article, nous allons voir ensemble comment réaliser une application minimaliste pour synchroniser vos données. Cependant, pour un exemple plus complet, vous trouverez dans le zip Codeplex, une application complète pour Windows Phone 8 et pour WinRT, dont voici quelques copies d écrans : WINDOWS PHONE 8 WINDOWS STORE APPLICATION INSTALLATION Pour pouvoir créer une «application synchronisable», il va vous falloir préparer : 1. Un serveur de données exposant vos entités. a. Ce serveur attaquera une base de données SQL SERVER, elle-même correctement configurée pour supporter la synchronisation de ses tables. 2. Une application Windows Store Apps capable de récupérer ces données et les stocker en local avec SQLite 3. Une application Windows Phone 8 capable aussi de récupérer ces données et les stocker en local avec SQLite
SERVER Coté serveur, la première étape consiste à installer le Sync Framework 2.1. Ce Framework fait partie du.net mais doit être mis à jour vers la dernière version. Vous devez donc installer la version x86 ou x64 : http://www.microsoft.com/enus/download/details.aspx?id=23217 VISUAL STUDIO ET LE SYNC FRAMEWORK ATTENTION : Si vous travaillez en mode Debug ou Développement, vous travaillez surement sur une machine x64 avec Visual Studio qui lui marche en x86. Il faut donc installer les 2 versions du Sync Framework 2.1 Hors les 2 packages d installation refusent de se déployer cote à cote. La technique est donc d installer le SDK x64 puis les redistribuables x86: SDK x64 : http://www.microsoft.com/en-us/download/details.aspx?id=23217 Redistribuables x86 : http://www.microsoft.com/en-us/download/details.aspx?id=19502 (Installez les 3 msi) Une fois le Sync Framework 2.1 installé, il vous faut récupérer la toolkit sur http://syncwinrt.codeplex.com La DLL à utiliser coté serveur se trouve ici : \Sync Framework 4.0 Toolkit\Server\Release
Lors de la création de votre serveur vous aurez donc à référencer ces assemblys : 1. Les 3 premières sont les assemblys provenant du Sync Framework 2.1 a. Microsoft.Synchronization b. Microsoft.Synchronization.Data.Server c. Microsoft.Synchronization.Data.SqlServer 2. La dernière est l assembly de la toolkit, dont vous trouverez les sources dans le projet Codeplex a. Microsoft.Synchronization.Services Note: Je vous conseille de faire tourner votre application web sur un server IIS local. Les appels depuis l émulateur WP8 sont de ce fait beaucoup plus simples. Si toutefois vous n avez pas de serveur IIS installé sur votre machine de développement, vous avez deux solutions : 1. Vous installez IIS sur votre poste de développement, c est une bonne chose! 2. Vous suivez cette procédure pour vous connecter depuis votre émulateur Windows phone 8 sur votre IIS Express : How To Connect a local web service from Windows Phone 8 Note : Dans la suite de notre tutorial, j ai utilisé un serveur IIS local. La solution Windows Phone 8 fonctionne donc en utilisant l IP de la machine comme indiqué dans la ressource MSDN. WINDOWS STORE APPS Concernant la partie Windows Store Apps, la première chose à faire est d installer SQLite sur votre machine (enfin les redistribuables qui se déploieront sur la machine cible)
(Remarquez que vous aurez à faire la même chose pour Windows Phone 8) Une fois installé, vous pouvez télécharger la version codeplex de la toolkit, si ce n est pas déjà fait : http://syncwinrt.codeplex.com Les fichiers nécessaires se trouvent ici : \Sync Framework 4.0 Toolkit\Client\WinRT\Release\ Votre projet doit contenir les références suivantes : SQLite for Windows Runtime : Vous allez suremment utilisé SQLite-net
Microsoft.Synchronization.ClientServices.Win8 : Toolkit pour WinRT SQLiteWinRT : Wrapper C++/CX pour la toolkit WIDOWS PHONE 8 Comme précédemment, n oubliez pas d installer SQLite via Extensions and Updates Une fois installé, vous pouvez télécharger la version codeplex de la toolkit (encore une fois si vous ne l avez pas déjà fait) : http://syncwinrt.codeplex.com Les fichiers nécessaires pour Windows Phone 8 se trouvent ici : Votre projet doit contenir les références suivantes :
Microsoft.Synchronization.ClientServices.WP8 : Toolkit pour Windows Phone 9 SQLiteWinRTPhone : Wrapper C++/CX utilisé par la toolkit A partir de là, vous pouvez synchroniser vos données. Mais vous aurez aussi besoin, dans votre application, de manipuler ces données, de les requêter et de les mettre à jour, avant de lancer une synchronisation. Pour ce faire vous pouvez rajouter SQLite-net. Il vous faudra alors aussi rajouter une assembly C++ / CX, spécialement construite pour WP8, nécessaire à SQLite-net pour fonctionner. Je vous renvoie sur ce post détaillant comment installer SQLite-net pour WP8 : http://blogs.windows.com/windows_phone/b/wpdev/archive/2013/03/12/using-the-sqlite-databaseengine-with-windows-phone-8-apps.aspx J ai inclus dans le zip le projet sqlite-net-wp8-master que vous trouverez dans le répertoire dédié aux exemples. Au final, vous devriez avoir une référence en plus : TUTORIAL Il s agit ici de construire une application très simple capable de se connecter à un serveur de synchronisation distant et de lancer une réplication. Pour un exemple plus complet, je vous laisse regarder le code de l application Fabrikam complète fournie avec le code source. Pour ce tutorial, nous partons du prérequis que vous avez installé l ensemble des assemblys nécessaires, comme indiqué précédemment. SOLUTION DE DEPART
Ma solution de départ contient l ensemble des assemblys nécessaires ainsi que SQLite-net que j ai rajouté à mes projets clients via Nuget :
CONFIGURATION SERVER Vous trouverez dans le sample fournit un script SQL permettant de créer rapidement une base de données SQL SERVER. La base de données doit être configurée pour pouvoir fonctionner avec le Sync Framework: 1. Ajout de métadatas 2. Ajout de triggers 3. Ajout de tables Il est nécessaire d avoir un fichier descriptif des données que vous voulez synchroniser. Voici celui que nous allons utiliser : <?xml version="1.0" encoding="utf-8"?> <configuration> <configsections> <section name="syncconfiguration" type="microsoft.synchronization.clientservices.configuration.syncconfigurationsection, SyncSvcUtil, Version=1.0.0.0, Culture=neutral" allowdefinition="everywhere" allowexedefinition="machinetoapplication" restartonexternalchanges="true" /> </configsections> <SyncConfiguration> <SyncScopes> <SyncScope Name="DefaultScope" IsTemplateScope="true"> <SyncTables> <SyncTable Name="dbo.Customers" GlobalName="Customers" IncludeAllColumns="true" /> <SyncTable Name="dbo.ServiceTickets" GlobalName="ServiceTickets" IncludeAllColumns="true" /> </SyncTables> </SyncScope> </SyncScopes> <Databases> <TargetDatabase Name="FabrikamFIber" DbServer=".\SQL2012" DbName="FabrikamFIber" UseIntegratedAuth="true" /> </Databases> </SyncConfiguration> </configuration> La génération de code s effectue via l utilitaire en ligne de commande disponible ici : \Sync Framework 4.0 Toolkit\Tools
Dans mon cas la ligne de commande est la suivante : syncsvcutil.exe /mode:provision /scopeconfig:fabrikam.xml La base de données est configurée et on voit bien apparaitre un ensemble de métadonnées supplémentaires, de tables et de triggers :
Coté application web, il faut aussi générer du code, permettant de se connecter à la base : Syncsvcutil.exe /scopeconfig:fabrikam.xml /mode:codegen /target:server /directory:server Le code généré se trouve dans le répertoire /Server et il est à ajouter à votre solution : Il est tout de même nécessaire de modifier le fichier DefaultScopeSyncService.svc pour configurer la chaine de connexion, et le format de sérialisation de vos données (JSON, ATOM-XML) #region SyncService: Configuration and setup public class DefaultScopeSyncService : Microsoft.Synchronization.Services.SyncService<DefaultScopeOfflineEntities> { public static void InitializeService(Microsoft.Synchronization.Services.ISyncServiceConfiguration config) { // TODO: MUST set these values // config.serverconnectionstring = "connection string here"; // config.setenablescope("scope name goes here"); // // // TODO: Optional. // config.setdefaultsyncserializationformat(microsoft.synchronization.services.syncserializationf ormat.odatajson); // config.setconflictresolutionpolicy(microsoft.synchronization.services.conflictresolutionpolicy.serverwins); } } #endregion
Après ajout de la chaine de connexion dans le web.config; voici le fichier complété : public class DefaultScopeSyncService : Microsoft.Synchronization.Services.SyncService<DefaultScopeOfflineEntities> { public static void InitializeService(Microsoft.Synchronization.Services.ISyncServiceConfiguration config) { config.serverconnectionstring = ConfigurationManager.ConnectionStrings["Fabrikam"].ConnectionString; config.setenablescope("defaultscope"); config.setdefaultsyncserializationformat(syncserializationformat.odatajson); config.setconflictresolutionpolicy(conflictresolutionpolicy.serverwins); } } Naviguez sur l url pour voir apparaître cette page ODATA : A partir de là, votre serveur est configuré. APPLICATION WINRT Comme la partie serveur, vous allez devoir générer le code client permettant de faire les appels vers votre serveur de synchronisation. La ligne de commande est très semblable à celle du serveur. Seul le /target change: syncsvcutil.exe /mode:codegen /scopeconfig:fabrikam.xml /directory:client /target:sqliteclient
Le code généré se trouve dans le répertoire /Client et il est à ajouter à votre solution Windows Store Apps: Note : Vous allez surement vouloir utiliser SQLite-net. Il est donc nécessaire de modifier ces fichiers, notamment pour placer les attributs des clés primaires sur vos entités. Les entités se trouvent dans le fichier DefaultScopeEntities.cs A partir de là, synchroniser votre base est extrêmement simple : Dans la MainPage.xaml, ajoutez un bouton. Sur l évènement click ajouter le code suivant : Uri serviceuri = new Uri("http://localhost/Sample.WebServer/DefaultScopeSyncService.svc/"); DefaultScope.DefaultScopeOfflineContext ctx = new DefaultScopeOfflineContext("fabrikam.db", serviceuri); var stats = await ctx.synchronizeasync(); if (stats.error!= null) { Debug.WriteLine(stats.Error.Message); return; } Debug.WriteLine(stats.TotalDownloads);
Le résultat en image de notre test : Vous pouvez consulter la structure de votre base locale si nécessaire. Personnellement, j utilise SQLiteManager ou SQLiteMaestro Ma base de données locale (et générée via la première synchronisation) se trouve ici : AppData\Local\Packages\46f9d90d-893a-4319-8a18-a3c4a40513c7_frjbj8e8b44ec\LocalState Vous retrouvez la structure de votre base ainsi que les métadonnées supplémentaires et nécessaires à la synchronisation :
APPLICATION WINDOWS PHONE 8 Comme la partie Serveur ou WinRT, vous allez devoir générer le code nécessaire à l exécution de la synchronisation pour votre application Windows Phone 8 Vous pouvez utiliser l utilitaire en ligne de commande, mais vous pouvez aussi directement ajouter les fichiers précédemment générés, puisque ceux-ci sont identiques : Votre projet Windows Phone 8 prend alors la structure suivante :
Notez les deux fichiers ajoutés en tant que liens. VERIFIER LA CONNECTIVITE DE VOTRE EMULATEUR Avant de déployer, vous devez être sûr que votre émulateur Windows Phone (ou votre device) est capable d atteindre le serveur web de synchronisation. Pour vérifier, lancez l émulateur, et naviguez vers votre url (dans mon cas http://192.168.0.17/sample.webserver/defaultscopesyncservice.svc/$syncscopes) Note : Voici les étapes que je reproduis systématiquement sur mon émulateur Windows Phone 8 Lancer Internet Explorer Effectuer une recherche quelconque (Amazon par exemple) Tenter de rentrer en contact avec mon serveur Web de synchronisation A partir de là, il suffit d exécuter le même code que la version WinRT depuis votre application Windows Phone 8 :
SI vous avez des questions, n hésitez pas à m envoyer un mail, ou utilisez le site Codeplex, section Discussions ou Issue Tracker Bonne synchronisation!!