@@ -9,6 +9,7 @@ import 'package:process/process.dart';
9
9
import 'package:vm_service/vm_service.dart' as vm_service;
10
10
11
11
import '../application_package.dart' ;
12
+ import '../base/common.dart' ;
12
13
import '../base/file_system.dart' ;
13
14
import '../base/io.dart' ;
14
15
import '../base/logger.dart' ;
@@ -21,6 +22,7 @@ import '../device.dart';
21
22
import '../device_port_forwarder.dart' ;
22
23
import '../globals.dart' as globals;
23
24
import '../macos/xcdevice.dart' ;
25
+ import '../mdns_discovery.dart' ;
24
26
import '../project.dart' ;
25
27
import '../protocol_discovery.dart' ;
26
28
import '../vmservice.dart' ;
@@ -189,15 +191,6 @@ class IOSDevice extends Device {
189
191
return majorVersionString != null ? int .tryParse (majorVersionString) ?? 0 : 0 ;
190
192
}
191
193
192
- @override
193
- bool get supportsHotReload => interfaceType == IOSDeviceConnectionInterface .usb;
194
-
195
- @override
196
- bool get supportsHotRestart => interfaceType == IOSDeviceConnectionInterface .usb;
197
-
198
- @override
199
- bool get supportsFlutterExit => interfaceType == IOSDeviceConnectionInterface .usb;
200
-
201
194
@override
202
195
final String name;
203
196
@@ -318,7 +311,11 @@ class IOSDevice extends Device {
318
311
@visibleForTesting Duration ? discoveryTimeout,
319
312
}) async {
320
313
String ? packageId;
321
-
314
+ if (interfaceType == IOSDeviceConnectionInterface .network &&
315
+ debuggingOptions.debuggingEnabled &&
316
+ debuggingOptions.disablePortPublication) {
317
+ throwToolExit ('Cannot start app on wirelessly tethered iOS device. Try running again with the --publish-port flag' );
318
+ }
322
319
if (! prebuiltApplication) {
323
320
_logger.printTrace ('Building ${package .name } for $id ' );
324
321
@@ -353,8 +350,10 @@ class IOSDevice extends Device {
353
350
EnvironmentType .physical,
354
351
route,
355
352
platformArgs,
353
+ ipv6: ipv6,
354
+ interfaceType: interfaceType,
356
355
);
357
- final Status installStatus = _logger.startProgress (
356
+ Status startAppStatus = _logger.startProgress (
358
357
'Installing and launching...' ,
359
358
);
360
359
try {
@@ -379,9 +378,10 @@ class IOSDevice extends Device {
379
378
deviceLogReader.debuggerStream = iosDeployDebugger;
380
379
}
381
380
}
381
+ // Don't port foward if debugging with a network device.
382
382
observatoryDiscovery = ProtocolDiscovery .observatory (
383
383
deviceLogReader,
384
- portForwarder: portForwarder,
384
+ portForwarder: interfaceType == IOSDeviceConnectionInterface .network ? null : portForwarder,
385
385
hostPort: debuggingOptions.hostVmServicePort,
386
386
devicePort: debuggingOptions.deviceVmServicePort,
387
387
ipv6: ipv6,
@@ -412,12 +412,59 @@ class IOSDevice extends Device {
412
412
return LaunchResult .succeeded ();
413
413
}
414
414
415
- _logger.printTrace ('Application launched on the device. Waiting for observatory url.' );
416
- final Timer timer = Timer (discoveryTimeout ?? const Duration (seconds: 30 ), () {
417
- _logger.printError ('iOS Observatory not discovered after 30 seconds. This is taking much longer than expected...' );
418
- iosDeployDebugger? .pauseDumpBacktraceResume ();
415
+ _logger.printTrace ('Application launched on the device. Waiting for Dart VM Service url.' );
416
+
417
+ final int defaultTimeout = interfaceType == IOSDeviceConnectionInterface .network ? 45 : 30 ;
418
+ final Timer timer = Timer (discoveryTimeout ?? Duration (seconds: defaultTimeout), () {
419
+ _logger.printError ('The Dart VM Service was not discovered after $defaultTimeout seconds. This is taking much longer than expected...' );
420
+
421
+ // If debugging with a wireless device and the timeout is reached, remind the
422
+ // user to allow local network permissions.
423
+ if (interfaceType == IOSDeviceConnectionInterface .network) {
424
+ _logger.printError (
425
+ '\n Click "Allow" to the prompt asking if you would like to find and connect devices on your local network. '
426
+ 'This is required for wireless debugging. If you selected "Don\' t Allow", '
427
+ 'you can turn it on in Settings > Your App Name > Local Network. '
428
+ "If you don't see your app in the Settings, uninstall the app and rerun to see the prompt again."
429
+ );
430
+ } else {
431
+ iosDeployDebugger? .pauseDumpBacktraceResume ();
432
+ }
419
433
});
420
- final Uri ? localUri = await observatoryDiscovery? .uri;
434
+
435
+ Uri ? localUri;
436
+ if (interfaceType == IOSDeviceConnectionInterface .network) {
437
+ // Wait for Dart VM Service to start up.
438
+ final Uri ? serviceURL = await observatoryDiscovery? .uri;
439
+ if (serviceURL == null ) {
440
+ await iosDeployDebugger? .stopAndDumpBacktrace ();
441
+ return LaunchResult .failed ();
442
+ }
443
+
444
+ // If Dart VM Service URL with the device IP is not found within 5 seconds,
445
+ // change the status message to prompt users to click Allow. Wait 5 seconds because it
446
+ // should only show this message if they have not already approved the permissions.
447
+ // MDnsVmServiceDiscovery usually takes less than 5 seconds to find it.
448
+ final Timer mDNSLookupTimer = Timer (const Duration (seconds: 5 ), () {
449
+ startAppStatus.stop ();
450
+ startAppStatus = _logger.startProgress (
451
+ 'Waiting for approval of local network permissions...' ,
452
+ );
453
+ });
454
+
455
+ // Get Dart VM Service URL with the device IP as the host.
456
+ localUri = await MDnsVmServiceDiscovery .instance! .getVMServiceUriForLaunch (
457
+ packageId,
458
+ this ,
459
+ usesIpv6: ipv6,
460
+ deviceVmservicePort: serviceURL.port,
461
+ isNetworkDevice: true ,
462
+ );
463
+
464
+ mDNSLookupTimer.cancel ();
465
+ } else {
466
+ localUri = await observatoryDiscovery? .uri;
467
+ }
421
468
timer.cancel ();
422
469
if (localUri == null ) {
423
470
await iosDeployDebugger? .stopAndDumpBacktrace ();
@@ -429,7 +476,7 @@ class IOSDevice extends Device {
429
476
_logger.printError (e.message);
430
477
return LaunchResult .failed ();
431
478
} finally {
432
- installStatus .stop ();
479
+ startAppStatus .stop ();
433
480
}
434
481
}
435
482
@@ -569,7 +616,6 @@ String decodeSyslog(String line) {
569
616
}
570
617
}
571
618
572
- @visibleForTesting
573
619
class IOSDeviceLogReader extends DeviceLogReader {
574
620
IOSDeviceLogReader ._(
575
621
this ._iMobileDevice,
0 commit comments