iPhone
iPod touch
model identification
duplicate article
device detection

Detect the specific iPhone/iPod touch model

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you need the exact iPhone or iPod touch model, UIDevice.current.model is not enough because it only gives a generic label such as iPhone. The usual solution is to read the low-level machine identifier, map it to a friendly model name, and still keep capability checks separate from model checks.

Read the Machine Identifier

The system exposes a hardware identifier such as iPhone14,2 or iPod9,1. You can read it with uname.

swift
1import UIKit
2
3func machineIdentifier() -> String {
4    var systemInfo = utsname()
5    uname(&systemInfo)
6
7    let mirror = Mirror(reflecting: systemInfo.machine)
8    return mirror.children.reduce("") { partial, element in
9        guard let value = element.value as? Int8, value != 0 else { return partial }
10        return partial + String(UnicodeScalar(UInt8(value)))
11    }
12}
13
14print(machineIdentifier())

That identifier is the stable technical value you should store if you need exact hardware detection.

Map the Identifier to a Friendly Name

Human-friendly model names come from your own lookup table.

swift
1func modelName(from identifier: String) -> String {
2    let map: [String: String] = [
3        "iPhone14,2": "iPhone 13 Pro",
4        "iPhone15,2": "iPhone 14 Pro",
5        "iPod9,1": "iPod touch (7th generation)",
6        "x86_64": "Simulator",
7        "arm64": "Simulator"
8    ]
9
10    return map[identifier] ?? identifier
11}

If a device is unknown, returning the raw identifier is safer than crashing or pretending you know the exact model.

Simulator Handling

Simulator values deserve special handling because the runtime may report x86_64 or arm64 instead of a real device model. If you want the simulated hardware identifier, read the simulator environment value.

swift
let simulated = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"]
print(simulated ?? "not running in simulator")

This is useful when testing model-specific flows locally.

Capability Checks Are Often Better

A common mistake is using exact model detection for feature logic when a capability check would be more future-proof. For example, if the real question is whether a device supports a camera API, biometrics feature, or another hardware capability, check that capability directly instead of maintaining model-name conditions forever.

Model detection is most useful for:

  • analytics
  • diagnostics
  • support tooling
  • temporary rollout rules

Capability checks are usually better for runtime behavior.

Keep the Logic Centralized

Do not scatter identifier mapping across view controllers. Put it in one reusable helper so future device additions happen in one place.

swift
1struct DeviceInfo {
2    let identifier: String
3    let modelName: String
4}
5
6func currentDeviceInfo() -> DeviceInfo {
7    let identifier = machineIdentifier()
8    return DeviceInfo(
9        identifier: identifier,
10        modelName: modelName(from: identifier)
11    )
12}

That also makes telemetry and testing easier.

For analytics and support tooling, it is often useful to store both the raw identifier and the friendly mapped name. The raw identifier survives future remapping improvements, while the friendly name is easier for dashboards and support teams to read immediately. That dual storage pattern makes hardware telemetry much easier to maintain over time.

Common Pitfalls

  • Expecting UIDevice.current.model to provide an exact hardware model.
  • Hard-failing when a new identifier appears instead of falling back safely.
  • Using model checks where capability checks would be more robust.
  • Forgetting simulator-specific identifier behavior.
  • Letting the mapping table go stale as new hardware ships.

Summary

  • Exact iPhone or iPod detection uses the machine identifier, not the generic model string.
  • Map that identifier to a friendly device name with your own lookup table.
  • Handle simulators and unknown identifiers gracefully.
  • Prefer capability checks over model checks for most runtime feature decisions.
  • Keep detection logic centralized so it stays maintainable.

Course illustration
Course illustration

All Rights Reserved.