2

我发现修复特定于我的应用程序的 iOS 部分的问题非常慢。我想知道当浏览器调试器不可用时调试 Worklight 应用程序的推荐方法。

特别是,我正在处理仅适用于 iOS 和 Android 的 WL.JSONStore 问题。我无法使用浏览器调试器查看发生了什么。当我执行 WL.Logger.debug() 语句时,Xcode 控制台中没有显示任何内容,iPad 模拟器控制台 (Cordova) 仅显示几行。本周也有一段时间没有在任何地方打印输出。

我也下载并安装了 Weinre,但它的控制台中似乎没有显示任何打印语句,而且通常我只是看不到有关我需要的区域的信息。

提前感谢您的建议。

4

2 回答 2

4

通用 Worklight 5.0.6 调试

Worklight 5.0.6 上 JSONStore 的调试提示

  • 尝试console.log('message')WL.Logger.debug('message')在里面jsonstore.js和你的代码([app-name].js等)。输出应该显示在 Xcode 的控制台和 Android 的 LogCat 中。

  • 重置模拟器或模拟器和/或调用WL.JSONStore.destroy().

  • 确保您在受支持的环境中运行:

    • Android >=2.2 ARM/x86 模拟器或设备
    • iOS >=5.0 模拟器或设备
  • 尝试关闭加密(即不要将密码传递给WL.JSONStore.initWL.JSONStore.initCollection)。

  • 查看 JSONStore 生成的 SQLite 数据库文件。这仅在加密关闭时有效。

    • 安卓:

        $ adb shell
        $ cd /data/data/com.[app-name]/databases/wljsonstore
        $ sqlite3 jsonstore.sqlite
      
    • iOS

        $ cd ~/Library/Application Support/iPhone Simulator/6.1/Applications/[id]/Documents/wljsonstore
        $ sqlite3 jsonstore.sqlite
      

    尝试查看 searchFields.schema并使用 选择数据SELECT * FROM [collection-name];。退出sqlite3类型.exit。以这个 StackOverflow 问题为例。

  • (仅限 Android)启用详细 JSONStore。

      adb shell setprop log.tag.jsonstore-core VERBOSE
      adb shell getprop log.tag.jsonstore-core
    
  • (仅限 iOS >=6.0 和 Safari >=6.0)尝试使用JavaScript 调试器。在里面设置断点jsonstore.js。有用的线路:

    • 桥接本机代码:

        cdv.exec(options.onSuccess, options.onFailure, pluginName, nativeFunction, args);
      
    • 从本机代码返回的成功回调:

        deferred.resolve(data, more);
      
    • 从 Native 代码返回的失败回调:

        deferred.reject(new ErrorObject(errorObject));
      
  • 编写适当的测试(单元、功能、集成——获得测试覆盖率)。这是一个使用QUnitSinon.js创建沙盒环境的模板,您可以在其中测试 JSONStore 如何处理不同类型的数据/调用:

      <!DOCTYPE HTML>
      <html>
    
      <head>
          <title>JSONStore Test App</title>
          <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css">
          <script src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
          <script src="http://sinonjs.org/releases/sinon-1.6.0.js"></script>
          <script>
              //QUnit configuration flags, no need to change it.
              QUnit.config.requireExpects = true;
          </script>
      </head>
    
      <body id="content" style="display: none;">
    
          <!-- Test results will be appended to the div below, no need to make changes here. -->
          <div id="qunit"></div>
    
      <script>
    
      //Start Worklight
      WL.Client.init({connectOnStartup : false});
    
      //Hook into the deviceready event
      document.addEventListener("deviceready", onDeviceReady, false);
    
      //onDeviceReady will be called when JSONStore/Cordova is ready
      function onDeviceReady () {
    
          //Auto executing function that holds the test
          (function (jQuery) { //The variable jQuery is usable inside.
    
              //Mock WL.Client.invokeProcedure using a Stub.
              //This is only useful if you need to link a Worklight Adapter
              //to a JSONStore collection to reproduce your issue or bug.
              //API Doc: http://sinonjs.org/docs/#stubs
              var fakeAdapter = sinon.stub(WL.Client, "invokeProcedure", function (invocationData, options) {
    
                  //DO NOT Create a real adapter, just mock the reponse here if it's relevant to the bug.
                  var ADAPTER_RESPONSE = {invocationResult: {fakeKey: [{fn: 'carlos'}, {fn: 'mike'}]}};
                  options.onSuccess(ADAPTER_RESPONSE);
              });
    
              //[**Explain your test here**]
              var EXPECTED_ASSERTIONS = 2; //every assertion is a deepEqual below.
              asyncTest('[**Meaningful title here**]', EXPECTED_ASSERTIONS, function () {
    
                  //Destroy first to make sure we don't depend on state
                  WL.JSONStore.destroy()
    
                  .then(function () {
    
                      //[**Start writting your test here**]
                      //The test below is an example, it does the following:
                      // - Initializes a collection linked to a fake adapter (see stub above).
                      // - Checks if initialization worked by checking the collection name.
                      // - Loads data from the fake adapter (see stub above).
                      // - Checks if load worked by checking the number of documents loaded.
    
                      var collections = {
                          col1 : {
                              searchFields : {fn: 'string'},
                              adapter : {name: 'fakeAdapter',
                                  load: {
                                      procedure: 'fakeProcedure',
                                      params: [],
                                      key: 'fakeKey'
                                  }
                              }
                          }
                      };
    
                      return WL.JSONStore.init(collections);
                  })
    
                  .then(function (response) {
    
                      //Prep for your assertion
                      var ACTUAL_VALUE = response.col1.name;
                      var EXPECTED_VALUE = 'col1';
                      var COMMENT = 'Checking for the right collection name';
    
                      //Do your assertion using deepEqual
                      //API Doc: http://api.qunitjs.com/deepEqual/
                      deepEqual(ACTUAL_VALUE, EXPECTED_VALUE, COMMENT);
    
                      return WL.JSONStore.get('col1').load();
                  })
    
                  .then(function (response) {
    
                      //Prep for your assertion
                      var ACTUAL_VALUE = response; //load returns number of documents loaded
                      var EXPECTED_VALUE = 2; //two documents are returned by the fake adapter (stub)
                      var COMMENT = 'Checking if load worked';
    
                      //Do the assertion using deepEqual
                      deepEqual(ACTUAL_VALUE, EXPECTED_VALUE, COMMENT);
    
                      start();//call start() after you finish your test succesfully
                  })
    
                  .fail(function (error) {
    
                      deepEqual(false, true, 'Failure callback should not be called' + error.toString());
                      start();//call start() after you finish your test with a failure
                  });
    
              });
    
          }(WLJQ)); //end auto executing function that holds the test
    
      } //end wlCommonInit
      </script>
    
      </body>
      </html>
    

