iOS检测系统设置"设置/移动/蜂窝数据"主开关?

时间:2018-01-10 19:37:38

标签: ios core-telephony

从iOS9开始,可以使用Apple的CTCellularData类检查设置以启用/禁用应用程序的蜂窝数据(Settings / Cellular / AppName)。以下代码将在最初运行时设置cellularDataRestrictedState,然后设置它并在其发生更改时进行记录:

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将仍然将应用程序的状态恢复为"不受限制"。这对我来说似乎是一个错误,除非有办法检测主开关的状态。

是否有单独的机制来查询系统的状态"设置/蜂窝/蜂窝数据"主开关?

1 个答案:

答案 0 :(得分:0)

解决方案是我检查iOS网络名称,并同时使用我的应用程序的蜂窝数据,但我不确定这是不是真的好主意。没有提供有关它的信息。

   cellularData?.cellularDataRestrictionDidUpdateNotifier = { (dataRestrictedState) in
        if dataRestrictedState == .restricted { // State has changed - log to console
                self.checkIfCellularDataRestricted()
        }
    }

    func pdpIpExists() -> Bool {
//        ap1, en0, en1 are names of the interfaces on iOS as well as on Mac.
//        pdp_ip interfaces are those that are used for 3G and cellular data
    var pdpIpExists = false
    var address: String?
    var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
    if getifaddrs(&ifaddr) == 0 {
        var ptr = ifaddr
        while ptr != nil {
            defer { ptr = ptr?.pointee.ifa_next }

            let interface = ptr?.pointee
            let addrFamily = interface?.ifa_addr.pointee.sa_family
            if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {

                if let interface = interface, String(cString: interface.ifa_name).contains("pdp_ip") {
                    pdpIpExists = true
                    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                    getnameinfo(interface.ifa_addr, socklen_t((interface.ifa_addr.pointee.sa_len)), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST)
                    address = String(cString: hostname)
                }
            }
        }
        freeifaddrs(ifaddr)
    }
    //if cellular data is on, set notifyIfCellularDataRestricted to true, to notify next time when cellular data is off
    if pdpIpExists && cellularData?.restrictedState == .notRestricted {
        TWUserDefaults.notifyIfCellularDataRestricted = true
    }
    return pdpIpExists
}