Skip to content

Running dev on device Iphone 15+ and IOS17+ will fail if you have a Apple Watch in Run Destinations. #417

@iskng

Description

@iskng

Describe the bug
devicectl::parse_device_list() is deserializing assuming "cpuType" on all devices but devicectl doesn't output one for apple watch.

Causes:
thread 'apple::device::devicectl::device_list::tests::test_parse_device_list' panicked at src/apple/device/devicectl/device_list.rs:405:47:
Failed to parse device list: InvalidDeviceList(Error("missing field cpuType", line: 261, column: 9))

Steps To Reproduce
Steps to reproduce the behavior. It must use cargo-mobile2 itself and wry template directly instead of tauri-cli.
Have an apple watch paired to xcode and an iphone 15+ with ios 17+
pnpm tauri dev --host (yep read the above)

Add this test to src/apple/device/devicectl/device_list.rs
Its a slimmed down version of my devicectl output.

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_parse_device_list() {
        let json =
            r#"{
  "info" : {
    "arguments" : [
      "devicectl",
      "list",
      "devices",
      "--json-output",
      "/Users/arst/arst/arst/arst/arst/devicelist.json"
    ],
    "commandType" : "devicectl.list.devices",
    "environment" : {
      "TERM" : "xterm-256color"
    },
    "jsonVersion" : 2,
    "outcome" : "success",
    "version" : "355.28"
  },
  "result" : {
    "devices" : [
      {
        "capabilities" : [
          {
            "featureIdentifier" : "Cryptex1",
            "name" : "com.apple.security.cryptexd.remote"
          },
          {
            "featureIdentifier" : "com.apple.coredevice.feature.getdeviceinfo",
            "name" : "Fetch Extended Device Info"
          }
        ],
        "connectionProperties" : {
          "authenticationType" : "manualPairing",
          "isMobileDeviceOnly" : false,
          "lastConnectionDate" : "2024-10-26T04:57:34.972Z",
          "localHostnames" : [
            "PhoneName.coredevice.local",
            "arstasrt-arstasrtastasrt.coredevice.local",
            "arstarstas-arst-arst-arst-arstasrtasrt.coredevice.local"
          ],
          "pairingState" : "paired",
          "potentialHostnames" : [
            "arstarst-arstasrtasrtarstas.coredevice.local",
            "arstarst-arst-arst-arst-arstarstasrt.coredevice.local"
          ],
          "transportType" : "wired",
          "tunnelIPAddress" : "fda8:33d4:a882::1",
          "tunnelState" : "connected",
          "tunnelTransportProtocol" : "tcp"
        },
        "deviceProperties" : {
          "bootedFromSnapshot" : true,
          "bootedSnapshotName" : "com.apple.os.update-arstarstarstarstarstarstarstarstarstarstarstasrtarstasrars",
          "bootState" : "booted",
          "ddiServicesAvailable" : true,
          "developerModeStatus" : "enabled",
          "hasInternalOSBuild" : false,
          "name" : "Fown",
          "osBuildUpdate" : "21G93",
          "osVersionNumber" : "17.6.1",
          "rootFileSystemIsWritable" : false,
          "screenViewingURL" : "coredevice-devices:/viewDeviceByUUID?uuid=arstarst-arst-arst-arst-arstarstarst"
        },
        "hardwareProperties" : {
          "cpuType" : {
            "name" : "arm64",
            "subType" : 2,
            "type" : 16777228
          },
          "deviceType" : "iPhone",
          "ecid" : 123412341324123,
          "hardwareModel" : "D83AP",
          "internalStorageCapacity" : 1024000000000,
          "isProductionFused" : true,
          "marketingName" : "iPhone 15 Pro",
          "platform" : "iOS",
          "productType" : "iPhone16,1",
          "reality" : "physical",
          "serialNumber" : "arstarstars",
          "supportedCPUTypes" : [
            {
              "name" : "arm64e",
              "subType" : 2,
              "type" : 16777228
            },
            {
              "name" : "arm64",
              "subType" : 0,
              "type" : 16777228
            },
            {
              "name" : "arm64",
              "subType" : 1,
              "type" : 16777228
            },
            {
              "name" : "arm64_32",
              "subType" : 1,
              "type" : 33554444
            }
          ],
          "supportedDeviceFamilies" : [
            1
          ],
          "thinningProductType" : "iPhone16,1",
          "udid" : "arstarsta-arstasrtarstas"
        },
        "identifier" : "arstarsta-arsa-arsta-arst-arstarstarst",
        "visibilityClass" : "default"
      },
      {
        "capabilities" : [
          {
            "featureIdentifier" : "com.apple.coredevice.feature.unpairdevice",
            "name" : "Unpair Device"
          }
        ],
        "connectionProperties" : {
          "authenticationType" : "manualPairing",
          "isMobileDeviceOnly" : false,
          "pairingState" : "paired",
          "potentialHostnames" : [
            "arstarstar-starstasrtasrt.coredevice.local",
            "arstarstasrtars-tarstasrtastasrt.coredevice.local"
          ],
          "tunnelState" : "unavailable"
        },
        "deviceProperties" : {
          "ddiServicesAvailable" : false,
          "name" : "Frank’s Apple Watch"
        },
        "hardwareProperties" : {
          "deviceType" : "appleWatch",
          "ecid" : 1234132411234,
          "platform" : "watchOS",
          "productType" : "Watch7,5",
          "udid" : "arstarstarst"
        },
        "identifier" : "arstarstast-arstarstarst-arstarst",
        "visibilityClass" : "default"
      }
    ]
  }
}
"#.to_string();

        let devices = parse_device_list(json).expect("Failed to parse device list");

        // Should only get one device since the other has tunnelState: "unavailable"
        assert_eq!(devices.len(), 1, "Expected exactly one device");

        let device = devices.iter().next().unwrap();
        assert_eq!(device.name(), "Fown");
        assert_eq!(device.model(), "iPhone16,1");
        assert_eq!(device.kind(), DeviceKind::DeviceCtlDevice);
    }
}

Expected behavior
Should be able to parse the list regardless of other devices in the Run Destinations
lazy fix is unpair watch or filter_map an Option but haven't checked if an apple tv or other platforms are different

Platform and Versions (please complete the following information):
Host OS: Mac 14.5
Target OS: IOS 17.6.1
Rustc: 1.82

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions