Maze / Library /PackageCache /com.unity.inputsystem@1.6.1 /InputSystem /Plugins /iOS /iOSStepCounter.mm
| class iOSStepCounterWrapper | |
| { | |
| public: | |
| typedef void (*OnDataReceived) (int deviceId, int numberOfSteps); | |
| struct iOSStepCounterCallbacks | |
| { | |
| OnDataReceived dataReceived; | |
| }; | |
| iOSStepCounterWrapper() | |
| { | |
| m_Pedometer = nullptr; | |
| m_Device = -1; | |
| } | |
| void Enable(int deviceId, iOSStepCounterCallbacks* callbacks) | |
| { | |
| if (IsEnabled()) | |
| { | |
| STEP_COUNTER_LOG(@"Was already enabled?"); | |
| if (m_Device != deviceId) | |
| STEP_COUNTER_LOG(@"Enabling with different device id? Expected %d, was %d. Are you creating more than one iOSStepCounter", m_Device, deviceId); | |
| } | |
| m_Pedometer = [[CMPedometer alloc]init]; | |
| m_Callbacks = *callbacks; | |
| m_Device = deviceId; | |
| [m_Pedometer startPedometerUpdatesFromDate: [NSDate date] withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) | |
| { | |
| // Note: We need to call our callback on the same thread the Unity scripting is operating | |
| dispatch_async(dispatch_get_main_queue(), ^{ | |
| if (error != nil) | |
| { | |
| STEP_COUNTER_LOG(@"startPedometerUpdatesFromDate threw an error '%@', was it authorized?", [error localizedDescription]); | |
| if (m_Device != -1) | |
| Disable(m_Device); | |
| return; | |
| } | |
| // Guard against situation where device was disabled, any event which are received after that, should be ignored. | |
| if (m_Device == -1) | |
| return; | |
| m_Callbacks.dataReceived(m_Device, [pedometerData.numberOfSteps intValue]); | |
| }); | |
| }]; | |
| } | |
| bool Disable(int deviceId) | |
| { | |
| if (m_Pedometer == nullptr) | |
| return false; | |
| if (m_Device != deviceId) | |
| STEP_COUNTER_LOG(@"Disabling with wrong device id, expected %d, was %d", m_Device, deviceId); | |
| [m_Pedometer stopPedometerUpdates]; | |
| m_Pedometer = nullptr; | |
| m_Device = -1; | |
| return true; | |
| } | |
| bool IsEnabled() const | |
| { | |
| return m_Pedometer != nullptr; | |
| } | |
| private: | |
| CMPedometer* m_Pedometer; | |
| iOSStepCounterCallbacks m_Callbacks; | |
| int m_Device; | |
| }; | |
| static iOSStepCounterWrapper s_Wrapper; | |
| static const int kResultSuccess = 1; | |
| static const int kResultFailure = -1; | |
| extern "C" int _iOSStepCounterIsAvailable() | |
| { | |
| return [CMPedometer isStepCountingAvailable] ? 1 : 0; | |
| } | |
| extern "C" int _iOSStepCounterGetAuthorizationStatus() | |
| { | |
| if (@available(iOS 11.0, *)) | |
| { | |
| return (int)[CMPedometer authorizationStatus]; | |
| } | |
| return 0; | |
| } | |
| extern "C" int _iOSStepCounterEnable(int deviceId, iOSStepCounterWrapper::iOSStepCounterCallbacks* callbacks, int sizeOfCallbacks) | |
| { | |
| if (sizeof(iOSStepCounterWrapper::iOSStepCounterCallbacks) != sizeOfCallbacks) | |
| { | |
| STEP_COUNTER_LOG(@"iOSStepCounterCallbacks size mismatch, expected %lu was %d", sizeof(iOSStepCounterWrapper::iOSStepCounterCallbacks), sizeOfCallbacks); | |
| return kResultFailure; | |
| } | |
| if (_iOSStepCounterIsAvailable() == 0) | |
| { | |
| STEP_COUNTER_LOG(@"Step counting is not available"); | |
| return kResultFailure; | |
| } | |
| NSString* motionUsage = @"NSMotionUsageDescription"; | |
| if ([[NSBundle mainBundle] objectForInfoDictionaryKey: motionUsage] == nil) | |
| { | |
| STEP_COUNTER_LOG(@"%@ is missing in Info.plist, please enable Motion Usage in Input Settings", motionUsage); | |
| return kResultFailure; | |
| } | |
| if (@available(iOS 11.0, *)) | |
| { | |
| if ([CMPedometer authorizationStatus] == CMAuthorizationStatusRestricted) | |
| { | |
| STEP_COUNTER_LOG(@"Step Counter was restricted."); | |
| return kResultFailure; | |
| } | |
| if ([CMPedometer authorizationStatus] == CMAuthorizationStatusDenied) | |
| { | |
| STEP_COUNTER_LOG(@"Step Counter was denied. Enable Motion & Fitness under app settings."); | |
| return kResultFailure; | |
| } | |
| // Do nothing for Authorized and NotDetermined | |
| } | |
| // Note: After installation this function will prompt a dialog asking about Motion & Fitness authorization | |
| // If user denies the prompt, there will be an error in startPedometerUpdatesFromDate callback | |
| // The dialog only appears once, not sure how to trigger it again, besides reinstalling app | |
| s_Wrapper.Enable(deviceId, callbacks); | |
| return kResultSuccess; | |
| } | |
| extern "C" int _iOSStepCounterDisable(int deviceId) | |
| { | |
| return s_Wrapper.Disable(deviceId) ? kResultSuccess : kResultFailure; | |
| } | |
| extern "C" int _iOSStepCounterIsEnabled(int deviceId) | |
| { | |
| return s_Wrapper.IsEnabled() ? 1 : 0; | |
| } | |