투케이2K

144. (TWOK/UTIL) [Ios/Swift] C_Wifi_Ap_Module : 와이파이 및 모바일 핫스팟 관련 기능 사용 모듈 - Wifi , Ap 본문

투케이2K 유틸파일

144. (TWOK/UTIL) [Ios/Swift] C_Wifi_Ap_Module : 와이파이 및 모바일 핫스팟 관련 기능 사용 모듈 - Wifi , Ap

투케이2K 2024. 11. 24. 17:18

[설 명]

프로그램 : Ios / Swift

설 명 : C_Wifi_Ap_Module : 와이파이 및 모바일 핫스팟 관련 기능 사용 모듈 - Wifi , Ap

 

[소스 코드]

 

import Foundation
import UIKit
// -----------------------------------------
//MARK: [와이파이 및 무선 인터넷 접근 : Capabillities : wireless accessory configuration , Access Wi-Fi Information설정 필요]
import Network
import NetworkExtension
import SystemConfiguration.CaptiveNetwork
// -----------------------------------------

class C_Wifi_Ap_Module {



    /**
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * TODO [클래스 설명]
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 1. 와이파이 및 AP 통신 관련 클래스
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * */





    /**
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * //  TODO [빠른 로직 찾기 : 주석 로직 찾기]
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : getWifiIpAddress : 현재 연결 된 와이파이 ip 주소 확인
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : getWifiSsid : 현재 연결 된 와이파이 SSID 정보 확인 수행
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : getWifiBssid : 현재 연결 된 와이파이 BSSID 정보 확인 수행
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : getNetworkMonitorStatus : 현재 네트워크 안정적 상태 여부 확인
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : observableSetWifiConnection : 특정 와이파이 SSID , PW 입력 다이렉트 연결 수행
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : observableGetWifiConnectionList : 특정 와이파이 SSID , PW 입력 다이렉트 연결 수행 리스트 목록 확인
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : observableRemoveWifSsid : 특정 와이파이 SSID 연결 해제 수행
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     *
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     *
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * */
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [전역 변수 선언]
    // -----------------------------------------------------------------------------------------
    private static let ACTIVITY_NAME = "C_Wifi_Ap_Module"
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : getWifiIpAddress : 현재 연결 된 와이파이 ip 주소 확인
    // -----------------------------------------------------------------------------------------
    func getWifiIpAddress() -> String {
        
        /*
        // -----------------------------------------
        [getWifiIpAddress 메소드 설명]
        // -----------------------------------------
        1. 현재 연결 된 와이파이 ip 주소 확인
        // -----------------------------------------
        2. 호출 방법 :
         
         C_Wifi_Ap_Module().getWifiIpAddress()
        // -----------------------------------------
        3. 참고 설정 :
         
         swift 브릿지 헤더에 import 추가 필요 : #include<ifaddrs.h>
        // -----------------------------------------
        */

        
        // [변수 선언]
        var returnData = ""
        var M_LOG = ""
        
        
        // [로직 처리 실시]
        if C_StateCheck().isWifiConnected() == true { // [와이파이 연결 상태 확인]
            
            var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
            if getifaddrs(&ifaddr) == 0 {
                var ptr = ifaddr
                while ptr != nil {
                    defer { ptr = ptr?.pointee.ifa_next }

                    guard let interface = ptr?.pointee else { return "" }
                    let addrFamily = interface.ifa_addr.pointee.sa_family
                    if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {

                        // wifi = ["en0"]
                        // wired = ["en2", "en3", "en4"]
                        // cellular = ["pdp_ip0","pdp_ip1","pdp_ip2","pdp_ip3"]

                        let name: String = String(cString: (interface.ifa_name))
                        if  name == "en0" || name == "en2" || name == "en3" || name == "en4" || name == "pdp_ip0" || name == "pdp_ip1" || name == "pdp_ip2" || name == "pdp_ip3" {
                            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)
                            returnData = String(cString: hostname)
                        }
                    }
                    else {
                        M_LOG = "[Error] :: AF_INET check error"
                    }
                }
                freeifaddrs(ifaddr)
                
                if returnData != "" && returnData.count > 0 {
                    M_LOG = "[Success] :: Wifi Get Ip Address"
                }
                else {
                    M_LOG = "[Error] :: returnData Is Null"
                }
            }
            else {
                M_LOG = "[Error] :: getifaddrs check error"
            }
            
        }
        else {
            M_LOG = "[Error] :: Device Wifi Not Connected"
        }
        
        
        // [로그 출력 수행]
        S_Log._D_(description: "현재 연결 된 와이파이 ip 주소 확인", data: [
            "M_LOG :: \(M_LOG)",
            "RETURN :: \(returnData)"
        ])
        
        
        // [리턴 반환 수행]
        return returnData
    }





    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : getWifiSsid : 현재 연결 된 와이파이 SSID 정보 확인 수행
    // -----------------------------------------------------------------------------------------
    func getWifiSsid(completion: @escaping (String)->()) {
        
        /*
        // -----------------------------------------
        [getWifiSsid 메소드 설명]
        // -----------------------------------------
        1. 현재 연결 된 와이파이 SSID 정보 확인 수행
        // -----------------------------------------
        2. 호출 방법 :
         
         C_Wifi_Ap_Module().getWifiSsid(){(result) in
             
             S_Log._F_(description: "현재 연결 된 와이파이 SSID 정보 확인 수행", data: ["\(result)"])
             
         }
         
        // -----------------------------------------
        3. 필요 import :
         
         import NetworkExtension
         import SystemConfiguration.CaptiveNetwork
        // -----------------------------------------
        4. 필요 권한 : 위치 권한 Location
         
         Privacy - Location Always Usage Description
         Privacy - Location Always and When In Use Usage Description
        // -----------------------------------------
        5. MARK: xcode 프로젝트 NEHotspotNetwork 사용 설정 방법 : [Access Wi-Fi Information]
         
         - 사전) 유료 결제를 진행한 개발자 계정이 필요 (or 개발자 초대)
         - Xcode 프로젝트 설정 >> Capabillity >> Access Wi-Fi Information 추가
         - 프로젝트 entitlements 에서 추가한 Access Wi-Fi Information 권한이 정상 표시 되는 것 확인
         - 프로젝트 설정 참고 사이트 : 
         https://blog.naver.com/kkh0977/223667701982
         https://blog.naver.com/kkh0977/223669259799
        // -----------------------------------------
        */


        // [리턴 변수 선언]
        var returnData = ""
        var M_LOG = ""

        
        // [로직 처리 수행]
        DispatchQueue.main.async {

            if C_StateCheck().isWifiConnected() == true { // [와이파이 연결 된 상태]

                // [IOS 버전 분기 처리 수행]

                if #available(iOS 14.0, *) {
                    NEHotspotNetwork.fetchCurrent { network in
                        if let network = network {
                            
                            // ------------------------------------------
                            // network.ssid.description
                            // network.bssid.description
                            // ------------------------------------------
                            M_LOG = "[Success] : NEHotspotNetwork.fetchCurrent Network Search"
                            returnData = "\(network.ssid.description)"

                            S_Log._D_(description: "현재 연결 된 와이파이 SSID 정보 확인 성공", data: [ "M_LOG :: \(M_LOG)", "RETURN :: \(returnData)" ])

                            // [콜백 반환]
                            completion(returnData)
                            return

                        } else {
                            M_LOG = "[Error] : NEHotspotNetwork.fetchCurrent Network Is Nil"

                            S_Log._D_(description: "현재 연결 된 와이파이 SSID 정보 확인 실패", data: [ "M_LOG :: \(M_LOG)" ])

                            // [콜백 반환]
                            completion(returnData)
                            return
                        }
                    }
                }
                else {
                    M_LOG = "[Error] : Ios Version Under iOS 14"

                    S_Log._D_(description: "현재 연결 된 와이파이 SSID 정보 확인 실패", data: [ "M_LOG :: \(M_LOG)" ])

                    // [콜백 반환]
                    completion(returnData)
                    return
                }
            }
            else { // [와이파이 연결 안된 상태]
                M_LOG = "[Error] : Wifi Connect False"

                S_Log._D_(description: "현재 연결 된 와이파이 SSID 정보 확인 실패", data: [ "M_LOG :: \(M_LOG)" ])

                // [콜백 반환]
                completion(returnData)
                return
            }

        }
    }





    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : getWifiBssid : 현재 연결 된 와이파이 BSSID 정보 확인 수행
    // -----------------------------------------------------------------------------------------
    func getWifiBssid(completion: @escaping (String)->()) {
        
        /*
        // -----------------------------------------
        [getWifiBssid 메소드 설명]
        // -----------------------------------------
        1. 현재 연결 된 와이파이 BSSID 정보 확인 수행
        // -----------------------------------------
        2. 호출 방법 :
         
         C_Wifi_Ap_Module().getWifiBssid(){(result) in
             
             S_Log._F_(description: "현재 연결 된 와이파이 BSSID 정보 확인 수행", data: ["\(result)"])
             
         }
         
        // -----------------------------------------
        3. 필요 import :
         
         import NetworkExtension
         import SystemConfiguration.CaptiveNetwork
        // -----------------------------------------
        4. 필요 권한 : 위치 권한 Location
         
         Privacy - Location Always Usage Description
         Privacy - Location Always and When In Use Usage Description
        // -----------------------------------------
        5. MARK: xcode 프로젝트 NEHotspotNetwork 사용 설정 방법 : [Access Wi-Fi Information]
         
         - 사전) 유료 결제를 진행한 개발자 계정이 필요 (or 개발자 초대)
         - Xcode 프로젝트 설정 >> Capabillity >> Access Wi-Fi Information 추가
         - 프로젝트 entitlements 에서 추가한 Access Wi-Fi Information 권한이 정상 표시 되는 것 확인
         - 프로젝트 설정 참고 사이트 : 
         https://blog.naver.com/kkh0977/223667701982
         https://blog.naver.com/kkh0977/223669259799
        // -----------------------------------------
        */


        // [리턴 변수 선언]
        var returnData = ""
        var M_LOG = ""

        
        // [로직 처리 수행]
        DispatchQueue.main.async {

            if C_StateCheck().isWifiConnected() == true { // [와이파이 연결 된 상태]

                // [IOS 버전 분기 처리 수행]
                if #available(iOS 14.0, *) {
                    NEHotspotNetwork.fetchCurrent { network in
                        if let network = network {
                            
                            // ------------------------------------------
                            // network.ssid.description
                            // network.bssid.description
                            // ------------------------------------------
                            M_LOG = "[Success] : NEHotspotNetwork.fetchCurrent Network Search"
                            returnData = "\(network.bssid.description)"

                            S_Log._D_(description: "현재 연결 된 와이파이 BSSID 정보 확인 성공", data: [ "M_LOG :: \(M_LOG)", "RETURN :: \(returnData)" ])

                            // [콜백 반환]
                            completion(returnData)
                            return

                        } else {
                            M_LOG = "[Error] : NEHotspotNetwork.fetchCurrent Network Is Nil"

                            S_Log._D_(description: "현재 연결 된 와이파이 BSSID 정보 확인 실패", data: [ "M_LOG :: \(M_LOG)" ])

                            // [콜백 반환]
                            completion(returnData)
                            return
                        }
                    }
                }
                else {
                    M_LOG = "[Error] : Ios Version Under iOS 14"

                    S_Log._D_(description: "현재 연결 된 와이파이 BSSID 정보 확인 실패", data: [ "M_LOG :: \(M_LOG)" ])

                    // [콜백 반환]
                    completion(returnData)
                    return
                }
            }
            else { // [와이파이 연결 안된 상태]
                M_LOG = "[Error] : Wifi Connect False"

                S_Log._D_(description: "현재 연결 된 와이파이 BSSID 정보 확인 실패", data: [ "M_LOG :: \(M_LOG)" ])

                // [콜백 반환]
                completion(returnData)
                return
            }

        }
    }





    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : getNetworkMonitorStatus : 현재 네트워크 안정적 상태 여부 확인
    // -----------------------------------------------------------------------------------------
    func getNetworkMonitorStatus() -> Bool {
        
        /*
        // -----------------------------------------
        // [getNetworkMonitorStatus 메소드 설명]
        // -----------------------------------------
        1. 필요 import : import Network
        // -----------------------------------------
        2. 호출 방법 : if C_Wifi_Ap_Module().getNetworkMonitorStatus() == true {} else {}
        // -----------------------------------------
        3. 애플 사이트 : https://developer.apple.com/documentation/network/nwpathmonitor
        // -----------------------------------------
        */


        // [리턴 변수 선언]
        var returnData = false
        var M_LOG = ""

        
        // [로직 처리 수행]
        if #available(iOS 12, *) {

            // [현재 네트워크 연결 상태 확인 객체 선언]
            let monitor = NWPathMonitor()

            // [세마포어 선언 : 프로그램 로직을 동기화 구현 : value 0 값은 대기 상태 선언]
            let semaphore = DispatchSemaphore(value: 0)

            // [네트워크 연결 상태 확인 부분]
            monitor.pathUpdateHandler = { path in
                if path.status == .satisfied { // [네트워크가 연결된 경우]
                    
                    // [리턴 값 삽입]
                    M_LOG = "[Status] :: Satisfied !!"
                    returnData = true

                    // [네트워크 상태 확인 종료]
                    monitor.cancel()

                    // [세마포어 신호 알림]
                    semaphore.signal()
                }
                else { // [네트워크가 연결되지 않은 경우]
                
                    // [리턴 값 삽입]
                    M_LOG = "[Status] :: UnSatisfied .."
                    returnData = true

                    // [네트워크 상태 확인 종료]
                    monitor.cancel()

                    // [세마포어 신호 알림]
                    semaphore.signal()
                }
            }
            
            // [네트워크 연결 상태 확인 수행]
            monitor.start(queue: DispatchQueue.global())
            
            // [세마포어 확인 대기]
            semaphore.wait()
            
        }
        else {
            M_LOG = "[Error] : Ios Version Under iOS 12"
        }


        // [로그 출력 수행]
        S_Log._D_(description: "현재 네트워크 안정적 상태 여부 확인", data: [
            "M_LOG :: \(M_LOG)",
            "RETURN :: \(returnData)"
        ])
        
        
        // [리턴 반환 수행]
        return returnData

    }





    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : observableSetWifiConnection : 특정 와이파이 SSID , PW 입력 다이렉트 연결 수행
    // -----------------------------------------------------------------------------------------
    static var WIFI_CONNECT_LOG = ""
    func observableSetWifiConnection(ssid:String, pw:String, completion: @escaping (Bool)->()) {
        
        /*
        // -----------------------------------------
        [observableSetWifiConnection 메소드 설명]
        // -----------------------------------------
        1. 특정 와이파이 SSID , PW 입력 다이렉트 연결 수행
        // -----------------------------------------
        2. 호출 방법 :
         
         C_Wifi_Ap_Module().observableSetWifiConnection(ssid:"TWOK", pw:"1234"){(result) in
             
             S_Log._F_(description: "특정 와이파이 SSID , PW 입력 다이렉트 연결 확인 수행", data: ["\(result)"])

             if result == true {
                
                // [현재 연결 된 WIFI SSID 체크 >> 소켓 통신 수행]
             }
             else {
                S_Log._F_(description: "특정 와이파이 SSID , PW 입력 다이렉트 연결 에러 메시지", data: ["\(C_Wifi_Ap_Module.WIFI_CONNECT_LOG)"])
             }
             
         }
         
        // -----------------------------------------

        3. 필요 import :
         
         import NetworkExtension
         import SystemConfiguration.CaptiveNetwork
        // -----------------------------------------
        4. 필요 권한 : 위치 권한 Location
         
         Privacy - Location Always Usage Description
         Privacy - Location Always and When In Use Usage Description
        // -----------------------------------------
        5. MARK: xcode 프로젝트 Capabillity 사용 설정 방법 : [Hotspot Configuration]
         
         - 사전) 유료 결제를 진행한 개발자 계정이 필요 (or 개발자 초대)
         - Xcode 프로젝트 설정 >> Capabillity >> Hotspot Configuration 추가
         - 프로젝트 entitlements 에서 추가한 Hotspot Configuration 권한이 정상 표시 되는 것 확인
         - 설정 및 적용 참고 사이트 : 
         https://blog.naver.com/kkh0977/223669166907
         https://blog.naver.com/kkh0977/223669259799
        // -----------------------------------------
        */


        // [리턴 변수 선언]
        var returnData = false
        C_Wifi_Ap_Module.WIFI_CONNECT_LOG = ""

        
        // [로직 처리 수행]
        DispatchQueue.main.async {
            S_Log._D_(description: "특정 와이파이 SSID , PW 입력 다이렉트 연결 수행", data: [
                "SSID :: \(ssid)",
                "PW :: \(pw)"
            ])


            /*
            // -----------------------------------------
            [NEHotspotConfiguration 옵션 설명]
            // -----------------------------------------
            - Persistent configuration: Settings 에서 Wi-Fi 변경과 동일
            - Join-once configuration: 일시적으로 Wi-Fi network 변경
                >> joinOnce 가 true 로 설정되면 핫스팟은 앱이 포그라운드에서 실행되는 동안만 유지됩니다
                >> 앱이 15초 이상 백그라운드에 머물러 있는 경우 >> 해제
                   장치가 절전 모드에 들어간 경우 >> 해제
                   앱이 충돌하거나 종료되거나 제거 된 경우 >> 해제
                   다른 Wi-Fi 네트워크에 연결 한 경우 >> 해제
            // -----------------------------------------
            지원 인증 모델 :

            - 인증 없는 SSID
            - password-based 인증 SSID (WEP, WPA, WPA2)
            - EAP 인증 SSID
            - EAP 인증 Hotspot 2.0
            // -----------------------------------------
            NEHotspotConfigurationManager 에러 코드 참고 사이트

              >> https://developer.apple.com/documentation/networkextension/nehotspotconfigurationerror
            // -----------------------------------------
            */


            // [인풋 데이터 널 체크] : [비밀 번호는 null 일 수 있으니 예외]
            if C_Util().stringNotNull(str: ssid) == true {

                // [사전 다이렉트 연결 옵션이 있는 경우 해제]
                NEHotspotConfigurationManager.shared.removeConfiguration(forSSID: "\(ssid)")


                // [인풋으로 들어온 WIFI 정보로 연결 수행]
                //let hotspotConfig = NEHotspotConfiguration(ssid: "\(ssid)") // MARK: [SoftAp]
                let hotspotConfig = NEHotspotConfiguration(ssid: "\(ssid)", passphrase: "\(pw)", isWEP: false) // MARK: [WPA]
                hotspotConfig.joinOnce = true
                
                NEHotspotConfigurationManager.shared.apply(hotspotConfig) { error in
                    if let errorLet = error as NSError? {

                        switch errorLet.code {
                        case NEHotspotConfigurationError.invalid.rawValue: // [구성이 유효하지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : invalid : 구성이 유효하지 않음"
                        case NEHotspotConfigurationError.invalidSSID.rawValue: // [SSID 값이 유효하지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : invalidSSID : SSID 값이 유효하지 않음"
                        case NEHotspotConfigurationError.invalidWPAPassphrase.rawValue: // [WPA 암호가 유효하지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : invalidWPAPassphrase : WPA 암호가 유효하지 않음"
                        case NEHotspotConfigurationError.invalidWEPPassphrase.rawValue: // [WEP 암호가 유효하지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : invalidWEPPassphrase : WEP 암호가 유효하지 않음"
                        case NEHotspotConfigurationError.invalidEAPSettings.rawValue: // [EAP 설정이 유효하지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : invalidEAPSettings : EAP 설정이 유효하지 않음"
                        case NEHotspotConfigurationError.invalidHS20Settings.rawValue: // [HS 2.0 설정이 유효하지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : invalidHS20Settings : HS 2.0 설정이 유효하지 않음"
                        case NEHotspotConfigurationError.invalidHS20DomainName.rawValue: // [HS 2.0 도메인 이름이 유효하지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : invalidHS20DomainName : HS 2.0 도메인 이름이 유효하지 않음"
                        case NEHotspotConfigurationError.invalidSSIDPrefix.rawValue: // [핫스팟 구성을 만드는 데 사용된 SSID 접두사가 잘못됨]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : invalidSSIDPrefix : 핫스팟 구성을 만드는 데 사용된 SSID 접두사가 잘못됨"
                        case NEHotspotConfigurationError.userDenied.rawValue: // [사용자가 네트워크 구성을 거부함 - 권한 거부]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : userDenied : 사용자가 네트워크 구성을 거부함"
                        case NEHotspotConfigurationError.pending.rawValue: // [네트워크 구성 작업이 완료되지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : pending : 네트워크 구성 작업이 완료되지 않음"
                        case NEHotspotConfigurationError.systemConfiguration.rawValue: // [시스템 구성이 유효하지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : systemConfiguration : 시스템 구성이 유효하지 않음"
                        case NEHotspotConfigurationError.joinOnceNotSupported.rawValue: // [join-once 옵션은 EAP 구성을 지원하지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : joinOnceNotSupported : join-once 옵션은 EAP 구성을 지원하지 않음"
                        case NEHotspotConfigurationError.alreadyAssociated.rawValue: // [구성이 이미 핫스팟과 연결되어 있음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : alreadyAssociated : 구성이 이미 핫스팟과 연결되어 있음"
                        case NEHotspotConfigurationError.internal.rawValue: // [내부 시스템 에러 발생]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : internal : 내부 시스템 에러 발생 (네트워크 디버깅 해제, Xcode 설정 확인 및 재실행 - Hotspot Configuration 포함 확인, 휴대폰 재부팅 필요)"
                        case NEHotspotConfigurationError.applicationIsNotInForeground.rawValue: // [해당 애플리케이션이 포그라운드에서 실행되고 있지 않음]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : applicationIsNotInForeground : 해당 애플리케이션이 포그라운드에서 실행되고 있지 않음"
                        default: // [unknown = 알수 없음 오류]
                            C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : default : \(errorLet.code)"
                        }

                        S_Log._D_(description: "특정 와이파이 SSID , PW 입력 다이렉트 연결 에러", data: [
                            "M_LOG :: \(C_Wifi_Ap_Module.WIFI_CONNECT_LOG)",
                            "Description :: \(errorLet.description)"
                        ])
                        completion(returnData) // [콜백 반환]
                        return
                        
                    } else {

                        C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Success] : Wifi Connect : \(ssid)"
                        returnData = true

                        S_Log._D_(description: "특정 와이파이 SSID , PW 입력 다이렉트 연결 성공", data: [
                            "M_LOG :: \(C_Wifi_Ap_Module.WIFI_CONNECT_LOG)"
                        ])

                        completion(returnData) // [콜백 반환]
                        return

                    }
                }

            }
            else {
                C_Wifi_Ap_Module.WIFI_CONNECT_LOG = "[Error] : Input Ssid Is Null"

                S_Log._D_(description: "특정 와이파이 SSID , PW 입력 다이렉트 연결 실패", data: [ "M_LOG :: \(C_Wifi_Ap_Module.WIFI_CONNECT_LOG)" ])
                completion(returnData) // [콜백 반환]
                return
            }

        }
    }
    
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : observableGetWifiConnectionList : 특정 와이파이 SSID , PW 입력 다이렉트 연결 수행 리스트 목록 확인
    // -----------------------------------------------------------------------------------------
    static var configList : Array<String> = []
    func observableGetWifiConnectionList(completion: @escaping (Array<String>)->()) {
        
        /*
        // -----------------------------------------
        [observableSetWifiConnection 메소드 설명]
        // -----------------------------------------
        1. 특정 와이파이 SSID , PW 입력 다이렉트 연결 수행
        // -----------------------------------------
        2. 호출 방법 :
         
         C_Wifi_Ap_Module().observableGetWifiConnectionList(){(result) in
             
             S_Log._F_(description: "특정 와이파이 SSID , PW 연결 리스트 확인 수행", data: ["\(result)"])
             
         }
         
        // -----------------------------------------
        3. 필요 import :
         
         import NetworkExtension
         import SystemConfiguration.CaptiveNetwork
        // -----------------------------------------
        4. 필요 권한 : 위치 권한 Location
         
         Privacy - Location Always Usage Description
         Privacy - Location Always and When In Use Usage Description
        // -----------------------------------------
        5. MARK: xcode 프로젝트 Capabillity 사용 설정 방법 : [Hotspot Configuration]
         
         - 사전) 유료 결제를 진행한 개발자 계정이 필요 (or 개발자 초대)
         - Xcode 프로젝트 설정 >> Capabillity >> Hotspot Configuration 추가
         - 프로젝트 entitlements 에서 추가한 Hotspot Configuration 권한이 정상 표시 되는 것 확인
         - 설정 및 적용 참고 사이트 :
         https://blog.naver.com/kkh0977/223669166907
         https://blog.naver.com/kkh0977/223669259799
        // -----------------------------------------
        */


        // [변수 선언]
        var M_LOG = ""
        C_Wifi_Ap_Module.configList = []

        
        // [로직 처리 수행]
        DispatchQueue.main.async {
            S_Log._D_(description: "특정 와이파이 SSID , PW 연결 리스트 확인 수행", data: nil)

            NEHotspotConfigurationManager.shared.getConfiguredSSIDs { (ssidsArray) in
                
                if ssidsArray != nil && ssidsArray.count > 0 {
                    
                    for ssid in ssidsArray {
                        C_Wifi_Ap_Module.configList.append(ssid) // [리스트에 추가]
                    }
                    
                    M_LOG = "[Success] : Search Ssid List"
                    
                    S_Log._D_(description: "특정 와이파이 SSID , PW 연결 리스트 확인 성공", data: [
                        "M_LOG :: \(M_LOG)",
                        "COUNT :: \(C_Wifi_Ap_Module.configList.count)",
                        "LIST :: \(C_Wifi_Ap_Module.configList)"
                    ])
                    completion(C_Wifi_Ap_Module.configList) // [콜백 반환]
                    return
                    
                }
                else {
                    M_LOG = "[Not Found] : Search Ssid List Is Null"
                    
                    S_Log._D_(description: "특정 와이파이 SSID , PW 연결 리스트 확인 실패", data: [ "M_LOG :: \(M_LOG)" ])
                    completion(C_Wifi_Ap_Module.configList) // [콜백 반환]
                    return
                }
                
            }

        }
    }
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : observableRemoveWifSsid : 특정 와이파이 SSID 연결 해제 수행
    // -----------------------------------------------------------------------------------------
    func observableRemoveWifSsid(ssid:String, completion: @escaping (Bool)->()) {
        
        /*
        // -----------------------------------------
        [observableRemoveWifSsid 메소드 설명]
        // -----------------------------------------
        1. 특정 와이파이 SSID 연결 해제 수행
        // -----------------------------------------
        2. 호출 방법 :
         
         C_Wifi_Ap_Module().observableRemoveWifSsid(ssid: "KKH"){(result) in
             
             S_Log._F_(description: "특정 와이파이 SSID 연결 해제 수행", data: ["\(result)"])
             
         }
         
        // -----------------------------------------
        3. 필요 import :
         
         import NetworkExtension
         import SystemConfiguration.CaptiveNetwork
        // -----------------------------------------
        4. 필요 권한 : 위치 권한 Location
         
         Privacy - Location Always Usage Description
         Privacy - Location Always and When In Use Usage Description
        // -----------------------------------------
        5. MARK: xcode 프로젝트 Capabillity 사용 설정 방법 : [Hotspot Configuration]
         
         - 사전) 유료 결제를 진행한 개발자 계정이 필요 (or 개발자 초대)
         - Xcode 프로젝트 설정 >> Capabillity >> Hotspot Configuration 추가
         - 프로젝트 entitlements 에서 추가한 Hotspot Configuration 권한이 정상 표시 되는 것 확인
         - 설정 및 적용 참고 사이트 :
         https://blog.naver.com/kkh0977/223669166907
         https://blog.naver.com/kkh0977/223669259799
        // -----------------------------------------
        */


        // [변수 선언]
        var returnData = false
        var M_LOG = ""

        
        // [로직 처리 수행]
        DispatchQueue.main.async {
            S_Log._D_(description: "특정 와이파이 SSID 연결 해제 수행", data: nil)
            
            // [인풋 데이터 널 체크]
            if C_Util().stringNotNull(str: ssid) == true {
                
                // [삭제 수행]
                NEHotspotConfigurationManager.shared.removeConfiguration(forSSID: ssid)
                
                // [리스트 확인해서 삭제 된 내역 확인]
                NEHotspotConfigurationManager.shared.getConfiguredSSIDs { (ssidsArray) in
                    
                    if ssidsArray.contains(ssid) == false { // [삭제 됨]
                        M_LOG = "[Success] : Ssid Remove"
                        returnData = true
                        
                        S_Log._D_(description: "특정 와이파이 SSID , PW 연결 해제 성공", data: [ "SSID :: \(ssid)", "M_LOG :: \(M_LOG)" ])
                        completion(returnData) // [콜백 반환]
                        return
                        
                    }
                    else {
                        M_LOG = "[Error] : Search Ssid List Found Ssid"
                        
                        S_Log._D_(description: "특정 와이파이 SSID , PW 연결 리스트 확인 실패", data: [ "M_LOG :: \(M_LOG)" ])
                        completion(returnData) // [콜백 반환]
                        return
                    }
                    
                }
                
            }
            else {
                M_LOG = "[Error] : Input Ssid Is Null"
                
                S_Log._D_(description: "특정 와이파이 SSID , PW 연결 해제 실패", data: [ "M_LOG :: \(M_LOG)" ])
                completion(returnData) // [콜백 반환]
                return
            }

        }
    }
    

    
} // [클래스 종료]

 

반응형
Comments