투케이2K

341. (ios/swift5) URLSession 사용해 HTTP 통신 동기 방식 SYNC POST BODY JSON 요청 수행 실시 본문

IOS

341. (ios/swift5) URLSession 사용해 HTTP 통신 동기 방식 SYNC POST BODY JSON 요청 수행 실시

투케이2K 2023. 10. 8. 13:57

[개발 환경 설정]

개발 툴 : XCODE

개발 언어 : SWIFT5

 

[소스 코드]

 

    // -----------------------------------------------------------------------------------------
    // MARK: - [PUT 방식 Body Json HTTP 통신 수행]
    // -----------------------------------------------------------------------------------------
    func requestPutBodyJsonHttp(tag: String, url: String, header: Dictionary<String, Any>?, params: Dictionary<String, Any>?, completion: @escaping (Bool, String)->()) {
        
        /*
         // -----------------------------------------
         [requestPutBodyJsonHttp 메소드 설명]
         // -----------------------------------------
         1. 동기 PUT 방식 Body Json HTTP 통신 수행 및 콜백 반환 실시
         // -----------------------------------------
         2. 호출 방법 :
         
         let tag_ = "테스트 json 요청"
         let url_ = "http://jsonplaceholder.typicode.com/posts/1"
         let header_ : Dictionary<String, Any> = [:]
         let params_ : Dictionary<String, Any> = ["userId":1 , "id":1, "bar":"foo", "title":"foo"]
         
         
         N_SyncHttp().requestPutBodyJsonHttp(tag: tag_, url: url_, header: header_, params: params_){(result, response) in
             
             S_Log._D_(description: "HTTP 콜백 결과 확인", data: [response])
             
         }
         
         S_Log._D_(description: "HTTP 로직 종료", data: nil)
         // -----------------------------------------
         3. 사전 설정 사항 :
         
         - 필요 info plist 설정
         [1] http 허용 : App Transport Security Settings >> Allow Arbitrary Loads >> YES
         // -----------------------------------------
         */
        
        
        // -----------------------------------------
        // [세마포어 선언 : 프로그램 로직을 동기화 구현]
        // -----------------------------------------
        let semaphore = DispatchSemaphore(value: 0) // [value 0 값은 대기 상태 선언]
        
        
        // -----------------------------------------
        // [url 선언 실시]
        // -----------------------------------------
        var urlData = String(describing: url)
        // -----------------------------------------
        
        
        // -----------------------------------------
        // [body json 생성]
        // -----------------------------------------
        var jsonData: Data? = nil
        if C_Util().dicNotNull(dic_: params) == true {
            
            jsonData = try! JSONSerialization.data(withJSONObject: params!, options: [])
            
        }
        
        // -----------------------------------------
        
        
        // -----------------------------------------
        // [URLRequest 생성 실시]
        // -----------------------------------------
        let urlComponents = URLComponents(string: urlData)
        var requestURL = URLRequest(url: (urlComponents?.url)!)
        
        requestURL.httpMethod = "PUT"
        
        requestURL.addValue("application/json", forHTTPHeaderField: "Content-Type") // header settings
        requestURL.addValue("no-cache", forHTTPHeaderField: "Cache-Control") // header settings
        
        if C_Util().dicNotNull(dic_: header) == true {
            
            for key in header!.keys {
                
                requestURL.addValue("\(String(describing: header![key] ?? ""))", forHTTPHeaderField: "\(key)")
                
            }

        }
        
        
        // [body 데이터 삽입]
        if jsonData != nil {
            requestURL.httpBody = jsonData // Body 부분에 Json 데이터 삽입 실시
        }
        
        
        S_Log._D_(description: "동기 PUT 방식 Body Json HTTP [요청] 수행", data: [
            "TAG :: " + String(describing: tag),
            "TYPE :: PUT >> REQUEST",
            "URL :: " + String(describing: urlData),
            "HEADER :: " + String(describing: header),
            "PARAMS :: " + String(describing: params),
        ])
        
        
        // -----------------------------------------
        // [http 요쳥을 위한 URLSessionDataTask 생성]
        // -----------------------------------------
        let sessionConfig = URLSessionConfiguration.default
        sessionConfig.timeoutIntervalForRequest = N_SyncHttp.connectTimeout // [커넥션 타임 아웃 설정]
        let session = URLSession(configuration: sessionConfig)
        
        let dataTask = session.dataTask(with: requestURL, completionHandler: { (data, response, error) in

            // [error가 존재하면 종료]
            guard error == nil else {
                S_Log._D_(description: "동기 PUT 방식 Body Json HTTP [결과] 실패", data: [
                    "TAG :: " + String(describing: tag),
                    "TYPE :: PUT >> FAIL",
                    "URL :: " + String(describing: urlData),
                    "HEADER :: " + String(describing: header),
                    "PARAMS :: " + String(describing: params),
                    "ERROR :: \(error?.localizedDescription ?? "")"
                ])
                
                // [콜백 반환]
                completion(false, "[ERROR] :: \(error?.localizedDescription ?? "")")
                
                // [세마 포어 종료]
                semaphore.signal()
                return
            }

            
            // [status 코드 체크 실시]
            let successsRange = 200..<300
            guard let statusCode = (response as? HTTPURLResponse)?.statusCode, successsRange.contains(statusCode)
            else {
                S_Log._D_(description: "동기 PUT 방식 Body Json HTTP [결과] 에러", data: [
                    "TAG :: " + String(describing: tag),
                    "TYPE :: PUT >> ERROR",
                    "URL :: " + String(describing: urlData),
                    "HEADER :: " + String(describing: header),
                    "PARAMS :: " + String(describing: params),
                    "STATUS CODE :: " + String(describing: (response as? HTTPURLResponse)?.statusCode ?? 0),
                    "RESPONSE DATA :: \((response as? HTTPURLResponse)?.description ?? "")"
                ])
                
                // [콜백 반환]
                completion(false, "[ERROR] :: \((response as? HTTPURLResponse)?.description ?? "")")
                
                // [세마 포어 종료]
                semaphore.signal()
                return
            }

            
            // [response 데이터 획득]
            let resultCode = (response as? HTTPURLResponse)?.statusCode ?? 0 // [상태 코드]
            let resultData = String(data: data!, encoding: .utf8) ?? "" // [데이터 확인]
            
            S_Log._D_(description: "동기 PUT 방식 Body Json HTTP [결과] 확인", data: [
                "TAG :: " + String(describing: tag),
                "TYPE :: PUT >> RESPONSE",
                "URL :: " + String(describing: urlData),
                "HEADER :: " + String(describing: header),
                "PARAMS :: " + String(describing: params),
                "STATUS CODE :: " + String(describing: resultCode),
                "RESPONSE DATA :: " + String(describing: resultData)
            ])
            
            // [콜백 반환]
            completion(true, resultData)
            
            // [세마 포어 종료]
            semaphore.signal()
        })

        
        // [network 통신 실행]
        dataTask.resume()
        
        
        // [동기화 대기]
        semaphore.wait()
    }

반응형
Comments