microsoft/vscode-cordova

Debugger does nothing when attaching to iOS device

fortinmike opened this issue · 11 comments

Actual Behavior

  1. Start debugging using the default "Attach to iOS on device" build config
  2. Nothing happens
    • The "debug starting" indicator animates indefinitely
    • There is no error nor any kind of output that I could find

Expected Behavior

  1. The debugger attaches to the running app

Additional information

Trying to find the cause of this, I made sure that ios-webkit-debug-proxy was actually working by trying to run it manually and using their troubleshooting steps (there was indeed something to fix). Now I can successfully view my running app and Webview in the ios-webkit-debug-proxywebpage on localhost:9221 if I run the proxy manually from Terminal.

I tried looking for output of some kind to understand why the extension does nothing, but as you can see below, there is no output anywhere to give any hint of what's going on.

I tried reinstalling the extension, restarting VS Code, etc.

A few peculiarities specific to my project that might have an impact on this:

  • The Cordova app does not live in the directory in which the .vscode/launch.json resides. I tried setting the cwd just in case (like this: "cwd": "${workspaceRoot}/../my-cordova-app",) but that does not help.
  • The app's web content is hosted by a dev server on my machine, which the app on the phone loads instead of its built-in files, using a redirect. I mention this because of #87 (comment). I tried the debugger with a fully packaged app but the issue remains.

Also, some troubleshooting led to the following facts:

  • It seems that the extension never starts the webkit debug proxy as I can successfully start the proxy manually from Terminal after launching the debug session in VS Code. If the extension did start the proxy, I assume that the 9221 port would be reserved and I shouldn't be able to start the proxy manually.

Thanks in advance for any help!

Software versions

  • Cordova VS Code extension version: 1.8.5
  • VSCode version: 1.37.1
  • OS platform and version: macOS 10.14.5
  • NodeJS version: 11.10.1
  • Cordova version: 9.0.0 (cordova-lib@9.0.1)
  • Cordova-Android/iOS/Windows version: 5.0.1

Outputs (Include if relevant)

  • Output of the Debug Console (View -> Toggle Debug Console):
No output at all
  • Output of the Cordova output channel (View -> Toggle Output -> Select Cordova in ListBox):
No "Cordova" item in the listbox
  • Output of the Developer Tools console (Help -> Toggle Developer Tools -> Select Console tab):
No output either

Hi @fortinmike and thanks for reaching us. Сould you please try to debug freshly created Сordova application and let us know how it works in your case? Also, it would be very helpful for us if you could share a configured demo application where this behaviour is reproduced.

I tested such configuration and it works without any problems:

  • rootFolder
    • .vscode/launch.json
    • cordova_app (fresh Cordova 9 app)

Content of launch.json file:

        {
            "name": "Attach to running iOS on device",
            "type": "cordova",
            "request": "attach",
            "platform": "ios",
            "target": "device",
            "port": 9220,
            "sourceMaps": true,
            "cwd": "${workspaceFolder}/cordova_app"
        }

At first, I run the app from the cordova_app folder and then attach to it with Attach to running iOS on device debug scenario.
Result of the cordova info command for the project:

cordova-lib@9.0.1 with:
  cordova-common@3.2.0
  cordova-create@2.0.0
  cordova-fetch@2.0.1
  cordova-serve@3.0.0

Environment: 
  OS: darwin (macOS 10.14.6)
  Node: v10.16.0
  npm: 6.9.0

Plugins:
  cordova-plugin-whitelist

Android platform:
  *************************************************************************
  The "android" command is deprecated.
  For manual SDK, AVD, and project management, please use Android Studio.
  For command-line tools, use tools/bin/sdkmanager and tools/bin/avdmanager
  *************************************************************************
  Running /Users/admin/Library/Android/sdk/tools/bin/avdmanager list target

  Available Android targets:==============] 100% Fetch remote repository...       
  ----------
  id: 1 or "android-27"
       Name: Android API 27
       Type: Platform
       API level: 27
       Revision: 3
  ----------
  id: 2 or "android-28"
       Name: Android API 28
       Type: Platform
       API level: 28
       Revision: 6



iOS platform:
  Xcode 10.3
  Build version 10G8

config.xml <<EOF
<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>HelloCordova</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
</widget>

EOF

package.json <<EOF
{
  "name": "helloworld",
  "displayName": "HelloCordova",
  "version": "1.0.0",
  "description": "A sample Apache Cordova application that responds to the deviceready event.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "ecosystem:cordova"
  ],
  "author": "Apache Cordova Team",
  "license": "Apache-2.0",
  "dependencies": {
    "cordova-android": "^8.0.0",
    "cordova-browser": "^6.0.0",
    "cordova-ios": "^5.0.1"
  },
  "devDependencies": {
    "cordova-plugin-whitelist": "^1.3.4"
  },
  "cordova": {
    "plugins": {
      "cordova-plugin-whitelist": {}
    },
    "platforms": [
      "android",
      "ios",
      "browser"
    ]
  }
}

