Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flutter run should support wireless debugging of iOS devices #15072

Closed
phumberdroz opened this issue Mar 2, 2018 · 87 comments · Fixed by #118104 or #118895
Closed

flutter run should support wireless debugging of iOS devices #15072

phumberdroz opened this issue Mar 2, 2018 · 87 comments · Fixed by #118104 or #118895
Assignees
Labels
a: annoyance Repeatedly frustrating issues with non-experimental functionality c: new feature Nothing broken; request for a new capability customer: crowd Affects or could affect many people, though not necessarily a specific customer. P2 Important issues not at the top of the work list platform-ios iOS applications specifically r: fixed Issue is closed as already fixed in a newer version tool Affects the "flutter" command-line tool. See also t: labels.

Comments

@phumberdroz
Copy link

phumberdroz commented Mar 2, 2018

Latest update: #15072 (comment)


Steps to Reproduce

connect iPhone via usb
Open xcode -> window -> devices & Simulators -> select correct device and enable connect via network
Network Symbol is shown in the list to the left
disconnect iPhone

Android Studio shows devices but if you try to run it it is in an endless waiting loop without visual indication

If you then connect the devices via USB it continues on

Logs

https://gist.github.com/phumberdroz/9700d43d2bc9f5e510bebc6dab9b509c

Flutter Doctor

[✓] Flutter (Channel beta, v0.1.5, on Mac OS X 10.13.3 17D102, locale en-US)
    • Flutter version 0.1.5 at /Users/phumberdroz/flutter
    • Framework revision 3ea4d06340 (8 days ago), 2018-02-22 11:12:39 -0800
    • Engine revision ead227f118
    • Dart version 2.0.0-dev.28.0.flutter-0b4f01f759

[✓] Android toolchain - develop for Android devices (Android SDK 27.0.3)
    • Android SDK at /Users/phumberdroz/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-27, build-tools 27.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-915-b08)

