Skip to content
This repository has been archived by the owner on Jun 23, 2023. It is now read-only.

Latest commit

 

History

History
259 lines (208 loc) · 8.42 KB

[15-1]200210_UIDevice.md

File metadata and controls

259 lines (208 loc) · 8.42 KB

UIDevice

  • UIDevice를 통해 다음 정보를 확인할 수 있다.
    • Device 이름, 모델, 화면 방향 등
    • OS 이름, 버전
    • Interface 형식(iPhone, iPad, appleTV 등)
    • 배터리 정보
    • 근접 센서 정보
    • 멀티태스킹 지원 여부

Target Conditionals

  • 0(false) or 1(true)
  • 현재 target device에 대한 상태 정보 확인

TARGET_CPU

  • TARGET_CPU_X86 : Compiler is generating x86 instructions for 32-bit mode
  • TARGET_CPU_X86_64 : Compiler is generating x86 instructions for 64-bit mode
  • TARGET_CPU_ARM : Compiler is generating ARM instructions for 32-bit mode
  • TARGET_CPU_ARM64 : Compiler is generating ARM instructions for 64-bit mode

TARGET_OS

  • TARGET_OS_MAC : Generated code will run under Mac OS X variant
    • TARGET_OS_OSX : Generated code will run under OS X devices
    • TARGET_OS_IPHONE : Generated code for firmware, devices, or simulator
      • TARGET_OS_IOS : Generated code will run under iOS
      • TARGET_OS_TV, TARGET_OS_WATCH, TARGET_OS_BRIDGE, TARGET_OS_MACCATALYST
    • TARGET_OS_SIMULATOR : Generated code will run under a simulator

System

let device = UIDevice.current
device.systemName								// OS 이름(iOS)
device.systemVersion						// OS 버전(13.3.1)
device.name											// Settings에서 설정한 이름(cskim's iPhone)
device.model										// Device model(iPhone)
device.localizedModel						// model 값을 포함하는 model 설명
device.userInterfaceIdiom				// 현재 device에 사용되는 style(pphone, pad, ...)
device.orientation							// 화면 회전 방향(portrait, landscape)
device.isMultitaskingSupported	// 멀티태스킹 가능 여부. 

Battery

  • Device의 현재 배터리 상태 확인

    let device = UIDevice.current
    device.batteryState		// unknown, unplugged, charge, full
    device.batteryLevel		// 0.0 ~ 1.0. -1.0 when state is unknown
  • Battery 상태를 확인하기 위해 device가 배터리를 모니터링하도록 설정해야 함. 사용하지 않을 때는 isBatteryMonitoringEnabled 속성을 false로 전환해서 기능을 꺼야한다.

    @objc func batteryMonitoring(_ sender: UIButton) {
      device.isBatteryMonitoringEnabled.toggle()
    
      if device.isBatteryMonitoringEnabled {
        NotificationCenter.default.addObserver(
          self,
          selector: #selector(didChangeBatteryState(_:)),
          name: UIDevice.batteryStateDidChangeNotification,
          object: nil
        )
      } else {
        NotificationCenter.default.removeObserver(
          self,
          name: UIDevice.batteryStateDidChangeNotification,
          object: nil
        )
      }
    }
  • NotifcationCenter에 등록된 method를 통해 배터리 상태가 변경될 때 마다 해당 정보를 가져옴

    @objc func didChangeBatteryState(_ noti: Notification) {
      guard let device = noti.object as? UIDevice else { return }
      print("batteryState :", device.batteryState)
      print("batteryLevel :", device.batteryLevel)
    }

Proximity State

  • Device의 근접 센서 상태 확인

    let device = UIDevice.current
    device.proximityState		// 근접센서에 감지되면 true
  • 근접 센서 작동을 위해 device가 근접 센서 상태를 모니터링하도록 설정해야 함. 사용하지 않을 때는 isProximityMonitoringEnabled를 false로 전환해서 기능을 꺼야 한다.

    @objc func proximityMonitoring(_ sender: UIButton) {
      device.isProximityMonitoringEnabled.toggle()
      
      if device.isProximityMonitoringEnabled {
        NotificationCenter.default.addObserver(
          self,
          selector: #selector(didChangeProximityState(_:)),
          name: UIDevice.proximityStateDidChangeNotification,
          object: nil
        )
      } else {
        NotificationCenter.default.removeObserver(
          self,
         	name: UIDevice.proximityStateDidChangeNotification,
          object: nil
        )
      }
    }
  • NotifcationCenter에 등록된 method를 통해 근접 센서에 대상이 감지되어 상태가 변경될 때 마다 해당 정보를 가져옴

    @objc func didChangeProximityState(_ noti: Notification) {
      guard let device = noti.object as? UIDevice else { return }
      print("Proximity State :", device.proximityState)
    }

