Как узнать, отключен ли сотовый доступ для моего приложения iOS?
У меня есть приложение для iOS, которое делает небольшие сетевые запросы при запуске приложения (обновления ресурсов и т. Д.). Если пользователь отключает сотовый доступ к приложению в настройках iOS, он получает запрос от iOS об использовании сети при каждом запуске. Есть ли способ программно узнать, что сотовые данные для этого приложения были отключены, чтобы я мог отключить запросы при запуске?
7 ответов
Так что я нашел это на форумах Apple Dev от инженера Apple ( https://devforums.apple.com/message/1059332).
Другой разработчик написал в DTS, и у меня была возможность подробно изучить это. Увы, новости такие же, как я ожидал: нет поддерживаемого способа определить, что ваше приложение находится в этом состоянии. Также нет способа сделать сетевое соединение "без взаимодействия с пользователем", то есть запросить сбой соединения, а не представлять подобный интерфейс. Если эти ограничения создают проблемы для вашего приложения, я рекомендую вам сообщить об ошибке, описывающей ваши конкретные требования.
https://developer.apple.com/bug-reporting/
Таким образом, похоже, что невозможно определить, были ли отключены сотовые данные для вашего приложения.
редактировать
Я подал радар для этого с просьбой добавить его. Я только что получил это уведомление в моем радаре
Мы считаем, что эта проблема была решена в последней бета-версии iOS 9.
Я просмотрел различия API, но пока не могу найти новый API.
Начиная с iOS9, возможность проверить настройку включения / выключения использования данных сотовой связи для вашего приложения (Settings/Cellular/AppName) доступна с помощью класса Apple CTCellularData. Следующий код установит cellDataRestrictedState при его первоначальном запуске, а затем установит его и будет регистрировать каждый раз, когда он изменяется:
import CoreTelephony
var cellularDataRestrictedState = CTCellularDataRestrictedState.restrictedStateUnknown
let cellState = CTCellularData.init()
cellState.cellularDataRestrictionDidUpdateNotifier = { (dataRestrictedState) in
if cellularDataRestrictedState != .restrictedStateUnknown { // State has changed - log to console
print("cellularDataRestrictedState: " + "\(dataRestrictedState == .restrictedStateUnknown ? "unknown" : dataRestrictedState == .restricted ? "restricted" : "not restricted")")
}
cellularDataRestrictedState = dataRestrictedState
}
К сожалению (начиная с iOS11), это, кажется, проверяет только состояние переключателя приложения - если переключатель вашего приложения установлен в положение "включено", а пользователь переключает главный переключатель "Сотовые данные" в положение "отключено", этот API возвратит состояние приложения как "не ограниченное". ".
Просто хотел добавить Objective C версию вышеуказанного кода Swift для будущих путешественников.
- (void)monitorCanUseCellularData {
if (GCIsiOS9) {
CTCellularData *cellularData = [[CTCellularData alloc] init];
NSLog(@"%ld", cellularData.restrictedState);
// 0, kCTCellularDataRestrictedStateUnknown
[cellularData setCellularDataRestrictionDidUpdateNotifier:^(CTCellularDataRestrictedState state) {
NSLog(@"%ld", state);
self.canUseCellularData = cellularData.restrictedState ==2?true:false;
}];
}
}
Я обнаружил, что CTCellularData
классу нужно некоторое время, чтобы добраться до правильного значения. В моей реализации я называю didUpdateNotifier
очень рано после appDidFinishLaunching
, К тому времени, когда мой сетевой вызов возвращается с ошибками, у меня уже есть правильное значение для состояния с ограничениями.
`` `class CellularRestriction: NSObject {частная статическая переменная var cellData = CTCellularData() закрытая статическая переменная current currentState = CTCellularDataRestrictedState.restrictedStateUnknown
static var isRestricted: Bool {
currentState = cellularData.restrictedState
return currentState == .restricted
}
static func prepare() {
if currentState == .restrictedStateUnknown {
cellularData.cellularDataRestrictionDidUpdateNotifier = { state in
currentState = cellularData.restrictedState // This value may be inconsistent, however the next read of isRestricted should be correct.
}
}
}
} `` `
Вы можете определить, отключены ли сотовые данные, с помощью класса NWPathMonitor. (https://developer.apple.com/documentation/network/nwpathmonitor)
let cellMonitor = NWPathMonitor(requiredInterfaceType: .cellular)
cellMonitor.pathUpdateHandler = { path in
self.isCellConnected = path.status == .satisfied
}
В дополнение к ответу dirkgroten, вы можете использовать класс Apple Reachability, найденный здесь:
https://developer.apple.com/Library/ios/samplecode/Reachability/Introduction/Intro.html
Оно использует SCNetworkReachability
, и очень прост в использовании, он обнаружит подключение через сотовый и WiFi, так как вам нужно будет проверить оба при запуске.
Существует множество платформ, которые дадут вам статус вашего сетевого подключения, и, конечно, вы можете развернуть свой собственный. я обнаружил AFNetworking
быть одним из лучших. У него есть одноэлементный класс AFNetworkReachabilityManager
это отвлекает вас от некоторых сложностей. В частности, вы захотите взглянуть на два логических свойства:
reachableViaWWAN
reachableViaWiFi
Существует также измененный блок состояния доступности, который вы можете установить:
– setReachabilityStatusChangeBlock: