Accueil Nos publications Blog Windows Phone : Comment informer vos utilisateurs

Windows Phone : Comment informer vos utilisateurs


En tant que développeur d’application Windows Phone, la communication avec vos utilisateurs est primordiale. On pense souvent à laisser son mail, pour être contacté en cas de problème ou suggestion, mais contacter dans l’autre sens peut également s’avérer utile !

L’application me parle !

Scénario catastrophe, un bug imprévu s’invite dans votre app, boom, là comme ça ! Ca arrive, il suffit qu’une page html parsée change, ou encore qu’une API devienne obsolète.

Vous vous retrouvez alors dans l’impossibilité de prévenir vos utilisateurs de l’incident malheureux et de sa résolution prochaine. Pire encore, s’il vous faut publier une nouvelle version, vos utilisateurs devront attendre 1 semaine avant d’en bénéficier, certification oblige.

Bref, pouvoir communiquer des messages à vos utilisateurs peut s’avérer utile de bien des manières, que ce soit pour une maintenance, une notification de mise à jour, de la publicité… Voyons voir comment implémenter tout ça simplement !

Wallbase : notification de mise à jour Wallbase : notification de mise à jour[/caption]

Quoties : demande de suggestions Quoties : demande de suggestions[/caption]

Chargeons le cahier

L’idée va être de pousser un message serveur dépendant de la culture de l’application, et de la version de l’application. Ainsi, on pourra pousser un message traduit dans une langue donnée et pour une version en particulier (utile pour prévenir d’une mise à jour !). Allez, soyons fous, on va même permettre d’afficher le message à partir d’une date donnée.

Si on résume le cahier des charges :

  • Traduit dans la langue de l’utilisateur
  • Dépendant d’une version de l’app
  • Affiché qu’1 seule fois pour éviter le spam
  • Affiché à partir d’une date donnée

Des messages organisés

Il va falloir héberger nos messages sur un serveur. On va faire simple en déployant des fichiers textes dans un format spécifique :

Le chemin sera le suivant : https://monserver/Messages/<num_version>/message.<langue>.txt.

Ainsi, la langue est inclue dans le nom du fichier, et chaque sous-répertoire représente un numéro de version. On cherche d’abord dans le répertoire de la version, si on ne trouve rien, on remonte à la racine pour chercher un message global à toutes les versions.

Seul bémol : il faudra trouver un hébergement. Vous pouvez par exemple profiter de l’hébergement gratuit sur Azure Web Sites.

Codons !

Maintenant qu’on sait d’où télécharger nos messages, allons-y !


private const string MSG_VERSION_URL = "https://localhost:55538/Messages/{1}/message.{0}.txt";
private const string MSG_URL = "https://localhost:55538/Messages/message.{0}.txt";

private static readonly Guid _cacheInvalidator = Guid.NewGuid();
private bool _isVersionedMessageChecked = false;

private void LoadServerMessage()
{
    var client = new WebClient();
    client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Message_DownloadStringCompleted);

    Uri url;
    // 1er download : message versionné
    if (!_isVersionedMessageChecked)
    {
        url = new Uri(string.Format(MSG_VERSION_URL + "?" + _cacheInvalidator,
            Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName,
            PhoneHelper.GetAppAttribute("Version").ToString()), UriKind.Absolute);
    }
    else // 2ème download si 1er non trouvé : message indépendant de la version
    {
        url = new Uri(string.Format(MSG_URL + "?" + _cacheInvalidator,
            Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName), UriKind.Absolute);
    }

    client.DownloadStringAsync(url);
}

On tente un 1er appel sur le message spécifique à la version de l’app. S’il ne retourne rien, on charge le message générique, indépendant de la version.

A noter qu’on concatène un Guid à l’url afin d’invalider le cache et être sûr de télécharger le fichier à chaque lancement de l’application.

Voici à quoi ressemble le contenu d’un fichier de message :


2012-10-17
Nouvelle mise à jour disponible !

La première ligne contient la date à partir de laquelle le message est affiché.
Le reste correspond au message à afficher.


private const string CONFIG_LAST_MESSAGE_DATE = "last_message_date";

private void Message_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null && !string.IsNullOrEmpty(e.Result))
    {
        // Décomposition des différentes lignes
        var messageLines = e.Result.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
        if (messageLines.Length > 1)
        {
            var messageDateString = messageLines[0];
            DateTime messageDate = DateTime.MinValue;

            // Récupération de la date, on n'affiche le message que si la date est antérieure à maintenant
            if (DateTime.TryParse(messageDateString, CultureInfo.InvariantCulture, DateTimeStyles.None, out messageDate)
                && DateTime.Now > messageDate)
            {
                if (IsolatedStorageSettings.ApplicationSettings.Contains(CONFIG_LAST_MESSAGE_DATE))
                {
                    var lastMessageDate = (DateTime)IsolatedStorageSettings.ApplicationSettings[CONFIG_LAST_MESSAGE_DATE];
                    // Si le message n'est pas nouveau, on l'ignore
                    if (lastMessageDate == messageDate)
                        return;
                }

                var message = string.Join(" ", messageLines.Skip(1).ToArray());

                // Affichage du message
                Dispatcher.BeginInvoke(() => MessageBox.Show(message));

                // Archivage de la date pour ne pas réafficher le message
                IsolatedStorageSettings.ApplicationSettings[CONFIG_LAST_MESSAGE_DATE] = messageDate;
            }
        }

        return;
    }

    if (!_isVersionedMessageChecked)
    {
        _isVersionedMessageChecked = true;
        LoadServerMessage();
        return;
    }
}

A noter qu’on sauvegarde la date du dernier message traité, afin de ne pas le réafficher au prochain lancement.

Ce comportement est à adapter à vos besoins. Dans Quoties par exemple, le message serveur n’est pas affiché sous forme de popup mais dans un coin de l’app. Ce n’est pas intrusif, on l’affiche donc en permanence.

Conclusion

Communiquer vers les utilisateurs n’est pas toujours primordial mais peut vous sauver de certaines situations inconfortables et vous éviter quelques critiques négatives en cas de crise. L’idée est là, n’hésitez pas à adapter cette solution à vos besoins !

Télécharger le projet démo