Hi @fortinmike . Do you have a chance to look at this?

Sorry for the delay, I was on vacation.

I successfully ran the debugger and stopped at a breakpoint in a freshly-generated Cordova app, made as you suggested.

I'm still trying to figure out what might be different in our project, apart from the obvious peculiarities I mentioned in my initial post:

  • The Cordova app does not live in the directory in which the .vscode/launch.json resides. I tried setting the cwd just in case (like this: "cwd": "${workspaceRoot}/../my-cordova-app",) but that does not help.
  • The app's web content is hosted by a dev server on my machine, which the app on the phone loads instead of its built-in files, using a redirect. I mention this because of #87 (comment). I tried the debugger with a fully packaged app but the issue remains.

Do you have any troubleshooting steps to try and figure out where the extension is getting stuck? Is there a way I could step into the extension's code to try to figure out where the "freeze" happens?

Here is the result of running cordova info, if that can help figuring things out:

cordova-lib@9.0.1 with:
  cordova-common@3.2.0
  cordova-create@2.0.0
  cordova-fetch@2.0.1
  cordova-serve@3.0.0

Environment: 
  OS: darwin
  Node: v11.10.1
  npm: 6.7.0

Plugins:
  com.unarin.cordova.beacon
  cordova-plugin-device
  cordova-plugin-splashscreen
  cordova-plugin-whitelist
  cordova-plugin-wkwebview-engine

iOS platform:
  Xcode 10.3
  Build version 10G8

config.xml <<EOF
<!-- This is a generated file. Do not edit! -->
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.simbioz.Ripple" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>Ripple</name>
    <description>Ripple App</description>
    <author email="info@simbioz.com" href="http://www.simbioz.com">Simbioz</author>
    <content src="index.html" />

    <!-- This allows loading the app from our dev server at design time -->
    <access origin="*" />
    <allow-navigation href="*" />

    <!-- By overriding the user agent, we have a reliable way to detect that we're running in RCC from Ripple -->
    <preference name="OverrideUserAgent" value="rcc" />

    <!-- Disable the "fake" splash screen (keeps the platform-native one) to prevent the startup page from being hidden -->
    <preference name="SplashScreenDelay" value="0"/>
    <preference name="FadeSplashScreenDuration" value="0"/>

    <!-- Disable overscroll and bounce to prevent the whole app from being scrollable -->
    <preference name="webviewbounce" value="false" />
    <preference name="DisallowOverscroll" value="true" />

    <!-- Allow inline video playback on iOS. Only works in iOS 10+ with WKWebView, according to this: -->
    <!-- https://github.com/apache/cordova-plugin-wkwebview-engine#apple-issues -->
    <preference name="AllowInlineMediaPlayback" value="true" />

    <platform name="ios">
        <hook type="after_platform_add" src="scripts/apply-patches.js" />
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <icon src="../../app/rcc/ios/icon/icon_20pt.png" width="20" height="20" />
        <icon src="../../app/rcc/ios/icon/icon_20pt@2x.png" width="40" height="40" />
        <icon src="../../app/rcc/ios/icon/icon_20pt@3x.png" width="60" height="60" />
        <icon src="../../app/rcc/ios/icon/icon_29pt.png" width="29" height="29" />
        <icon src="../../app/rcc/ios/icon/icon_29pt@2x.png" width="58" height="58" />
        <icon src="../../app/rcc/ios/icon/icon_29pt@3x.png" width="87" height="87" />
        <icon src="../../app/rcc/ios/icon/icon_40pt.png" width="40" height="40" />
        <icon src="../../app/rcc/ios/icon/icon_40pt@2x.png" width="80" height="80" />
        <icon src="../../app/rcc/ios/icon/icon_40pt@3x.png" width="120" height="120" />
        <icon src="../../app/rcc/ios/icon/icon_60pt@2x.png" width="120" height="120" />
        <icon src="../../app/rcc/ios/icon/icon_60pt@3x.png" width="180" height="180" />
        <icon src="../../app/rcc/ios/icon/icon_76pt.png" width="76" height="76" />
        <icon src="../../app/rcc/ios/icon/icon_76pt@2x.png" width="152" height="152" />
        <icon src="../../app/rcc/ios/icon/icon_83.5@2x.png" width="167" height="167" />
        <icon src="../../app/rcc/ios/icon/icon.png" width="1024" height="1024" />
        <splash src="../../app/rcc/ios/splash/Default@2x~universal~anyany.png" />

        <!-- Use WKWebView instead of UIWebView on iOS (important for safe area, performance and possibly more.)-->
        <preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" />
        <feature name="CDVWKWebViewEngine">
          <param name="ios-package" value="CDVWKWebViewEngine" />
        </feature>
    </platform>

    <platform name="android">
        <allow-intent href="market:*" />
    </platform>

    <plugin name="cordova-plugin-whitelist" spec="^1.3.3" />
</widget>

EOF

