Знакомство с вашим устройством iOS: краткое руководство по получению информации об устройстве

Информация об устройстве — очень полезные данные в любом мобильном приложении. Его можно использовать для наблюдения за состоянием батареи, уровнем громкости, яркостью и т. д., а также для уведомления пользователей об изменении некоторых из этих значений. Например, в приложении для доставки еды можно показывать оповещение, если уровень громкости слишком низкий, чтобы курьер не пропустил уведомления о новых заказах. Почти каждое приложение использует информацию об устройстве для аналитики. Это помогает быть в курсе того, какая версия iOS у пользователей и какие устройства они используют. Такие данные могут быть полезны, если вы хотите обновить минимальную версию iOS вашего приложения.

Чтобы получить информацию об устройстве, вы можете использовать класс UIDevice, который предоставляет информацию о текущем устройстве и состоянии его батареи. Другие данные, такие как уровень громкости или яркость, хранятся в других классах. В этой статье я покажу, какие данные можно получить с помощью нативного API, предоставляемого Apple. И мы рассмотрим одну замечательную стороннюю библиотеку, которая помогает легко получить информацию об устройстве.

UIDevice

UIDevice — это класс из собственной библиотеки UIKit. Он может предоставить вам информацию о вашем телефоне, такую ​​как его имя, версия ОС, модель, уровень заряда батареи и состояние, уровень близости и ориентация. Это также дает вам возможность управлять уведомлениями о батарее, приближении и ориентации.

Чтобы получить доступ ко всей этой информации, вам необходимо сначала получить доступ к вашему текущему устройству. Этого можно добиться с помощью свойства класса current класса UIDevice.

UIDevice.current

Чтобы получить информацию о текущем устройстве, его модели, ОС и версии ОС, вы можете использовать следующие свойства:

  UIDevice.current.name
  UIDevice.current.model
  UIDevice.current.systemName
  UIDevice.current.systemVersion

UIDevice.current.name представляет имя устройства, для iOS 15 и более ранних версий он возвращает назначенное пользователем имя устройства, например "Artem’s iPhone 13 Pro" Макс. Для iOS 16.0 и более поздних версий он возвращает общее имя, например “iPhone”или “iPad”.

UIDevice.current.model представляет тип текущего устройства. Для любого iPhone это будет “iPhone”, для iPad — “iPad” и так далее. Если вам нужна более конкретная информация, например “iPhone 13 Pro Max”, вам нужно использовать другой подход. Мы поговорим об этом позже в этой статье.

UIDevice.current.systemName представляет ОС, работающую на текущем устройстве, например, для любого iPhone это будет “iOS”. UIDevice.current.systemVersion представляет версию ОС, например 16.2.

Информация о батарее

UIDevice также предоставляет нам информацию о батарее. Во-первых, необходимо включить isBatteryMonitoringEnabled, если вы хотите получить информацию о батарее. Вы можете включить его, просто установив его значение на true.

UIDevice.current.isBatteryMonitoringEnabled = true

Чтобы получить текущий уровень заряда батареи, можно использовать свойство batteryLevel. Он возвращает значение в диапазоне от 0 до 1,0, поэтому вам нужно умножить его на 100, если вы хотите получить процентное значение. Если isBatteryMonitoringEnabled ложно, вы получите -1.0.

Свойство batteryState представляет текущее состояние батареи устройства. Это перечисление с 4 возможными случаями:

  • unknown Невозможно определить состояние батареи устройства;
  • unplugged Устройство не подключено к сети; батарея разряжается;
  • charging Устройство подключено к сети, а батарея заряжена менее чем на 100%;
  • full Устройство подключено к сети, а аккумулятор заряжен на 100 %.

Кроме того, UIDevice имеет два уведомления, позволяющих нам наблюдать за изменением уровня заряда батареи и состояния. Это UIDevice.batteryLevelDidChangeNotification и UIDevice.batteryStateDidChangeNotification соответственно. Вы можете настроить наблюдателей с помощью NotificationCenter следующим образом:

  NotificationCenter.default.addObserver(self,
              selector: #selector(didChangeBatteryLevel(_:)),
              name: UIDevice.batteryLevelDidChangeNotification,
              object: nil)
  
  NotificationCenter.default.addObserver(self,
              selector: #selector(didСhangeBatteryState(_:)),
              name: UIDevice.batteryStateDidChangeNotification,
              object: nil)

  @objc private func didChangeBatteryLevel(_ notification: Notification) {
    // Check battery level and perform some actions
  }
  
  @objc private func didСhangeBatteryState(_ notification: Notification) {
    // Check battery state and perform some actions
  }

Ориентация

