Skip to main content
The Phone class represents a connected iPhone and provides methods for controlling it. You access phones through the TapKitClient.

Getting a Phone

Single Phone

When you have one phone connected, use get_phone():
from tapkit import TapKitClient

client = TapKitClient()
phone = client.get_phone()

print(f"Connected to: {phone.name}")
print(f"Screen: {phone.width}x{phone.height}")
get_phone() raises an error if you have zero or multiple phones. Use list_phones() or phone() for more control.

Multiple Phones

List all available phones:
phones = client.list_phones()

for phone in phones:
    print(f"{phone.name} ({phone.id})")
    print(f"  Screen: {phone.width}x{phone.height}")
    print(f"  Unique ID: {phone.unique_id}")
Get a specific phone by name or ID:
# By name
iphone = client.phone("iPhone 15 Pro")

# By ID
iphone = client.phone("abc123-def456")

Setting a Default Phone

Set a default phone for the client session:
client.use_phone("iPhone 15 Pro")

# Now client-level methods use this phone
client.tap((100, 200))
client.home()

Phone Properties

PropertyTypeDescription
idstrServer-assigned phone ID
namestrDevice name (e.g., “iPhone 15 Pro”)
unique_idstrHardware identifier
widthintScreen width in pixels
heightintScreen height in pixels
screenScreenScreen object for coordinate utilities

Screen Property

Every phone has a screen property with helpful coordinate utilities:
phone = client.get_phone()

# Get screen center
center = phone.screen.center
phone.tap(center)

# Check if point is within bounds
point = Point(100, 200)
if phone.screen.contains(point):
    phone.tap(point)

# Clamp coordinates to valid range
clamped = phone.screen.clamp(Point(-10, 3000))
See Geometry for more screen utilities.

Executing Actions

The Phone object provides methods for all actions:
phone = client.get_phone()

# Touch gestures
phone.tap((100, 200))
phone.double_tap((100, 200))
phone.flick((200, 400), direction="up")

# Device control
phone.home()
phone.lock()
phone.volume_up()

# App control
phone.open_app("Safari")
phone.type_text("Hello world")
All action methods return a Job object with status information:
job = phone.tap((100, 200))

print(f"Job ID: {job.id}")
print(f"Status: {job.status}")  # pending, running, completed, failed
print(f"Created: {job.created_at}")

Phone Resolution

When calling client methods, the SDK resolves which phone to use:
  1. Explicit phone_id - If passed to the method
  2. Client default - Set via use_phone()
  3. Auto-select - If exactly one phone exists
  4. Error - If ambiguous
# These are equivalent when you have one phone:
phone.tap((100, 200))
client.tap((100, 200))
client.tap((100, 200), phone_id=phone.id)

Next Steps