Upgrade to Pro — share decks privately, control downloads, hide ads and more …

15分で分かるCore Motionの全て

15分で分かるCore Motionの全て

@iOSDC 2017 Reject Conference days1

#iOSDCRC

Tatsuya Tanaka

October 13, 2017
Tweet

More Decks by Tatsuya Tanaka

Other Decks in Technology

Transcript

  1. 15෼Ͱ෼͔Δ
    CoreMotionͷશͯ
    @iOSDC 2017 Reject Conference days1
    ాத ୡ໵ (@tattn)

    View Slide

  2. ·ͣ͸͡Ίʹ
    ↑λΠτϧͷdiff͸ͪ͜ΒʹͳΓ·͢
    15෼Ͱ શͯ ͸ݫ͔ͬͨ͠Ͱ͢
    - શͯ
    + watchҎ֎ͷ΄΅શͯ

    View Slide

  3. • Yahoo!৐׵Ҋ಺
    • iOSΞϓϦΤϯδχΞ
    • GitHub: @tattn
    • Qiita: @tattn
    • Twitter: @tanakasan2525
    ాத ୡ໵ (@tattn)

    View Slide

  4. CoreMotion

    View Slide

  5. CoreMotion
    ୺຤ͷ܏͖΍า਺ͳͲɺσόΠεͷಈ͖ʹؔ͢Δ

    ৘ใΛऔಘͰ͖ΔϑϨʔϜϫʔΫɻ
    iOS 4͔ΒఏڙɻwatchOSͰ΋ར༻Մೳɻ

    (iOS 4 Ҏલ͸ UIAccelerometer ͱ͍͏ΫϥεͰՃ଎౓Λऔಘ͍ͯͨ͠)
    Sensing Device Motion in iOS 4
    https://developer.apple.com/videos/play/wwdc2010/423/

    View Slide

  6. CoreMotion
    iPhone 5sҎ߱ʹ౥ࡌͷ

    ίϓϩηοα (M7Ҏ߱) Ͱେ෯ػೳڧԽ
    What's New in Core Motion
    https://developer.apple.com/videos/play/wwdc2015/705/
    ←Ճ଎౓ηϯα
    ←δϟΠϩηϯα
    ←࣓ؾηϯα
    ←ߴ౓ηϯα

    View Slide

  7. औಘͰ͖Δ৘ใͷ͢΂ͯ
    Ճ଎౓ηϯα
    δϟΠϩηϯα
    ࣓ؾηϯα
    ߴ౓ηϯα
    • ୺຤ͷ޲͖ (ճస)
    • (୺຤ʹର͢Δ)ॏྗͷํ޲
    • ୺຤ͷՃ଎౓(ॏྗআ֎)
    • ֤ํ޲ͷ࣓ଋີ౓
    • า਺
    • า͍ͨڑ཭ (ਪఆ)
    • ฏۉ/ݱࡏͷา͘଎͞ [m/s]
    • Ұඵؒͷา਺ [า਺/s]
    • า͍ͯొͬͨ֊਺ (ਪఆ)
    • (ଌఆ͔ͯ͠Βͷ)૬ରߴ౓
    • ؾѹ
    • ཱͪࢭ·͔ͬͨ/า͖࢝Ί͔ͨ
    • ׆ಈঢ়ଶ 

    (ఀࢭ/ెา/૸Δ/ࣗಈं/

    ࣗసं)
    GPS

    View Slide

  8. ࣮૷ͷྲྀΕ

    View Slide

  9. Info.plistʹઃఆͷ௥Ճ
    ※ iOS 10͔ΒϓϥΠόγʔʹؔ͢ΔσʔλʹΞΫηε͢Δࡍ͸ઃఆ͕ඞਢʹ
    Core Motionͷ࢖༻໨తΛ௥Ճ͠·͢

    View Slide

  10. σʔλऔಘΫϥεͷੜ੒
    ཉ͍͠σʔλΛऔಘ͢ΔΫϥεΛੜ੒
    // Ճ଎౓ɾδϟΠϩɾ࣓ྗ
    let motionManager = CMMotionManager()
    // า਺
    let pedometer = CMPedometer()
    // ߴ౓
    let altimeter = CMAltimeter()
    // աڈͷՃ଎౓σʔλ
    let sensorRecoder = CMSensorRecorder()
    // Ϣʔβʔͷঢ়ଶ
    let motionActivityManager = CMMotionActivityManager()
    ↑͜ΕͰ؅ཧΫϥε͸શͯͰ͢
    (ൃද࣌)

    View Slide

  11. ػೳ͕ར༻Մೳ͔ΛνΣοΫ
    Ϋϥε໊.isʙAvailable()ϝιουͰ

    ୺຤͕ػೳΛར༻Ͱ͖Δ͔ΛऔಘͰ͖Δ
    if CMPedometer.isFloorCountingAvailable() {
    // ར༻Մೳ
    }
    CMAltimeter.isRelativeAltitudeAvailable()
    CMSensorRecorder.isAccelerometerRecordingAvailable()
    CMMotionActivityManager.isActivityAvailable()
    ↑ଞʹ΋ଟ਺͋Γ·͢

    View Slide

  12. ػೳͷରԠද
    T TT


    %FWJDF.PUJPO ˓ ˓ ˓ ˓
    "DDFMFSPNFUFS ˚ SFDPEJOH
    ˚ SFDPEJOH
    ˚ SFDPEJOH
    ˓
    (ZSP ˓ ˓ ˓ ˓
    .BHOFUPNFUFS ˓ ˓ ˓ ˓
    1FEPNFUFS
    ˚
    qPPSDPVOUJOH

    QBDF

    DBEFODF

    FWFOUUSBDLJOH

    ˚
    FWFOUUSBDLJOH

    ˓ ˓
    "MUJNFUFS ☓ ˓ ˓ ˓
    .PUJPO"DUJWJUZ ˓ ˓ ˓ ˓
    ※()ͷத͸ඇରԠͳػೳ

    View Slide

  13. ηϯαʔσʔλͷऔಘ
    ར༻Մೳͳͷ͔ΛνΣοΫޙ

    σʔλऔಘϝιουΛݺͼग़͢
    // σʔλΛऔಘͰ͖Δ৔߹ͷΈऔಘϝιουΛݺͼग़͢Α͏ʹ͢Δ
    if CMPedometer.isPedometerEventTrackingAvailable() {
    pedometer.startEventUpdates { (event, error) in
    // σʔλऔಘͷͨͼʹΫϩʔδϟ͕ݺ͹ΕΔ
    }
    }

    View Slide

  14. औಘํ๏ͷछྨ
    1. ηϯαʔͷ஋ͷ؂ࢹ։࢝
    2. ஋Λఆظతʹऔಘ(ΫϩʔδϟorϓϩύςΟ)
    ఆظऔಘ
    ظؒऔಘ
    1. ظؒΛࢦఆ
    2. ظؒதʹଌఆͨ͠σʔλΛऔಘ

    View Slide

  15. ύλʔϯ1 - ఆظऔಘ
    CMMotionManager().startDeviceMotionUpdates()
    CMMotionManager().startAccelerometerUpdates()
    CMMotionManager().startGyroUpdates()
    CMMotionManager().startMagnetometerUpdates()
    CMPedometer().startUpdates(from: date) { (data, error) in }
    CMPedometer().startEventUpdates { (event, error) in }
    CMAltimeter()
    .startRelativeAltitudeUpdates(to: .init()) { data, _ in }
    CMMotionActivityManager()
    .startActivityUpdates(to: .init()) { activity in }
    औಘ։࢝ϝιουΛݺͼग़͢

    View Slide

  16. ύλʔϯ1 - ఆظऔಘ
    manager.deviceMotion?.rotationRate
    motionActivityManager.startActivityUpdates(to: .init()) { activity in
    guard let activity = activity else { return }
    if activity.stationary {
    print("ࢭ·ͬͯΔΑ")
    }
    if activity.cycling {
    print("νϟϦͰདྷͨ")
    }
    }
    ϓϩύςΟ·ͨ͸ΫϩʔδϟͰ஋Λड͚औΔ

    View Slide

  17. ύλʔϯ2 - ظؒͰऔಘ
    let now = Date()
    let dayBeforeYesterDay = now.addingTimeInterval(-60 * 60 * 24 * 2)
    pedometer.queryPedometerData(from: dayBeforeYesterDay,
    to: now) { data, error in
    guard let data = data, error == nil else { return }
    print(data.distance ?? 0)
    print(data.numberOfSteps)
    print(data.floorsAscended ?? 0)
    }
    (from:to)ͰظؒΛࢦఆ͢Δ

    View Slide

  18. CoreMotionͷڐՄঢ়ଶͷνΣοΫ
    pedometer.queryPedometerData(from: now, to: now) { (data, error) in
    if let code = error?._code,
    code == Int(CMErrorMotionActivityNotAuthorized.rawValue) {
    // ະڐՄ
    }
    iOS10·Ͱ͸

    errorͰ൑ఆ͢Δ͔͋͠Γ·ͤΜͰͨ͠ʘ(^o^)ʗ

    View Slide

  19. ڐՄঢ়ଶΛࣄલʹऔಘՄೳʹ
    ࠓ·Ͱ
    iOS 11 / watchOS 4͔Β
    pedometer.queryPedometerData(from: now, to: now) { (data, error) in
    if let code = error?._code,
    code == Int(CMErrorMotionActivityNotAuthorized.rawValue) {
    // ະڐՄ
    }
    if CMPedometer.isStepCountingAvailable() {
    switch CMPedometer.authorizationStatus() {
    case .notDetermined:
    break
    case .restricted:
    break
    case .denied:
    break
    case .authorized:
    break
    }
    }

    View Slide

  20. CoreMotionͷڐՄঢ়ଶͷνΣοΫ
    ͢ͰʹiOS11ະຬΛ੾ΕΔ

    ϫΠϧυͳ

    αʔϏεͷ৔߹͸ࣄલʹνΣοΫ͠·͠ΐ͏

    View Slide

  21. ࣮૷্ͷ஫ҙ఺

    View Slide

  22. Operation Queueʹ஫ҙ
    ͲͷOperation QueueͰσʔλΛड͚औΔ͔ΛࢦఆͰ͖Δ
    motionManager.startMagnetometerUpdates(to: .main) { (data, error) in
    // ϝΠϯεϨου
    }
    ↑OperationQueue.main͸σʔλऔಘͷͨͼʹ

    UIεϨουΛϒϩοΩϯά͢Δ͜ͱʹͳΔɻɻ
    Because the processed events might arrive at a high rate, using the
    main operation queue is not recommended.
    https://developer.apple.com/documentation/coremotion/cmmotionmanager/1615968-startmagnetometerupdates

    View Slide

  23. Operation Queueʹ஫ҙ
    όοΫάϥ΢ϯυεϨουͰड͚औΓɺ

    ඞཁʹԠͯ͡ϝΠϯεϨουʹ੾Γସ͑ΔΑ͏ʹ͢Δͱྑ͍
    motionManager.startMagnetometerUpdates(to: .init()) { (data, error) in
    // όοΫάϥ΢ϯυεϨου
    if ඞཁͳΒ {
    DispatchQueue.main.async {
    // UIͷߋ৽
    }
    }
    }

    View Slide

  24. CMMotionManager
    CMMotionManager͸ಉ࣌ʹෳ਺ͷΠϯελϯεΛ࡞੒ͯ͠͸͍͚ͳ͍
    https://developer.apple.com/documentation/coremotion/cmmotionmanager
    Ճ଎౓ɾδϟΠϩɾ࣓ྗͳΜͰ΋औಘͰ͖ΔਆΫϥε
    CMMotionManager().startMagnetometerUpdates(to: .init()) { (data, error) in
    }
    CMMotionManager().startAccelerometerUpdates(to: .init()) { (data, error) in
    }
    ෼͔Γ΍͍͢μϝͳྫ

    View Slide

  25. CMMotionManager
    ෳ਺ͷը໘Ͱར༻͢Δ৔߹͸

    γϯάϧτϯΛ࡞Δͷ͕Φεεϝ
    https://developer.apple.com/documentation/coremotion/cmmotionmanager
    final class SharedMotionManager: CMMotionManager {
    static let shared = SharedMotionManager()
    // Ϋϥε֎ͰͷΠϯελϯεੜ੒ͷ๷ࢭ
    private override init() {
    super.init()
    }
    }

    View Slide

  26. ༷ʑͳଌఆํ๏͕͋Δ

    View Slide

  27. ༷ʑͳଌఆํ๏͕͋Δ
    xArbitraryZVertical
    Z͕࣠ਨ௚ɺX͕࣠ฏ໘ͷ೚ҙํ޲
    xArbitraryCorrectedZVertical
    ࣓ؾηϯαͰyawͷਫ਼౓͕޲্ͨ͠xArbitraryZVertical

    CPU࢖༻཰্͕͕Δ
    xMagneticNorthZVertical
    Z͕࣠ਨ௚ɺX͕࣓࣠๺

    ୺຤Λಈ͔࣓ͯ͠ؾηϯαͷΩϟϦϒϨʔγϣϯ͕ඞཁ
    xTrueNorthZVertical
    Z͕࣠ਨ௚ɺX͕࣠ਅ๺

    ࣓๺ͱਅ๺ͷܭࢉʹ࣓ؾηϯαͱGPSΛ࢖༻

    View Slide

  28. ༷ʑͳଌఆํ๏͕͋Δ
    xArbitraryCorrectedZVertical
    ࣓ؾηϯαͰyawͷਫ਼౓͕޲্ͨ͠xArbitraryZVertical

    CPU࢖༻཰্͕͕Δ
    xTrueNorthZVertical
    Z͕࣠ਨ௚ɺX͕࣠ਅ๺

    ࣓๺ͱਅ๺ͷܭࢉʹ࣓ؾηϯαͱGPSΛ࢖༻
    ࣮͸࣓ؾηϯαΛ࢖༻

    (໊લ͔Β͸Θ͔Γʹ͍͘)
    ࣮͸GPSΛ࢖༻

    (GPSͷڐՄΞϥʔτग़ͳ͍ & 

    Ґஔ৘ใαʔϏεͷON͕ඞਢ)

    View Slide

  29. ࠷ޙʹ

    View Slide

  30. ػೳͷରԠද
    ※()ͷத͸ඇରԠͳػೳ
    T TT


    %FWJDF.PUJPO ˓ ˓ ˓ ˓
    "DDFMFSPNFUFS ˚ SFDPEJOH
    ˚ SFDPEJOH
    ˚ SFDPEJOH
    ˓
    (ZSP ˓ ˓ ˓ ˓
    .BHOFUPNFUFS ˓ ˓ ˓ ˓
    1FEPNFUFS
    ˚
    qPPSDPVOUJOH

    QBDF

    DBEFODF

    FWFOUUSBDLJOH

    ˚
    FWFOUUSBDLJOH

    ˓ ˓
    "MUJNFUFS ☓ ˓ ˓ ˓
    .PUJPO"DUJWJUZ ˓ ˓ ˓ ˓

    View Slide

  31. ࠷ޙʹ
    https://github.com/tattn/TryCoreMotion
    ΄΅શػೳ࢖ͬͨαϯϓϧΞϓϦ࡞Γ·ͨ͠

    View Slide

  32. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide