获取WI-FI信息以及蜂窝网络信息

最近的项目中需要获取wifi的相关信息, 包括SSID, BSSID, IP, 以及手机是否开始蜂窝网络, 是否开启个人热点等, 所以这里做一个汇总, 记录一下.

注意: 以下所有代码均为swift 4.0, 如果需要低版本语言的写法, 介于篇幅, 就不一一列举了, 有需要的小伙伴可以私信留言.

检查是否有网络(false 没有网络,true 有网络)

class func isConnectedToNetwork() -> Bool {
        var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
        zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)
    
        let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) { (unSafePointer) in
            SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer.init(OpaquePointer.init(unSafePointer))!)
        }

        var flags: SCNetworkReachabilityFlags = []
        if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
            return false
        }

        let isReachable = flags.contains(.reachable)
        let needsConnection = flags.contains(.connectionRequired)

        return isReachable && !needsConnection
 }

获取当前wifi的ssid

func getSSidInfo() -> String {
        if let cfas: NSArray = CNCopySupportedInterfaces() {
            for cfa in cfas {
                if let dict = CFBridgingRetain(CNCopyCurrentNetworkInfo(cfa as! CFString)) {
                    let dic = dict as! NSDictionary
                    if let ssid = dic["SSID"] as? String {
                        return ssid
                    }
                }
            }
        }
        return "未连接"
    }

获取当前wifi的IP地址

func getIPAddress() -> String {
        var address = ""
        
        // Get list of all interfaces on the local machine:
        var ifaddr : UnsafeMutablePointer? = nil
        if getifaddrs(&ifaddr) == 0 {
            
            // For each interface ...
            var ptr = ifaddr
            while ptr != nil {
                let interface = ptr?.pointee
                
                // Check for IPv4 or IPv6 interface:
                let addrFamily = interface?.ifa_addr.pointee.sa_family
                if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
                    
                    // Check interface name:
                    let name = String(cString: (interface?.ifa_name)!)
                    if name == "en0" {
                        
                        // Convert interface address to a human readable string:
                        var addr = interface?.ifa_addr.pointee
                        var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                        getnameinfo(&addr!, socklen_t(interface!.ifa_addr.pointee.sa_len),
                                    &hostname, socklen_t(hostname.count),
                                    nil, socklen_t(0), NI_NUMERICHOST)
                        address = String.init(cString: hostname)
                    }
                }
                ptr = ptr?.pointee.ifa_next
            }
            freeifaddrs(ifaddr)
        }
        return (address == "") ? "255.255.255.255" : address
    }

检测系统此时正在使用的wifi情况(SSID,BSSID(mac))

func getWifiInfo() -> (ssid: String, mac: String) {
        if let cfas: NSArray = CNCopySupportedInterfaces() {
            for cfa in cfas {
                if let dict = CFBridgingRetain(CNCopyCurrentNetworkInfo(cfa as! CFString)) {
                    let dic = dict as! NSDictionary
                    if let ssid = dic["SSID"] as? String, let bssid = dic["BSSID"] as? String {
                        return (ssid, bssid)
                    }
                }
            }
        }
        return ("未连接", "未知")
    }

获取手机当前所有的网络信息(便于蜂窝网络&个人热点的判断)

func getAllIfaName() -> [String] {
        var ifaNames = [String]()
        var ifaddr: UnsafeMutablePointer? = nil
        if getifaddrs(&ifaddr) == 0 {
            var temp_addr = ifaddr
            while temp_addr != nil {
                let interface = temp_addr?.pointee
                let addrFamily = interface?.ifa_addr.pointee.sa_family
                if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
                    let ifaName = String.init(utf8String: (interface?.ifa_name)!)
                    if ifaName != nil {
                        ifaNames.append(ifaName!)
                    }
                }
                temp_addr = temp_addr?.pointee.ifa_next
            }
        }
        return ifaNames
    }

判断手机是否连接蜂窝网络

func judgeCellularNetworkLinkStatus() -> Bool {
        let ifaNames = getAllIfaName()
        for item in ifaNames {
            if item.contains("pdp_ip") {
                return true
            }
        }
        return false
    }

判断手机是否开启个人热点(此方法通过遍历所有ipv4网卡,查询网卡名称是否包含“bridge”即可判断当前热点是否启动,但是并不能准确的判断出,因为只有两种情况下才会出现以上情况,1.当前有设备连上此热点, 2.曾经连过,但是后来断开,但是个人热点在这个过程中未重新启动过)

func judgeHotPointIsOpen() -> Bool {
        let ifaNames = getAllIfaName()
        for item in ifaNames {
            if item.contains("bridge") {
                return true
            }
        }
        return false
    }

处理wifi的BSSID转换为常用的mac地址

func getMacInAPStyle() -> String {
        let bssid = getWifiInfo().mac
        return bssidToDeviceMac(bssid: bssid).uppercased() // 转换为大写
    }

fileprivate func bssidToDeviceMac(bssid: String) -> String {
        let charAry = bssid.components(separatedBy: ":")
        // 补足数据中只有一位的问题, 便于后面的数据拼接
        var newCharAry = [String]()
        for item in charAry {
            var newItem = ""
            if item.length == 1 {
                newItem = "0" + item
            } else {
                newItem = item
            }
            newCharAry.append(newItem)
        }
        
        var newBssid = ""
        for item in newCharAry {
            newBssid += item
        }
        
        let decimal = newBssid.hexToDecimal()
        let mac = (decimal - 1).decimalToHex()
        return mac
    }

你可能感兴趣的:(获取WI-FI信息以及蜂窝网络信息)