Обновления CoreMotion в фоновом режиме
С чипом M7 в последних устройствах iOS можно получать программные уведомления, когда пользователь переходит от стационарного к бегу, ходьбе и т. Д., Используя CMMotionActivityManager. Stava и Runkeeper оба использовали это для автоматической приостановки опроса GPS (отключение антенны GPS), когда он обнаруживает, что пользователь не движется через M7, и затем снова включают обновления GPS, когда они снова перемещаются. Это можно сделать, когда приложение находится в фоновом режиме, что является ключевым моментом здесь.
Проблема, с которой я сталкиваюсь при дублировании этой функции, заключается в том, что если я отключаю обновления GPS, когда мое приложение находится в фоновом режиме, я прекращаю получать обновления активности и больше не могу определить, когда пользователь снова перемещается через M7, чтобы снова включить GPS.
Если я оставлю GPS включенным все время, я продолжу получать обновления движения от Core Motion все время, пока приложение находится в фоновом режиме.
Я предполагаю, что они не играют белый шум или какой-то другой дешевый трюк, чтобы оставаться активным. Как они пошли по этому поводу?
5 ответов
RunKeeper на самом деле использует звуковой трюк, чтобы не спать. Если вы откроете пакет приложения и проверите его Info.plist, вы увидите, что он регистрируется в режиме фонового аудио. Вот как они производят периодические звуковые уведомления о вашем расстоянии, скорости и темпе. Кроме того, они бодрствуют во время бега, сводя к минимуму разрядку аккумулятора.
Если вы заметили, что значок Location Services (треугольник в строке состояния) полностью исчезает при использовании RunKeeper, то они определенно не используют какой-либо тип отслеживания местоположения для выполнения фонового выполнения. Даже активация геозон и мониторинг значительных изменений местоположения могут привести к появлению значка Службы определения местоположения.
Они также не используют M7, чтобы не спать, потому что это не работает таким образом. Обновление API-интерфейса CoreMotion, связанного с M7, не разбудит ваше приложение из спящего режима. Когда они проснут приложение, они смогут запросить историю действий и шагов и, возможно, попытаться что-то вычислить, но я сомневаюсь, что все будет так точно.
Наконец, вы должны отметить, что API-интерфейсы Auto-pause были введены в iOS 6 до выхода чипов iPhone 5s и M7. Это ортогональные понятия.
Рассматривали ли вы эксперименты с
application:performFetchWithCompletionHandler:
в приложении делегат? Вы не можете контролировать, как часто он вызывается, но в зависимости от приложения это может происходить каждые ~15 минут. Затем вы можете запустить CMMotionActivityManager и запросить результаты M7.
Не совсем понятно, какую функциональность вы пытаетесь воспроизвести, но чип M7 записывает всю активность независимо от того, запущено ли ваше приложение. Таким образом, вы можете просто запрашивать в фоновом режиме и обновлять итоги шагов или итоги видов деятельности.
Что я заметил, когда вы выключаете GPS, приложение не будет выполнять какой-либо код в фоновом режиме для iOS 7, приложение выглядит как в неактивном состоянии. Так лучше при переходе на фоновое использование startMonitoringSignificantLocationChanges
а также получать обновления от вашего менеджера местоположения. Значит одновременное использование обоих сервисов startUpdatingLocation
на изменение состояния пользователя и startMonitoringSignificantLocationChanges
в фоновом режиме.
Поэтому, когда пользователь включает GPS, а вы использовали startMonitoringSignificantLocationChanges
ваше приложение получит
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
Лучше посмотрите здесь, в самой истории, что не так с CoreMotion Framework. И попробуйте перезапустить его. Потому что без чипа M7 я могу читать показания акселерометра в таком случае.
Если ваш менеджер местоположений работает в активном режиме, чтобы включить фоновый режим, вам нужно выполнить следующие три шага:
- Убедитесь, что [Цель / Возможности / Фоновые режимы / Обновления местоположения] включены.
- [locationManager requestAlwaysAuthorization];
- locationManager.allowsBackgroundLocationUpdates = YES;
Во-первых, проверьте, настроили ли вы фоновое поведение вашего приложения.
Перейдите к разделу "Целевые возможности" и проверьте фоновый режим для обновлений местоположения.