iOS 10.3.1基于Cordova的应用程序试图写入indexedDB时会崩溃



我正在开发一个基于Cordova的多平台Web应用程序,使用SAPUI5 Framework v1.44和indexedDB用于存储数据。该应用程序正常运行良好,上一次iOS更新,10.3.1,现在试图写入indexedDB时它崩溃了。我正在使用POT方法来更新数据,然后进行了整个应用程序的安装。我尝试写入索引的代码框架是:

    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省略了代码的一部分。这与以前版本的iOS合作正常,我认为我已经安装了10.2.1,现在调用PUT方法后仅崩溃。我现在尝试将iOS升级到10.3.2的Beta,但结果是相同的。其他人注意到这一点,或者对如何解决这个问题有任何想法?谢谢k

更新我发现了问题:复杂的数据类型。由于IndexedDB支持保存和检索复杂的数据类型,因此我有一些属性是用于保存在某些对象店中的数组或对象。这对我来说绝对是一个大问题,因为我能想到的唯一解决方法是刺激复杂的领域,但是由于我使用大量数据,这会造成一个很大的性能问题。我希望iOS开发人员团队能尽快找到解决方案

您确定res []数组中的每个密钥是有效的键吗?这里有一个封闭的错误:

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

看起来,如果您通过无效的键,它将导致Webkit崩溃。

此修复程序可能包含在iOS的下一个公开版本中。

确定什么有效键是W3.org规格的这一部分:

3.1.3键

为了有效检索存储在索引数据库中的记录,每个记录都是根据其密钥组织的。如果值是以下ecmascript [ECMA-262]类型之一:数字原始值,字符串原始值,日期对象或数组对象之一,则据说是有效的密钥。当定义数组中的每个项目并且是有效的密钥(即稀疏数组不能是有效的键(,并且数组不直接或间接包含自身,数组只是一个有效的密钥。数组上的任何非数字属性都被忽略,因此不会影响数组是否是有效的键。如果该值是类型编号,则仅在不是NAN时才是有效的密钥。如果值是类型日期的值,则仅当[ECMA-262]定义的内部属性[[PrimitiveValue]]内部属性不是NAN时,它仅是有效的密钥。符合用户代理必须支持所有有效键作为密钥。

这是从这里获取的:

https://www.w3.org/tr/indexeddb/#key-construct

不确定这是否是同一问题,但是我在iOS 10.3上遇到了崩溃,我没有在任何其他浏览器中获得。使用dexie包装器作为indexeddb,我从表搜索中获取了所有记录:

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

并从Xcode那里得到了WebKit中看起来像是线程问题的火焰,所以我刚刚添加了setTimeout( ... ,1),并为我围绕问题而入侵。

相关内容

  • 没有找到相关文章

最新更新