// // DeviceDataUsage.swift // Broadcasting // // Created by Uldis Zingis on 28/06/2021. // import Foundation class DeviceDataUsage { private static let wwanInterfacePrefix = "pdp_ip" private static let wifiInterfacePrefix = "en" public static var dataUsed: Int { let wifiUsage = getDataUsage().wifiSent + getDataUsage().wifiReceived let cellUsage = getDataUsage().wirelessWanDataSent + getDataUsage().wirelessWanDataReceived return Int(max(wifiUsage, cellUsage)) } class func getDataUsage() -> DataUsageInfo { var ifaddr: UnsafeMutablePointer? var dataUsageInfo = DataUsageInfo() guard getifaddrs(&ifaddr) == 0 else { return dataUsageInfo } while let addr = ifaddr { guard let info = getDataUsageInfo(from: addr) else { ifaddr = addr.pointee.ifa_next continue } dataUsageInfo.updateInfoByAdding(info) ifaddr = addr.pointee.ifa_next } freeifaddrs(ifaddr) return dataUsageInfo } private class func getDataUsageInfo(from infoPointer: UnsafeMutablePointer) -> DataUsageInfo? { let pointer = infoPointer let name: String! = String(cString: pointer.pointee.ifa_name) let addr = pointer.pointee.ifa_addr.pointee guard addr.sa_family == UInt8(AF_LINK) else { return nil } return dataUsageInfo(from: pointer, name: name) } private class func dataUsageInfo(from pointer: UnsafeMutablePointer, name: String) -> DataUsageInfo { var networkData: UnsafeMutablePointer? var dataUsageInfo = DataUsageInfo() if name.hasPrefix(wifiInterfacePrefix) { networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer.self) if let data = networkData { dataUsageInfo.wifiSent += UInt64(data.pointee.ifi_obytes) dataUsageInfo.wifiReceived += UInt64(data.pointee.ifi_ibytes) } } else if name.hasPrefix(wwanInterfacePrefix) { networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer.self) if let data = networkData { dataUsageInfo.wirelessWanDataSent += UInt64(data.pointee.ifi_obytes) dataUsageInfo.wirelessWanDataReceived += UInt64(data.pointee.ifi_ibytes) } } return dataUsageInfo } } struct DataUsageInfo { var wifiReceived: UInt64 = 0 var wifiSent: UInt64 = 0 var wirelessWanDataReceived: UInt64 = 0 var wirelessWanDataSent: UInt64 = 0 mutating func updateInfoByAdding(_ info: DataUsageInfo) { wifiSent += info.wifiSent wifiReceived += info.wifiReceived wirelessWanDataSent += info.wirelessWanDataSent wirelessWanDataReceived += info.wirelessWanDataReceived } }