require 'cfpropertylist'
require 'ostruct'
require 'simctl/device_path'
require 'simctl/device_settings'
require 'simctl/object'
require 'timeout'
module SimCtl
class Device < Object
attr_reader :availability, :name, :os, :state, :udid
# Boots the device
#
# @return [void]
def boot!
SimCtl.boot_device(self)
end
# Deletes the device
#
# @return [void]
def delete!
SimCtl.delete_device(self)
end
# Returns the device type
#
# @return [SimCtl::DeviceType]
def devicetype
@devicetype ||= SimCtl.devicetype(identifier: plist.deviceType)
end
# DEPRECATED: Please use device.settings.disable_keyboard_helpers! instead.
# Disables the keyboard helpers
#
# @return [void]
def disable_keyboard_helpers!
settings.disable_keyboard_helpers!
end
# Erases the device
#
# @return [void]
def erase!
SimCtl.erase_device(self)
end
# Installs an app on a device
#
# @param path Absolute path to the app that should be installed
# @return [void]
def install!(path)
SimCtl.install_app(self, path)
end
# Kills the device
#
# @return [void]
def kill!
SimCtl.kill_device(self)
end
# Launches the Simulator
#
# @return [void]
def launch!(scale=1.0, opts={})
SimCtl.launch_device(self, scale, opts)
end
# Launches an app in the given device
#
# @param opts [Hash] options hash - `{ wait_for_debugger: true/false }`
# @param identifier [String] the app identifier
# @param args [Array] optional launch arguments
# @return [void]
def launch_app!(identifier, args=[], opts={})
SimCtl.launch_app(self, identifier, args, opts)
end
def path
@path ||= DevicePath.new(udid)
end
# Renames the device
#
# @return [void]
def rename!(name)
SimCtl.rename_device(self, name)
end
# Resets the device
#
# @return [void]
def reset!
SimCtl.reset_device name, devicetype, runtime
end
# Resets the runtime
#
# @return [SimCtl::Runtime]
def runtime
@runtime ||= SimCtl.runtime(identifier: plist.runtime)
end
# Returns the settings object
#
# @ return [SimCtl::DeviceSettings]
def settings
@settings ||= DeviceSettings.new(path)
end
# Shuts down the runtime
#
# @return [void]
def shutdown!
SimCtl.shutdown_device(self)
end
# Returns the state of the device
#
# @return [sym]
def state
@state.downcase.to_sym
end
# Reloads the device until the given block returns true
#
# @return [void]
def wait!(timeout=SimCtl.default_timeout)
Timeout::timeout(timeout) do
loop do
break if yield SimCtl.device(udid: udid)
end
end
end
def ==(other)
return false if other.nil?
return false unless other.kind_of? Device
other.udid == udid
end
private
def plist
@plist ||= OpenStruct.new(CFPropertyList.native_types(CFPropertyList::List.new(file: path.device_plist).value))
end
end
end