Последнее свойство из UIDevice, о котором мы сегодня поговорим, — это ориентация устройства. Существует перечисление UIDeviceOrientation с 6 возможными случаями:

  • unknown Ориентация устройства не может быть определена;
  • portrait Устройство находится в портретном режиме, устройство находится в вертикальном положении, а фронтальная камера направлена ​​вверх;
  • portraitUpsideDown Устройство находится в портретном режиме, но перевернуто, при этом устройство удерживается вертикально, а фронтальная камера находится внизу;
  • landscapeLeft Устройство находится в ландшафтном режиме, устройство находится в вертикальном положении, а фронтальная камера находится слева;
  • landscapeRight Устройство находится в ландшафтном режиме, устройство находится в вертикальном положении, а фронтальная камера расположена справа;
  • faceUp Устройство держите параллельно земле экраном вверх;
  • faceDown Устройство держите параллельно земле экраном вниз.

Чтобы получить текущую ориентацию устройства, вы можете использовать свойство orientation файла UIDevice. UIDeviceOrientation также имеет набор логических свойств, помогающих определить текущую ориентацию. Это isFlat, isPortrait и isLandscape. Вот пример:

  UIDevice.current.orientation
  UIDevice.current.orientation.isFlat
  UIDevice.current.orientation.isPortrait
  UIDevice.current.orientation.isLandscape

Как и в случае с батареей, мы можем наблюдать за изменением ориентации с помощью уведомления orientationDidChangeNotification. Но чтобы иметь возможность получать уведомления, нам нужно сначала включить эту функцию. Для этого вам нужно использовать метод beginGeneratingDeviceOrientationNotifications(). Чтобы прекратить создание уведомлений об ориентации, используйте метод endGeneratingDeviceOrientationNotifications().

  UIDevice.current.beginGeneratingDeviceOrientationNotifications()
  
  NotificationCenter.default.addObserver(self,
              selector: #selector(didСhangeOrientation(_:)),
              name: UIDevice.orientationDidChangeNotification,
              object: nil)
  
  // Call when you don't need orientation notifications
  UIDevice.current.beginGeneratingDeviceOrientationNotifications()

  @objc private func didСhangeOrientation(_ notification: Notification) {
    // Check orientation and perform some actions
  }

Яркость

Чтобы получить текущую яркость устройства и возможность наблюдать за ее изменениями, вам нужно использовать класс UIScreen и его свойства и уведомления. Чтобы получить текущую яркость устройства, вам нужно использовать свойство brightness. Также есть уведомление об изменении яркости UIScreen.brightnessDidChangeNotification.

  UIScreen.main.brightness
  
  NotificationCenter.default.addObserver(self,
              selector: #selector(didСhangeBrightness(_:)),
              name: UIScreen.brightnessDidChangeNotification,
              object: nil)

  @objc private func didСhangeBrightness(_ notification: Notification) {
    // Check brightness and perform some actions
  }

Модель маркетинга устройств

Под маркетинговой моделью устройства я подразумеваю что-то вроде iPhone 12 Pro Max или iPhone 8 Plus. UIDevice таких данных нам не предоставляет, но способ их получить все же есть. Используя родной iOS SDK, мы можем использовать текущий код устройства. Код устройства не равен маркетинговой модели, но когда у нас есть код, мы можем сопоставить его с маркетинговой моделью. Используя следующую функцию, вы можете получить текущий код устройства:

func getDeviceCode() -> String? {
    var systemInfo = utsname()
    uname(&systemInfo)
    let modelCode = withUnsafePointer(to: &systemInfo.machine) {
        $0.withMemoryRebound(to: CChar.self, capacity: 1) {
            ptr in String.init(validatingUTF8: ptr)
        }
    }
    return modelCode
}

Если вы запустите эту функцию на симуляторе, вы получите одно из следующих значений: “i386”, “x86_64” или “arm64”. А на реальном устройстве вы получите код устройства. У меня 2 рабочих устройства и одно личное. Для моего рабочего устройства iPhone 12 код устройства — “iPhone13,2”, для iPhone 7 Plus — “iPhone9,4”, а для iPhone XS Max — “iPhone11,6”. Как видите, код устройства немного сбивает с толку. Единственный способ сопоставить код устройства с маркетинговой моделью — это иметь жестко закодированный словарь со всеми кодами устройств и маркетинговыми моделями для них. Если вы не хотите жестко кодировать его самостоятельно, вы можете использовать стороннюю библиотеку DeviceKit. Давайте посмотрим на это.

Комплект устройств

DeviceKit — это легкая сторонняя библиотека, которая позволяет легко получить информацию об устройстве и его свойствах. Вот ссылка на его репозиторий GitHub.