上述代码的预期输出:

图片

旁注:这是一篇关于特定开发人员的 PhoneGap/Cordova 工作流程的一般文章。有一部分调试,只是基于浏览器。其中一些也适用于 IBM Worklight 开发。

于 2013-04-11T22:29:23.337 回答
1

cnandreu 在这里提供了很好的提示。尽管如此,能见度还是很差,这些方法并没有真正解决我的问题。我还想建议我发现在我的项目中最有用的东西(除了 WL.Logger.debug() 无处不在):

  • JSConsole 已经不可或缺(http://jsconsole.com/)。实际上,我实际上并没有像预期的那样使用它。但是,我发现它的启动警告消息对 WL.Logger.debug()(和 console.log())有作用,使语句能够实际打印到控制台,这样我就可以看到我在做什么。

  • 在 iOS 6 中,Mac 上的 Safari 允许您检查连接设备的 DOM。它相当有用,特别是对于仅在 iOS 上本机运行时行为不端的混合 UI 问题。否则我觉得它不是很有帮助。在https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/DebuggingSafarioniPhoneContent/DebuggingSafarioniPhoneContent.html上查看更多信息

  • 我一直在使用的最有用的技术是将状态消息写入 UI。是的,这是一种丑陋的史前做事方式,但其他一切——包括 80 年代到控制台的错误打印语句——都惨遭失败。这是我所做的(使用 Dojo 和 JavaScript):

    var v = dom.byId('audio_status'); if (v) { v.innerHTML += "recording file ["+filename+"]"; }

显示调试内容的 DIVaudio_status在哪里。ID

这东西很丑,但至少我们可以看到一些东西

于 2013-05-26T17:58:02.030 回答