[✓] iOS toolchain - develop for iOS devices (Xcode 9.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 9.2, Build version 9C40b
    • ios-deploy 1.9.2
    • CocoaPods version 1.4.0

[✓] Android Studio (version 3.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-915-b08)

[✓] IntelliJ IDEA Ultimate Edition (version 2017.3.4)
    • Flutter plugin version 22.2.2
    • Dart plugin version 173.4548.30

[✓] VS Code (version 1.20.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Dart Code extension version 2.9.2

[✓] Connected devices (2 available)
    • Pierre’s iPhone • ec754a5c0607923df2a99ccd051938e0045dee6b • ios • iOS 11.2.6
    • iPhone 7        • 5001A557-2FB6-49EB-8C5C-ABC8396F19E9     • ios • iOS 11.2 (simulator)

• No issues found!
> For more information about diagnosing and reporting Flutter bugs, please see [https://flutter.io/bug-reports/](https://flutter.io/bug-reports/).
@Hixie
Copy link
Contributor

Hixie commented May 30, 2018

cc @devoncarew IDE bug

@devoncarew
Copy link
Member

This issue was moved to flutter/flutter-intellij#2308

@devoncarew devoncarew reopened this Jun 1, 2018
@devoncarew
Copy link
Member

@phumberdroz, to re-phrase your report:

  • connect iPhone via usb
  • use an xcode feature to enable connect via network
  • disconnect iPhone

We then locate the device correctly, but when you try and run, flutter run doesn't work with it. It sounds like flutter_tools doesn't work with the network style connection. @cbracken @xster

@devoncarew devoncarew added tool Affects the "flutter" command-line tool. See also t: labels. platform-ios iOS applications specifically labels Jun 1, 2018
@devoncarew devoncarew changed the title Wireless Debugging does not work with Android Studio flutter_tools doesn't support the wireless debugging style connections for iOS devices (for flutter run) Jun 1, 2018
@devoncarew devoncarew added this to the No milestone necessary milestone Jun 1, 2018
@phumberdroz
Copy link
Author

phumberdroz commented Jun 1, 2018

100% correct

@cbracken
Copy link
Member

cbracken commented Jun 4, 2018

I suspect we'll need to apply patches to our integration with the libimobiledevice toolchain. IIRC, we intentionally disabled wifi debugging due to issues a couple of years ago. I'll see if I can dig up the issue(s) and x-ref them here then we can look at a fix. Tooling has improved significantly since then, so definitely worth another look.

@cbracken
Copy link
Member

cbracken commented Jun 4, 2018

#8309 is where I disabled this. #7233 and #8308 were a couple reports of issues with wifi debugging enabled.

@tonikami
Copy link

@cbracken Any update on this?

@anderscheow
Copy link

We need this :(

@zoechi
Copy link
Contributor

zoechi commented Feb 11, 2019

The thumbs-ups should be on the initial comment to raise priority.

@Hixie
Copy link
Contributor

Hixie commented Apr 30, 2019

@anderscheow Can you talk more about why you need this? (It would help us with prioritization.)

@Hixie
Copy link
Contributor

Hixie commented Apr 30, 2019

cc @cyanglaz

@anderscheow
Copy link

@Hixie Using traditional way (wired connection) to do debugging is kinda troublesome. At some points, if cable is having issue, I need to get another cable in order to make debugging works.

@kunit1
Copy link

kunit1 commented May 2, 2019

In my case, one of the test devices has a bad lightning port; the device is otherwise fully functional. This would allow me to use this device for debugging while avoiding the finicky cable.

@ride4sun
Copy link

ride4sun commented May 2, 2019 via email

@Hixie Hixie modified the milestones: No milestone necessary, Goals May 3, 2019
@Hixie
Copy link
Contributor

Hixie commented May 3, 2019

Thanks for the clarifications!

@cbracken
Copy link
Member

cbracken commented May 3, 2019

I suspect we'll need this sooner or later.

Given the direction things are going (e.g. with headphones), one could also envision a day when Apple ships devices that charge wirelessly and don't include a lightning/USB-C port. FWIW I have no actual evidence for this; this is pure speculation on my part.

@zjjt

This comment was marked as off-topic.

@matthewlloyd
Copy link
Contributor

I'll add that I've been testing extensively both with Android, over WiFi, and iOS, tethered with a Lightning cable, and it really does make a difference having wireless support. My iPhone is my daily driver so when I need to test with it, I first have to find it (did I leave it on the kitchen counter?), then find the cable (I unplugged it when I took my laptop to the park, but where is it?), plug it in, then pick up the phone with the cable attached getting in the way of my hand, making it clumsy to test; iTunes automatically opens and I have to close it, then when I'm done debugging, I have to unplug the cable again. It's maybe only a minute of hassle each time, but it adds up, and I find myself testing mostly using WiFi on Android because it's faster and more convenient. It's a bit like hot swap, not strictly necessary but really, really great.

@caseyryan

This comment has been minimized.

@TabooSun
Copy link
Contributor

TabooSun commented Jan 27, 2022

I have forked @jmagman PR here. It really doesn't work for me as commented here, however, there is no detail on what isn't working. I tried to dig into it and found out that this is due to the fact that idevicepair -u <device UUID> pair is needed to be run (while the ios device is connected with cable) and you need to trust this mac on your ios device. Once this is done, you can unplug and happily debug wirelessly. I don't see these steps documented in @jmagman PR, so I guess this is the reason it does not work?

However, you need to do this quite frequently, at least from my observation, when any of the devices iPhone or MacBook sleep/restart. I am quite busy recently so my exploration stops here. I guess there should be a way to fix this by looking into the reason why mac can't remember the device.

@jmagman
Copy link
Member

jmagman commented Jan 27, 2022

I tried to dig into it and found out that this is due to the fact that idevicepair -u <device UUID> pair is needed to be run (while the ios device is connected with cable) and you need to trust this mac on your ios device.

Thanks for trying it. Flutter currently assumes the device is already paired in the normal tethered case. It doesn't try to pair if it's not. Once I had the device wirelessly set up in Xcode I didn't need to re-trust anything. It just constantly disconnected and forgot its network connected status, I kept having to re-tether and re-check that box (all in Xcode, this had nothing to do with Flutter). But I never needed to re-pair once it was paired.

@epaterlini
Copy link

epaterlini commented Apr 26, 2022

I am testing locally the "iproxy" program (which is at the heart of communication between computer and device).
I developed a very simple TCP server app that runs on my iPad and listens to every interface (0.0.0.0).
I then tried to connect in those ways:

  • directly through iPad WiFi's IP address: worked (of course)
  • using iproxy with iPad connected through USB (and WiFi disabled): worked
  • using iproxy with iPad connected over WiFi: not working (connection refused)

I suspect then that is "iproxy" program that's having trouble forwarding ports over Wi-Fi?
If yes, we can focus on fixing "iproxy" tool first and then retry testing the iOS WiFi debugging.

Let me know what you think guys,
cheers for now.

@jpangburn
Copy link

jpangburn commented Apr 26, 2022

@epaterlini looking at the iproxy man page may help. I know nothing about it, but the Archlinux one is
here. Relevant bits may be:

-n, --network
Connect to network device. The device needs to have WiFi sync enabled and needs to be paired with this computer for this to work. Please note that a device might close connections at any time to save power. This option will make iproxy try to connect to network attched devices only, unless -l is passed too (see below).
-l, --local
Connect to USB device. This is the default if no option is passed. If used together with -n, iproxy will first attempt a connection to a device attached via USB, and if not available attempt to reach a device via network.
-s, --source ADDR
Allows setting a source address for the listening socket. The default is 127.0.0.1 (local connections only). While not needed in normal setups, this option allows other than local connections, for example 0.0.0.0 would make the TCP proxy port(s) accessible from other computers in the network.
WARNING: Use with caution since this could expose a device over the network!

So looks like the default is a USB connection with -l and listen on 127.0.0.1. So may need -n -s 0.0.0.0 passed as options? Just wildly throwing a guess out here as I've not played with it at all.

@epaterlini
Copy link

epaterlini commented Apr 26, 2022

Hello @jpangburn,
yes of course I passed the "-n" flag when connecting through WiFi (otherwise I would get a "No device found" error) :-)
Regarding the "-s" (source) parameter, for me "localhost" (and for the Flutter use case I think) is fine, as I'm trying to forward device's port to localhost and then connect to localhost.
Thank you for your interest, any way :-) do you have some other ideas?

@jpangburn
Copy link

@epaterlini Sorry I misunderstood. I thought this line:

using iproxy with iPad connected over WiFi: not working (connection refused)

meant you were implicitly using -l rather than explicitly passing -n. But I see I misunderstood. Hope you have some success with this!

@TabooSun
Copy link
Contributor

The last remaining hurdle on the Flutter side is figuring out a reliable way to get the iOS device IP address to connect to the observatory.

@jmagman I have a suggestion for this. Since we have already added BonjourService in the Info.plist, i.e. _dartobservatory._tcp, we could probably make use of it to get the iOS IP address.

I tried writing a simple Swift CLI app to interact with the Network framework and turns out being able to get the IP address.

class BonjourService : NSObject, NetServiceDelegate {
	private let domain = "local"
	private let type = "_dartobservatory._tcp"
	private var bonjourBrowser: NWBrowser?
	private var netService: NetService?

	init(name: String) {
		super.init()
		bonjourBrowser = NWBrowser(for: .bonjourWithTXTRecord(type: type, domain: domain), using: NWParameters())
		let netService = NetService(domain: domain, type: type, name: name)
		self.netService = netService
		startDiscovering()
	}

	private func startDiscovering() {
		bonjourBrowser!.browseResultsChangedHandler = {
			(newResults: Set<NWBrowser.Result>, changes: Set<NWBrowser.Result.Change>) in
			self.resolveNetworkInformation()
		}
//		bonjourBrowser.start(queue: DispatchQueue.global())
		bonjourBrowser!.start(queue: DispatchQueue.main)
	}

	private func resolveNetworkInformation() {
		bonjourBrowser!.browseResults.forEach { (result) in
			/*	result.resolve(with: NWBrowser.Resolution.parameters(NWParameters())) { (newResult) in
				print("newResult: \(newResult)")
			}*/
			switch result.endpoint {
				case .hostPort(host: _, port: _):
					break;
				case .service(name: let name, type: let type, domain: let domain, interface: _):
					if netService!.delegate == nil {
						netService!.delegate = self
					}
					netService!.resolve(withTimeout: 10)
					break;
				case .unix(path: _):
					break;
				case .url(_):
					break;
				@unknown default:
					break;
			}
			/*NetService(domain: "local", type: "_dartobservatory._tcp", name: result.endpoint. 
			 )*/
		}
	}

	func netServiceDidResolveAddress(_ sender: NetService) {
		if let addresses = sender.addresses {
			addresses.filter({ data in data.count == 16 }).map { data -> String in
						var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
						return data.withUnsafeBytes { (ptr) -> String in
							guard let sockaddr_ptr = ptr.baseAddress?.assumingMemoryBound(to: sockaddr.self) else {
								return ""
							}
							let sockaddr = sockaddr_ptr.pointee
							guard getnameinfo(sockaddr_ptr, socklen_t(sockaddr.sa_len), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 else {
								return ""
							}
							return String(cString: hostname)
						}
					}
					.forEach { s in
						print("\(s)")
					}
		}
	}
}

In main.swift:

let bonjourService = BonjourService(name: "com.example.websocketplayground")

while true {
	RunLoop.current.run()
}

Now the only missing part that I can't figure out is the way to distinguish between multiple devices while debugging on these devices at the same time. Maybe someone can take it from here?

@thomassth
Copy link

Can we just add a flag for a single debug device only for the meantime?

This is already a great improvement

@seifkh97

This comment was marked as duplicate.

@saviourdog

This comment was marked as duplicate.

@edgarfroes

This comment was marked as off-topic.

@ahyangnb

This comment was marked as duplicate.

@jmagman
Copy link
Member

jmagman commented Dec 5, 2022

However, please PLEASE do not reply to this issue with "any updates?" or "me too" or other reasons why this feature should be implemented. You're adding noise to an issue with 50 participants and untold subscribers. And you're pushing out actually informative comments (like this one). Just hit it with a 👍.

@jmagman
Copy link
Member

jmagman commented Jan 19, 2023

#118826 was temporarily reverted.

@jmagman jmagman reopened this Jan 19, 2023
Tools - iOS review automation moved this from Engineer reviewed to Awaiting triage Jan 19, 2023
Tools - iOS review automation moved this from Awaiting triage to Engineer reviewed Jan 20, 2023
@jmagman
Copy link
Member

jmagman commented Jan 20, 2023

#118104 is available on the master channel, and we would love some feedback!

Setup

  1. Follow the instructions under "Steps to setup" in the Support iOS wireless debugging #118104 description. There's currently no way to set up wireless debugging from flutter, you need to do it from Xcode.
    Add feature to enable iOS wireless debugging from a flutter command. #118912
  2. Try flutter devices --device-timeout 5 / flutter run --device-timeout 5 etc. from the command line. You may need to adjust that timeout number up depending on your network.

Caveats

  1. You'll need to add --device-timeout to your flutter commands, as networked devices take longer to discover. We're working on making this a better experience.
    iOS network device not available when doing flutter run #118109
    iOS network device not selected when running/debugging in VSCode #118113
  2. Because of the device timeout issue, when you Run from your IDE, it may not discover your wirelessly connected device before timing out. Try the workaround listed in Support iOS wireless debugging #118104 to pass in --device-timeout as args.
    VSCode launch.json example:
{
  ...
  "configurations": [
      {
          "name": "my_app",
          "request": "launch",
          "type": "dart",
          "args": ["--device-timeout", "5"]
      },
      ...
  ]
}
  1. There is no documentation for iOS wireless debugging yet. We will add it to the website when the feature is further along.
  2. Installing and hot reloading wirelessly over the network is much slower than over a USB tether. There's not much Flutter can do about that, it's the performance characteristics of Xcode/iOS.
  3. To run your app from Xcode and flutter attach, you must add --observatory-host=0.0.0.0 or --observatory-host=::0 as a launch argument in your Xcode scheme. This would also be true for running an add-to-app host app with an embedded Flutter module. See Support iOS wireless debugging #118104 for instructions.
  4. If Xcode can't find your device, then Flutter tooling won't be able to either. If Flutter isn't discovering your device, open Xcode > Window > Devices and Simulators > Devices and make sure you see the device is under connected with globe network icon, and Connect via Network is checked. If either isn't true then you'll have to play with the settings in Xcode until it shows up.
    211061613-9f6f145d-be97-4722-9d2c-f5deee316be5

Please file new issues, including usability suggestions, as you see them. Thank you!

@AmitSonkhiya
Copy link

#118104 is available on the master channel, and we would love some feedback!

Submitted feedback
#119493

@maheshmnj maheshmnj added the r: fixed Issue is closed as already fixed in a newer version label Feb 1, 2023
@jmagman
Copy link
Member

jmagman commented Feb 21, 2023

#118104 is available on 3.7.0-24.0.pre and higher on the beta channel. If you are trying to test this you must either be on the master or beta channels, it is not yet available in stable.

@github-actions
Copy link

github-actions bot commented Mar 7, 2023

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a: annoyance Repeatedly frustrating issues with non-experimental functionality c: new feature Nothing broken; request for a new capability customer: crowd Affects or could affect many people, though not necessarily a specific customer. P2 Important issues not at the top of the work list platform-ios iOS applications specifically r: fixed Issue is closed as already fixed in a newer version tool Affects the "flutter" command-line tool. See also t: labels.
Projects
Tools - iOS review
  
Engineer reviewed