package.json <<EOF
{
  "name": "rcc",
  "version": "1.0.0",
  "main": "index.js",
  "author": "Simbioz Dev",
  "license": "Apache-2.0",
  "scripts": {
    "template-config": "node templates/template.js templates/config.xml ../../app/rcc/config.json config.xml",
    "reinstall-ios": "rm -rf plugins && yarn template-config && cordova platform remove ios && cordova platform add ios",
    "setup-ios-codesign": "cordova build ios --buildConfig=\"../../app/rcc/ios/build.json\"",
    "postinstall": "yarn reinstall-ios"
  },
  "dependencies": {
    "com.unarin.cordova.beacon": "git+https://github.com/petermetz/cordova-plugin-ibeacon.git",
    "cordova-ios": "^5.0.1",
    "cordova-plugin-device": "^2.0.3",
    "cordova-plugin-splashscreen": "^5.0.3",
    "cordova-plugin-wkwebview-engine": "^1.2.1"
  },
  "devDependencies": {
    "cordova-plugin-whitelist": "^1.3.4",
    "eslint": "^6.3.0",
    "handlebars": "^4.2.0",
    "prettier": "^1.18.2"
  },
  "cordova": {
    "plugins": {
      "cordova-plugin-whitelist": {},
      "cordova-plugin-splashscreen": {},
      "com.unarin.cordova.beacon": {},
      "cordova-plugin-wkwebview-engine": {}
    },
    "platforms": [
      "ios"
    ]
  }
}

EOF

@fortinmike @SounD120
In a similar situation, the output for all consoles was empty for any of the run types.

My directory structure is something like this:

-root
|-cordova_app
|-related_microservice
|-container_for_proxying_services

When I opened a new VSCode window and made the cordova_app directory the root of the project, then the debug tools worked as expected. Apparently there is an issue if the config for the VSCode cordova plugin is not at the root level of the project.

Good catch, @newdaveespionage ! I can confirm that the debugger does try to start and produces output when I open a new VS Code window with the Cordova app's root as the workspace root. I get the following output:

Attaching to ios
Configuring debugging proxy
Unable to find target app webview, trying to fallback to the only running webview
Attaching to app.
'Debugger' domain was not foundError processing "attach": 'Debugger' domain was not found: [object Object]

I don't know why it doesn't connect in the end, but it wouldn't do much good as the source files aren't located in my www directory at dev time (the Cordova app loads the webpage from webpack-dev-server).

So two things seem to prevent the plugin from working:

  • vscode-cordova doesn't seem to like it at all when the Cordova app isn't the workspace root.
  • In my case, the fact that source files are not in www at dev time might prevent the plugin from finding them.

Are there "Cordova root directory" / "source directory" settings that can be used to inform the plugin of those things' locations? I've tried cwd to no avail.

Hi @fortinmike, It seems that the debugger couldn't attach because WKWebView plugin is used. We already have similar issue for Ionic. Such a problem arises because of existing IWDP issues with WKWebView since iOS 12.3.
With respect to the project root problem: could you please send us a minimal configured demo project, so we can reproduce and investigate that behavior?

@fortinmike Do you have a chance to look at this?

@RedMickey I'm swamped by other work ATM but as soon as I can I'll try to make a minimal demo project to reproduce the issue. I'd really like this to get fixed so I'll definitely get to it ASAP. Most likely on or after Oct. 3rd.

Did you try to open a parent folder of the Cordova project as the workspace root instead of the project directory itself? Seems like just that might cause the issue to occur, according to @newdaveespionage's comment.

Added a basic repo with the ionic tabs app here

Debugger runs, but does nothing even when left for several minutes:
Screen Shot 2019-09-24 at 1 07 56 PM

Hi @fortinmike, @newdaveespionage.
It could be better to use multi-root approach to work with subdirectories.

  1. Open VS Code
  2. Click File from top menu, then select Add Folder to Workspace
  3. Choose your project folder and add it

Thus you will able to work with several projects in one workspace.
Further we also figured out why the extension displayes the following error:

'Debugger' domain was not foundError processing "attach": 'Debugger' domain was not found: [object Object]

Sо, under the hood this extension uses Chrome DevTools Protocol for debugging, but iOS devices require Webkit Remote Debugging Protocol. Ios-webkit-debug-proxy (IWDP) allows to transform Webkit Protocol to Chrome DevTools Protocol. IWDP worked perfectly until the changes in WKWebView since iOS 12.2. We already have similar issue for Ionic and figured out that Cordova has the same problem if WKWebView is using for application rendering. According to IWDP issue the library hasn’t been adapted to changes in WKWebView yet.
As seen from your project configuration, there is cordova-plugin-wkwebview-engine installed in your project. This plugin changes standard Cordova UIWebView to WKWebView, so IWDP can’t work properly and it leads to an attach error.
As this behavior is connected with IWDP issues I recommend to track the fix status in the IWDP repo.

Hey guys. Since this behavior is connected to ios-webkit-debug-proxy issues I am closing this issue. #574 was created for tracking workspace documentation enhancement issue.