Orientation

  • Device의 방향 정보 확인

    let device = UIDevice.current
    let orientation = device.orientation
    orientation.isPortrait
    orientation.isLandscape
    orientation.isFlat
    orientation.isValidInterfaceOrientation
    • UIDeviceOrientation enum으로 device orientation 상태를 확인할 수 있음

      public enum UIDeviceOrientation: Int {
        case unknown
        case portrait
        case portraitUpsideDown
        case landscapeLeft
        case landscapeRight
        case faceUp
        case faceDown
      }
  • Device 화면의 status bar에 대한 방향 정보.

    let orientation: UIInterfaceOrientation
    
    // iOS 13 이상에서 SceneDelegate을 사용하는 경우
    if #available(iOS 13.0, *) {
      let scene = UIApplication.shared.connected.first
    	orientation = (scene as! SceneDelegate).interfaceOrientation
    } else {
      orientation = UIApplication.shared.statusBarOrientation
    }
    
    orientation.isPortrait
    orientation.isLandscape
    • UIInterfaceOrientation enum으로 statusBar를 기준으로 한 device의 orientation 상태를 확인함

    • Device 상단을 기준으로 statusBar의 위치를 orientation으로 갖는다

    • 노치가 있는 iPhone X 이후로는 upsideDown이 적용되지 않는다. 화면이 뒤집히지 않음

      public enum UIInterfaceOrientation: Int {
        case unknown
        case portrait
        case portraitUpsideDown
        case landscapeLeft
        case landscapeRight
      }
  • Device orientation 상태를 확인하기 위해 orientation의 상태 변경을 모니터링하도록 설정해야함. 사용하지 않을 때는 endGeneratingDeviceOrientationNotifications()를 호출해서 기능을 꺼야 함. isGeneratingDeviceOrientationNotifications 속성으로 확인할 수 있다.

    @objc func beginOrientationNotification() {
      device.beginGeneratingDeviceOrientationNotifications()
      print(device.isGeneratingDeviceOrientationNotifications)	// true
      NotificationCenter.default.addObserver(
        self,
        selector: #selector(orientationDidChange(_:)),
        name: UIDevice.orientationDidChangeNotification,
        object: nil
      )
    }
    
    @objc func orientationDidChange(_ noti: Notification) {
      guard let deivce = noti.object as? UIDevice else { return }
      // SceneDelegate가 생겼을 때 기준
      if #available(iOS 13.0, *) {
        let scene = UIApplication.shared.connectedScenes.first
        let orientation = (scene as! UIWindowScene).interfaceOrientation
        print("Interface Orientation :", orientation)
      } else {
      	let orientation = UIApplication.shared.statusBarOrientation
        print("StatusBar Orientation :", orientation)
      }
    }
    • UIInterfaceOrientationUIDeviceOrientation은 값을 반대로 갖는다. portrait 상태는 둘 다 같지만, device가 landscapeLeft일 때 statusBar는 device 상단 기준 오른쪽에 위치하기 때문에 landscapeRight가 된다.
    • UIInterfaceOrientation은 project setting에서 설정한 [Device Orientation]과 같기 때문에,
  • beginGeneratingDeviceOrientationNotifications()는 여러 번 호출하면 count가 쌓이기 때문에, endGeneratingDeviceOrientationNotifications()도 같은 횟수만큼 호출해서 isGeneratingDDeviceOrientationNotificationsfalse가 되도록 해야 한다.

    @objc func endOrientationNotification() {
      while device.isGeneratingDeviceOrientationNotifications {
        device.endGeneratingDeviceOrientationNotifications()
      }
      NotificationCenter.default.removeObserver(
        self,
        name: UIDevice.orientationDidChangeNotification,
        object: nil
      )
    }

Trick and Tips

  • System version으로부터 Major, minor, bugfix version number 추출

    let version = UIDevice.current.systemVersion
    let splitVersion = version.split(separator: ".").compactMap { Int($0) }
    print(splitVersion)	// [13, 3, 1]
  • 환경변수를 통한 코드 분기

    // Build Phase가 DEBUG / RELEASE일 때를 구분
    #if DEBUG
    #else
    #endif
    
    // 현재 실행 환경이 Simulator / Device일 때를 구분
    #if targetEnvironment(simulator)
    #else
    #elseif