iPhone Data Usage Tracking/Monitoring

前端 未结 7 1265
感情败类
感情败类 2020-11-22 04:08

I\'ve searched over this topic but found very few details which were helpful. With these details I\'ve tried to cook some code as follows.

Note: Please compa

7条回答
  •  广开言路
    2020-11-22 04:29

    Sorry for same answer again.

    but I found that UInt32 is not enough, so it crashes when it became too big.

    I just changed UInt32 to UInt64 and it works fine.

    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
        }
    }
    
    class DataUsage {
    
        private static let wwanInterfacePrefix = "pdp_ip"
        private static let wifiInterfacePrefix = "en"
    
        class func getDataUsage() -> DataUsageInfo {
            var interfaceAddresses: UnsafeMutablePointer? = nil
    
            var dataUsageInfo = DataUsageInfo()
    
            guard getifaddrs(&interfaceAddresses) == 0 else { return dataUsageInfo }
    
            var pointer = interfaceAddresses
            while pointer != nil {
                guard let info = getDataUsageInfo(from: pointer!) else {
                    pointer = pointer!.pointee.ifa_next
                    continue
                }
                dataUsageInfo.updateInfoByAdding(info: info)
                pointer = pointer!.pointee.ifa_next
            }
    
            freeifaddrs(interfaceAddresses)
    
            return dataUsageInfo
        }
    
        private class func getDataUsageInfo(from infoPointer: UnsafeMutablePointer) -> DataUsageInfo? {
            let pointer = infoPointer
    
            let name: String! = String(cString: infoPointer.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? = nil
            var dataUsageInfo = DataUsageInfo()
    
            if name.hasPrefix(wifiInterfacePrefix) {
                networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer.self)
                dataUsageInfo.wifiSent += UInt64(networkData?.pointee.ifi_obytes ?? 0)
                dataUsageInfo.wifiReceived += UInt64(networkData?.pointee.ifi_ibytes ?? 0)
            } else if name.hasPrefix(wwanInterfacePrefix) {
                networkData = unsafeBitCast(pointer.pointee.ifa_data, to: UnsafeMutablePointer.self)
                dataUsageInfo.wirelessWanDataSent += UInt64(networkData?.pointee.ifi_obytes ?? 0)
                dataUsageInfo.wirelessWanDataReceived += UInt64(networkData?.pointee.ifi_ibytes ?? 0)
            }
    
            return dataUsageInfo
        }
    }
    

提交回复
热议问题