Это позволяет вам получить модель устройства, состояние батареи, яркость, доступное место на диске и другую дополнительную информацию о вашем устройстве. Если вы проверите ее исходный код, вы обнаружите, что большинство значений жестко закодированы, но это популярная и надежная библиотека. Он имеет более 4000 звезд на GitHub и всегда обновляется, поэтому смело используйте его в своем проекте, если хотите получить всю информацию о своем устройстве из одного места.

DeviceKit использует перечисление для типов устройств, и это перечисление называется Device. Вы можете получить доступ к своему текущему устройству через Device.current. Поскольку Device является перечислением, вы можете легко использовать его с оператором == в блоках if-else или в операторах switch.

  let currentDevice = Device.current
  
  if currentDevice == .iPhone12Pro {
   // Do something
  }
  
  switch currentDevice {
  case .iPhone12:
   //Do something
  case .iPhone4, .iPhone5:
   //Do something
  default:
   //Do something
  }

Дает возможность определить семейство устройств и симулятор это или нет. Кроме того, если текущее устройство является симулятором, вы можете определить, что это за симулятор.

  if currentDevice.isPod {
    // iPods (real or simulator)
  } else if currentDevice.isPhone {
    // iPhone (real or simulator)
  } else if currentDevice.isPad {
    // iPad (real or simulator)
  }
  
  if currentDevice.isSimulator {
   // Do something for simulator
  }
  
  if case .simulator(.iPhone12) = currentDevice {
   // Do something for iPhone 12 simulator
  }

Информация о батарее также предоставляется файлом DeviceKit. Чтобы получить уровень заряда батареи, вы можете использовать свойство batteryLevel. DeviceKit использует Int вместо Float для уровня заряда батареи, поэтому нет необходимости умножать его значение на 100, чтобы получить значение в процентах.

currentDevice.batteryLevel

Вы можете получить текущее состояние батареи, DeviceKit имеет перечисление BatteryState, которое предоставляет вам больше данных, чем перечисление UIDevice batteryState по умолчанию.

 switch currentDevice.batteryState {
    case .full:
        print("Your dive is fully charged")
    case .charging(let batteryLevel):
        print("Device is charging, currently at \(batteryLevel)%")
    case .unplugged(let batteryLevel):
        print("The device is not plugged into power; currently at \(batteryLevel)%")
    default:
        break
 }

BatteryState enum имеет логическое свойство lowPowerMode, которое определяет, когда включен режим пониженного энергопотребления.

 if currentDevice.batteryState.lowPowerMode {
    print("Low Power mode is enabled")
 } else {
    print("Low Power mode is disabled")
 }

DeviceKit также содержит информацию о текущей яркости. Прелесть в том, что вам не нужно использовать UIScreen для яркости. С DeviceKit все данные, связанные с устройством, хранятся в одном месте. Чтобы получить яркость, вам нужно получить доступ к свойству screenBrightness. Как и batteryLevel, это свойство является Int.

 if currentDevice.screenBrightness > 50 {
    print("Take care of your eyes!")
 }

В этом последнем абзаце мы рассмотрим свойства, которые представляют дисковое пространство. Они есть:

  • volumeTotalCapacity — общая емкость тома в байтах;
  • volumeAvailableCapacity доступная емкость тома в байтах;
  • volumeAvailableCapacityForImportantUsage доступная емкость тома в байтах для хранения важных ресурсов;
  • volumeAvailableCapacityForOpportunisticUsage — доступная емкость тома в байтах для хранения второстепенных ресурсов.

Эти данные можно использовать, когда вам нужно проверить доступное место на диске перед загрузкой большого количества данных.

DeviceKit предоставляет намного больше данных, чем я упомянул в этой статье. Он предоставляет информацию о поддержке Apple Pencil, камере, тепловом состоянии, процессоре, ppi и т. д. Но для меня главное преимущество заключается в том, что все данные хранятся в одном месте и доступны через Device.current.

Информация об устройстве — очень полезная информация в каждом приложении для iOS, и каждый должен знать, как ее получить. Ссылки на все ресурсы вы найдете ниже.

Ресурсы

Apple Documentation: UIDevice class
Apple Documentation: UIScreen class
DeviceKit GitHub repository

Спасибо за ваше время. Я надеюсь, что вы нашли эту статью полезной. Не стесняйтесь поделиться своим мнением в комментариях.

Check out my other articles about iOS Development

https://medium.com/@artem.khalilyaev

Повышение уровня кодирования

Спасибо, что являетесь частью нашего сообщества! Перед тем, как ты уйдешь:

  • 👏 Хлопайте за историю и подписывайтесь на автора 👉
  • 📰 Смотрите больше контента в публикации Level Up Coding
  • 💰 Бесплатный курс собеседования по программированию ⇒ Просмотреть курс
  • 🔔 Подписывайтесь на нас: Twitter | ЛинкедИн | "Новостная рассылка"

🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите прекрасную работу