Retrieve the iOS Simulator UDID

In order to reset my app application between tests (without reseting the whole simulator because that makes the tests real slow) - I want to delete the NSUserDefaults plist for my application.

The .plist is found here:

/Users//Library/Developer/CoreSimulator/Devices//data/Containers/Data/Application//Library/Preferences/com.xyz.plist

I want to run a shell script from inside my tests that deletes that file. The issues is that I need the SimulatorId in order to delete that file.

Any way to retrieve that?
Or is there any other way to reset your whole’s app state between tests without resetting the contents of the simulator - and thus making it really slow?

Thank you,
Cosmin

I do it by making a system call to instruments, executing the, ‘instruments -s devices’ command and then parsing the results based on the name of the simulator.

So in Ruby, something like:

def find_uuid(device_name)
  devices = `/usr/bin/instruments -s devices`
  device_list = devices.split("\n")
  device_list.each do |device|
    match_data = /(?<device_name>.*) \((?<os>.*)\) \[(?<uuid>.*)\]/.match(device)
    next if match_data.nil?
    next unless match_data[:device_name].eql? device_name
    return match_data[:uuid]
  end
end

By creating a simple file, ‘find_uuid.rb’ with a few extra parameters:

#!/usr/bin/ruby

device_name = ARGV[0]

def find_uuid(device_name)
  devices = `/usr/bin/instruments -s devices`
  device_list = devices.split("\n")
  device_list.each do |device|
    match_data = /(?<device_name>.*) \((?<os>.*)\) \[(?<uuid>.*)\]/.match(device)
    next if match_data.nil?
    next unless match_data[:device_name].eql? device_name
    return match_data[:uuid]
  end
end

puts find_uuid(device_name)

I get the following output from inputting a Simulator name I have:

ruby find_uuid.rb 'iPhone4s_9.3'
401E72EB-D3C7-4390-9FEB-40374092461C

NOTE: This script is usable for real devices or simulators.

Thanks for the help.

What I’ve ended up doing though is writing the following Java piece of code that clears the NSUserDefaults for all installed simulators (since I don’t run any tests in parallel on multiple simulators):

private void clearIosUserDefaults() {
    try {
        String user = System.getenv("USER");
        String removeUserDefaultsCommand = "find /Users/" + user + "/Library/Developer/CoreSimulator/Devices/ -path \"*/Preferences/com.mycompany.myapp.plist*\" -exec rm -rf {} \\;";
        String[] shellCommand = new String[] {"/bin/sh", "-c", removeUserDefaultsCommand };

        Runtime.getRuntime().exec(shellCommand);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

So far locally everything works great, hopefully I won’t run into permissions issues when I run this on Jenkins.

I also have a method that launches the application with clear local data:

public void launchAppWithClearedData() {
    if (Platform.isOnIOS()) {
        clearIosUserDefaults();
    }

    getDriver().launchApp();
}

This is kind of related to a different question that I’ve asked last week:

Now, using a @Before hook, all I do is call launchAppWithClearedData and my app always runs from a well know state for each test (scenario).

Is there a way to reset the NSUserDefaults on a real iOS device?