투케이2K

45. (ios/swift) http 통신 동기 요청 및 리턴 결과 확인 - URLSession , 세마포어 , DispatchSemaphore 본문

IOS

45. (ios/swift) http 통신 동기 요청 및 리턴 결과 확인 - URLSession , 세마포어 , DispatchSemaphore

투케이2K 2021. 11. 7. 10:02

[개발 환경 설정]

개발 툴 : XCODE

개발 언어 : SWIFT


[필요 설정]


[소스 코드]

    // MARK: - [테스트 메인 메소드]
    func testMain() {
        
        /*
        [요약 설명]
        1. 세마포어를 사용해서 네트워크 통신 프로그램 로직을 동기식으로 구현할 수 있습니다
        2. 세마포어 0 값을 사용 시 통신 대기 상태를 의미합니다
        3. 동기식 통신 : 네트워크 통신 결과 값을 확인 후 순차적으로 하위 로직을 수행합니다
        */
        let checkDic : Dictionary<String, Any> = requestSyncGetHttp()
        print("")
        print("===============================")
        print("[A_Main >> testMain() :: http 동기 get 요청 확인]")
        print("flag :: ", checkDic["responseFlag"] ?? false)
        print("msg :: ", checkDic["responseMsg"] ?? "")
        print("===============================")
        print("")
    }
    
    
    
    // MARK: - [동기 GET 요청 실시 : 쿼리 파라미터]
    func requestSyncGetHttp() -> Dictionary<String, Any> {
        // [http 통신 요청 후 응답 값 반환 변수]
        var responseDic : Dictionary<String, Any> = [String : Any]()
        
        
        // [세마포어 선언 : 프로그램 로직을 동기화 구현]
        let semaphore = DispatchSemaphore(value: 0) // [value 0 값은 대기 상태 선언]
        
        
        // [URL 지정 및 파라미터 값 지정 실시]
        var urlComponents = URLComponents(string: "https://jsonplaceholder.typicode.com/posts?")
        let paramQuery_1 = URLQueryItem(name: "userId", value: "1")
        let paramQuery_2 = URLQueryItem(name: "id", value: "1")
        urlComponents?.queryItems?.append(paramQuery_1) // 파라미터 지정
        urlComponents?.queryItems?.append(paramQuery_2) // 파라미터 지정
        
        
        // [http 통신 타입 및 헤더 지정 실시]
        var requestURL = URLRequest(url: (urlComponents?.url)!)
        requestURL.httpMethod = "GET" // GET
        requestURL.addValue("application/x-www-form-urlencoded; charset=utf-8;", forHTTPHeaderField: "Content-Type") // GET

        
        // [http 요쳥을 위한 URLSessionDataTask 생성]
        print("")
        print("====================================")
        print("[requestSyncGetHttp : http 동기 get 요청 실시]")
        print("url : ", requestURL)
        print("====================================")
        print("")
        let dataTask = URLSession.shared.dataTask(with: requestURL, completionHandler: { (data, response, error) in

            // [error가 존재하면 종료]
            guard error == nil else {
                print("")
                print("====================================")
                print("[requestSyncGetHttp : http 동기 get 요청 실패]")
                print("fail : ", error?.localizedDescription ?? "")
                print("====================================")
                print("")
                // [리턴 값 삽입]
                responseDic["responseFlag"] = false
                responseDic["responseMsg"] = error?.localizedDescription ?? ""
                
                // [네트워크 통신이 끝난 경우 신호 알림]
                semaphore.signal()
                return
            }

            // [status 코드 체크 실시]
            let successsRange = 200..<300
            guard let statusCode = (response as? HTTPURLResponse)?.statusCode, successsRange.contains(statusCode)
            else {
                print("")
                print("====================================")
                print("[requestSyncGetHttp : http 동기 get 요청 에러]")
                print("error : ", (response as? HTTPURLResponse)?.statusCode ?? 0)
                print("msg : ", (response as? HTTPURLResponse)?.description ?? "")
                print("====================================")
                print("")
                // [리턴 값 삽입]
                responseDic["responseFlag"] = false
                responseDic["responseMsg"] = (response as? HTTPURLResponse)?.description ?? ""
                
                // [네트워크 통신이 끝난 경우 신호 알림]
                semaphore.signal()
                return
            }

            // [response 데이터 획득, utf8인코딩을 통해 string형태로 변환]
            let resultCode = (response as? HTTPURLResponse)?.statusCode ?? 0
            let resultLen = data! // 데이터 길이
            let resultString = String(data: resultLen, encoding: .utf8) ?? "" // 응답 메시지
            print("")
            print("====================================")
            print("[requestSyncGetHttp : http 동기 get 요청 성공]")
            print("resultCode : ", resultCode)
            print("resultLen : ", resultLen)
            print("resultString : ", resultString)
            print("====================================")
            print("")
            // [리턴 값 삽입]
            responseDic["responseFlag"] = true
            responseDic["responseMsg"] = resultString
            
            // [네트워크 통신이 끝난 경우 신호 알림]
            semaphore.signal()
        })

        // [network 통신 실행]
        dataTask.resume()
        
        // [네트워크 통신 동기화 대기]
        semaphore.wait()
        
        // [통신 결과 반환 실시]
        return responseDic
    }

 


[결과 출력]


 

반응형
Comments