2017-04-20 2 views
0

Je développe une application Web multi-plateforme basée sur cordova en utilisant sapui5 framework v1.44 et indexedDB pour stocker des données. L'application fonctionnait bien jusqu'à la fin ios update, 10.3.1, maintenant il se bloque en essayant d'écrire dans indexedDB. J'utilise la méthode put pour mettre à jour les données et j'ai fait une installation propre de l'application. Le cadre de code où je tente d'écrire à IndexedDB est la suivante:IOS 10.3.1 L'application basée sur cordova se bloque en essayant d'écrire sur IndexedDB

writeToIDB: function (objStoreName, result, success, error) { 
    //Asynchronous function 
    var defer = Q.defer(); 
    var res = []; 
    if (!!result && Array.isArray(result)) { 
     res = result; 
    } else if (!!result && result.hasOwnProperty("results") && Array.isArray(result.results)) { 
     res = result.results; 
    } else if (!!result && typeof result === 'object') { 
     res.push(result); 
    } 
    if (res.length >= 0) { 
     if (window.myDB) { 
      if (!window.myDB.objectStoreNames.contains(objStoreName)) { 
       console.log("ObjectStore for " + objStoreName + " doesn't exist"); 
       if (error) { 
        error("ko") 
       } else { 
        defer.reject("ko"); 
       } 
      } else { 
       var oTransaction = window.myDB.transaction([objStoreName], "readwrite"); 
       var oDataStore = oTransaction.objectStore(objStoreName); 
       oTransaction.oncomplete = function (event) { 
        console.log("Transaction completed: database modification for " + objStoreName + " finished."); 
        if (success) { 
         success(); 
        } else { 
         defer.resolve("ok"); 
        } 

       }; 
       oTransaction.onerror = function (event) { 
        console.log("Transaction for " + objStoreName + " not opened due to error. Check for duplicate items or missing properties!"); 
        console.log(event.target.error); 
        if (error) { 
         error("ko") 
        } else { 
         defer.reject("ko"); 
        } 

       }; 
       var oRecord = {}; 
       for (var i = 0; i < res.length; i++) { 
        oRecord = res[i]; 
        oDataStore.put(oRecord); 
       } 
      } 
     } else { 
      this.createIDB().then(
       function (resCreate) { 
        console.log("DB Created successfully"); 
        if (!window.myDB.objectStoreNames.contains(objStoreName)) { 
         console.log("ObjectStore for " + objStoreName + " doesn't exist"); 
         if (error) { 
          error("ko") 
         } else { 
          defer.reject("ko"); 
         } 
        } else { 
         var oTransaction = window.myDB.transaction([objStoreName], "readwrite"); 
         var oDataStore = oTransaction.objectStore(objStoreName); 
         oTransaction.oncomplete = function (event) { 
          console.log("Transaction completed: database modification for " + objStoreName + " finished."); 
          if (success) { 
           success(); 
          } else { 
           defer.resolve("ok"); 
          } 
         }; 
         oTransaction.onerror = function (event) { 
          console.log("Transaction for " + objStoreName + " not opened due to error. Check for duplicate items or missing properties!"); 
          console.log(event.target.error); 
          if (error) { 
           error("ko") 
          } else { 
           defer.reject("ko"); 
          } 
         }; 
         var oRecord = {}; 
         for (var i = 0; i < res.length; i++) { 
          oRecord = res[i]; 
          oDataStore.put(oRecord); 
         } 
        } 
       }.bind(this), 
       function (err) { 
        console.log("DB Creation failed"); 
        if (error) { 
         error("ko") 
        } else { 
         defer.reject("ko"); 
        } 
       }.bind(this) 
      ); 
     } 
    } else { 
     if (error) { 
      error("ko") 
     } else { 
      defer.reject("ko"); 
     } 
    } 
    if (typeof success === 'undefined' && typeof error === 'undefined') { 
     return defer.promise; 
    } 


}, 

p.s.i. ont omis des parties du code. Cela fonctionnait très bien avec la version précédente de ios, je pense que j'avais installé le 10.2.1, maintenant il se bloque simplement après avoir appelé la méthode put. J'ai essayé de mettre à jour ios vers la bêta de 10.3.2 mais le résultat est le même. Quelqu'un d'autre a remarqué cela ou a une idée de la façon de résoudre ce problème? Merci K

MISE À JOUR J'ai trouvé la question: les types de données complexes. Comme IndexedDB supporte l'enregistrement et la récupération des types de données complexes, j'ai eu quelques propriétés qui étaient des tableaux ou des objets que j'avais l'habitude d'enregistrer dans certains de mes ObjectStores. C'est vraiment un gros problème pour moi parce que la seule solution que je peux penser pour cela est de stabiliser les champs complexes mais comme je travaille avec beaucoup de données cela créerait un gros problème de performance. J'espère que l'équipe de développeurs d'ios trouvera rapidement une solution pour cela

+0

Avez-vous des erreurs dans la console? –

+0

non, pas même un –

Répondre

0

Etes-vous sûr que chaque clé du tableau res [] est une clé valide? Il y a un bug fermé ici:

https://bugs.webkit.org/show_bug.cgi?id=170000

On dirait si vous passez dans une clé non valide, il causera webkit crash.

Ce correctif pour cela sera probablement contenu dans la prochaine version publique d'iOS.

Pour déterminer ce qu'est une clé valide est voir cette section de la spécification W3.org:

3.1.3 Touches

Afin de récupérer efficacement les enregistrements stockés dans une base de données indexée, chaque enregistrement est organisé selon sa clé. Une valeur est considérée comme une clé valide si elle est l'un des types ECMAScript [ECMA-262] suivants: valeur primitive Number, valeur de primitive String, objet Date ou objet Array. Un tableau est seulement une clé valide si chaque élément du tableau est défini et est une clé valide (c'est-à-dire que les tableaux clairsemés ne peuvent pas être des clés valides) et si le tableau ne se contient pas directement ou indirectement. Toutes les propriétés non numériques sur un tableau sont ignorées et n'affectent donc pas si le tableau est une clé valide. Si la valeur est de type Number, elle n'est valide que si elle n'est pas NaN. Si la valeur est de type Date, il s'agit uniquement d'une clé valide si sa propriété interne [[PrimitiveValue]], définie par [ECMA-262], n'est pas NaN. Les agents utilisateurs conformes doivent prendre en charge toutes les clés valides en tant que clés.

Ce fut pris d'ici:

https://www.w3.org/TR/IndexedDB/#key-construct

+0

Merci pour votre réponse. J'ai déjà vu avant le rapport de bug que vous avez mentionné mais je ne pense pas que ce soit mon cas. Il est vrai que j'ai des clés composées pour certains de mes objectStores mais je formate à l'avance chaque valeur passée à une chaîne vide si null ou undefined, et cela n'explique pas pourquoi, si le bug est lié aux clés composées cela arrive même avec le simple clés d'autres ObjectStore et pourquoi tout cela a bien fonctionné dans ios 10.2.1 qui était ma version précédente ios. Je pensais plus à un contrôle de sécurité introduit avec cette nouvelle version d'ios qui bloque tout ... –

0

Je ne sais pas si elle est la même question, mais j'ai eu un accident sur iOS 10.3 que je na pas obtenir dans un autre navigateur.L'utilisation wrapper Dexie pour IndexedDB, je l'ai fait un obtenir tous les documents de recherche de table:

db.table.toArray(function (results) { 
    // process... 
}) 

et a obtenu des flammes de Xcode à ce qui semblait être un problème de filetage dans WebKit donc je viens d'ajouter setTimeout(... ,1) et piraté autour du problème pour moi .