iOS) KakaoQRcode 클론코딩 - shake motion event(2/2) - CMMotionManager

3 minute read

내용

  • 카카오톡에서 두번 흔들면 qr 코드 뷰를 띄어주는 기능 클론코딩

두가지 방법에 대해서 알아볼 것이다.

  1. UIResponder 의 motion event 메서드를 재정의해서 사용
  2. CoreMotion Framework 사용

2️⃣ CoreMotion Framework 사용

시작 전

👏 원리

  • motion service 를 관리하는 CMMotionManager 를 활용.

👏 CMMotionManager

[CMMotionManager](https://developer.apple.com/documentation/coremotion/cmmotionmanager) 객체를 사용하여 장치의 온보드 센서에서 감지한 움직임을 보고하는 서비스를 시작합니다. 이 객체를 사용하여 4가지 유형의 모션 데이터를 수신합니다.

  • Accelerometer data, indicating the instantaneous acceleration of the device in three dimensional space.
  • Gyroscope data, indicating the instantaneous rotation around the device’s three primary axes.
  • Magnetometer data, indicating the device’s orientation relative to Earth’s magnetic field.
  • Device-motion data, indicating key motion-related attributes such as the device’s user-initiated acceleration, its attitude, rotation rates, orientation relative to calibrated magnetic fields, and orientation relative to gravity. This data is provided by Core Motion’s sensor fusion algorithms.

지정된 update intervals 로 센서 데이터를 수신하거나 센서가 데이터를 수집하고 나중에 검색하기 위해서 저장하도록 할수도 있다. 이 두가지 방법은 데이터가 더이상 필요없을 때 적절한 중지 메서드를 호출한다(stopAccelerometerUpdates(), stopGyroUpdates(), stopMagnetometerUpdates()stopDeviceMotionUpdates())

특정 intervals 로 motion 업데이트 처리

데이터를 수신하기 위해서 앱은 OperationQueue 의 인스턴스와 이러한 업데이트를 처리하기 위한 block handler 를 사용하는 start 메서드를 호출한다. 모션 데이터는 block handler 로 전달된다. 업데이트의 빈도는 interval 프로퍼티를 통해서 결정된다.

Motion Data 의 주기적 샘플링

주기적 샘플링으로 모션 데이터를 처리하기 위해서 앱은 argument 가 없는 start 메서드를 호출합니다. 그리고 지정된 모션 데이터 유형의 프로퍼티가 가진 모션 데이터에 주기적으로 접근한다. 이 접근 방식은 게임과 같은 앱에서 권장되는 접근방식이다.

accererometer data 를 block 에서 처리하면 오버헤드가 발생하고 대부분의 게임 앱은 프레임을 렌더링할 때 모션 데이터의 최신 샘플에만 관심이 있습니다.

Hardware Availability and State

hardware 기능(ex. gyroscope) 을 장치에서 사용할 수 없는 경우 해당기능과 관련된 start 메서드를 호출해도 효과가 없다. 적당한 프로퍼티로 하드웨어 기능이 사용가능하거나 활성화되어있는지 확인 할 수 있다.

device-motion 서비스의 경우, isDeviceMotionAvailable, isDeviceMotionActive 프로퍼티의 값을 체크해서 확인 가능하다.

시작하기

우리는 Device-motion data 를 수신해서 사용해보도록 하겠다.

  • MainViewController.swift
import UIKit
import SnapKit
// ✅ CMMotionMager 를 사용하기 위해서 import
import CoreMotion

class MainViewController: UIViewController {

// ...

    // MARK: - View Life Cycle

    override func viewDidLoad() {
        super.viewDidLoad()
        configUI()
        setLayout()

        // CMMotionManager 로 motion 을 캡쳐할 것이다
        let coreMotionManager = CMMotionManager()
        getDeviceMotion(coreMotionMager: coreMotionManager)
    }
}

// MARK: - Extensions

extension MainViewController {

    private func configUI(){
        // ...
    }

    private func setLayout() {
        // ...
    }

    @objc
    private func presentToQRCodeVC() {
        let nextVC = QRCodeViewController()
        nextVC.modalPresentationStyle = .overFullScreen
        present(nextVC, animated: true, completion: nil)

    }

// ✅ **shake motion detect with CMMotionMager**

    private func getDeviceMotion(coreMotionMager: CMMotionManager) {
        if coreMotionMager.isDeviceMotionAvailable {
            coreMotionMager.deviceMotionUpdateInterval = 1
            coreMotionMager.startDeviceMotionUpdates(to: .main
            ) { _, _  in
                print("shake")
                // qrcode 뷰가 dismiss 되더라도 motion은 계속 update 되야하기 때문에 stop 메서드를 주석처리해주었다.
//                coreMotionMager.stopDeviceMotionUpdates()
                self.presentToQRCodeVC()
            }
        }
    }
}

출처 :

iOS ShakeGesture

깃허브

GitHub - 28th-SOPT-iOS-CloneCoding/MiraClone-KimHyunGyu: 🧚 아요 미라클론코딩 김현규

Categories:

Updated: