투케이2K

139. (TWOK/UTIL) [Ios/Swift] C_GraphQL_Client_Module : GraphQL 통신 수행 클라이언트 유틸 파일 본문

투케이2K 유틸파일

139. (TWOK/UTIL) [Ios/Swift] C_GraphQL_Client_Module : GraphQL 통신 수행 클라이언트 유틸 파일

투케이2K 2024. 10. 4. 20:19

[설 명]

프로그램 : Ios / Swift

설 명 : C_GraphQL_Client_Module : GraphQL 통신 수행 클라이언트 유틸 파일

 

[소스 코드]

 

import Foundation
import UIKit

class C_GraphQL_Client_Module {
    
    
    
    /**
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * TODO [클래스 설명]
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 1. GraphQL 네트워크 통신 수행 클래스
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * */
    
    
    
    
    
    
    /**
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * TODO [개념 설명]
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 1. GraphQL 요약 설명 :
     *
     * - GraphQL 은 페이스북에서 만든 쿼리 언어로, API 를 위한 쿼리 언어로 주로 사용됩니다
     * - GraphQL 서비스는 타입과 필드를 정의하고, 각 타입의 필드에 대한 함수로 구현됩니다
     * - GraphQL 서비스가 실행되면 GraphQL 쿼리를 전송하여 유효성 검사 및 실행 >> 수신된 쿼리는 정의된 타입과 필드를 참조해 함수를 실행하여 결과를 생성합니다
     * - GraphQL 서비스에는 Queries , Mutations , Subscriptions 방식이 있으며, 해당 방식을 통해 데이터 읽기 및 수정 등 다양한 통신을 시도할 수 있습니다
     * - REST API 는 URL, METHOD 등을 조합해 요청하는 방식으로 다양한 Endpoint 가 존재하지만, gql 은 단 하나의 Endpoint 를 사용하며 쿼리를 조합해 결과를 요청합니다
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 2. TODO Queries 설명 :
     *
     * - 쿼리는 읽기 전용으로 Http Get 방식과 유사하며, [서버에 정보 요청 >> 정보 조회 >> 응답 결과 반환] 방식으로 사용합니다
     * - 쿼리 사용시 정의 된 Query 키워드는 서버에 요청을 보내는 클라이언트의 모든 진입점을 정의합니다
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 3. TODO Mutations 설명 :
     *
     * - Mutations 은 쓰기 작업을 수행하며, Http Post , Put 방식과 유사하며, [서버에 수정 요청 >> 정보 수정 >> 응답 결과 반환] 방식으로 사용합니다
     * - Mutations 사용시 정의 된 Mutation 키워드는 서버에 요청을 보내는 클라이언트의 수정 요청의 진입점을 정의합니다
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 4. TODO Subscriptions 설명 :
     *
     * - Subscriptions (구독) 은 서버와 클라이언트 간의 지속적인 양방향 연결을 여는 WebSockets 에 사용됩니다
     * - Subscriptions 은 일반적으로 클라이언트가 서버를 구독 후 >> 실시간 변경 된 데이터에 관해 메시지를 수신 받을 때 사용합니다
     *   >> 서버 측 변경이 있거나 서버에서 이벤트를 수행할 때마다 구독한 클라이언트가 업데이트를 받게 됩니다
     * - Subscriptions 작성 예시 : 새로운 Person이 추가될 때마다 구독한 클라이언트에게 메시지를 보냅니다
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 5. 개념 설명 및 테스트 참고 사이트 :
     *
     * https://docs.aws.amazon.com/ko_kr/appsync/latest/devguide/graphql-types.html
     *
     * https://www.postman.com/postman/published-postman-templates/graphql-request/63ce7518fe63376ed0693d9e
     *
     * https://lucasconstantino.github.io/graphiql-online/
     *
     * https://stackoverflow.com/questions/66010484/how-to-excute-graphql-query-with-okhttpclient
     *
     * https://docs.aws.amazon.com/ko_kr/appsync/latest/devguide/real-time-websocket-client.html
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * */





    /**
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * TODO [빠른 로직 찾기 : 주석 로직 찾기]
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : requestQueriesHttp
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : requestMutationHttp
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * [SEARCH FAST] : requestSubscriptionHttp
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     *
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     */
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [전역 변수 선언]
    // -----------------------------------------------------------------------------------------
    private static let ACTIVITY_NAME = "C_GraphQL_Client_Module"
    
    private static let TIME_OUT = 30.0
    
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : requestQueriesHttp
    // -----------------------------------------------------------------------------------------
    func requestQueriesHttp(tag: String, url: String, header: Dictionary<String, Any>?, graphql: String?, completion: @escaping (Bool, String)->()) {
        
        /*
         // -----------------------------------------
         [requestQueriesHttp 메소드 설명]
         // -----------------------------------------
         1. 비동기 POST 방식 graphql HTTP 통신 수행 및 콜백 반환 실시
         // -----------------------------------------
         2. 호출 방법 :
         
         let tag_ = "GraphQL HTTP 요청"
         let url_ = "https://graphql.postman-echo.com/graphql"
         let header_ : Dictionary<String, Any> = [:]
         var graphql_ = ""
         graphql_ += "query Hello {\n" +
                         "    hello\n" +
                         "}"
         
         
         C_GraphQL_Client_Module().requestQueriesHttp(tag: tag_, url: url_, header: header_, graphql: graphql_){(result, response) in
             
             S_Log._F_(description: "HTTP 콜백 결과 확인", data: [response])
             
         }
         // -----------------------------------------
         3. 사전 설정 사항 :
         
         - 필요 info plist 설정
         [1] http 허용 : App Transport Security Settings >> Allow Arbitrary Loads >> YES
         // -----------------------------------------
         */
        
        
        /*
        ================================================================
        LOG :: TYPE :: FILE :: 🔵
        -------------------------------------------------
        LOG :: CLASS PLACE :: C_GraphQL_Client_Module.swift :: requestQueriesHttp(tag:url:header:graphql:completion:) :: 269
        -------------------------------------------------
        LOG :: NOW TIME :: 2024-09-06 19:32:36
        -------------------------------------------------
        LOG :: DESCRIPTION :: GraphQL Queries Http [결과] 확인
        -------------------------------------------------
        LOG :: TAG :: GraphQL HTTP 요청
        -------------------------------------------------
        LOG :: TYPE :: POST >> RESPONSE
        -------------------------------------------------
        LOG :: URL :: https://graphql.postman-echo.com/graphql
        -------------------------------------------------
        LOG :: HEADER :: Optional([:])
        -------------------------------------------------
        LOG :: PARAMS :: ["query": "query Hello {\n    hello\n}"]
        -------------------------------------------------
        LOG :: STATUS CODE :: 200
        -------------------------------------------------
        LOG :: RESPONSE DATA :: {"data":{"hello":"Hello John Doe"}}
        ================================================================
        // */
        
        
        // -----------------------------------------
        // [사전 방어 로직 체크]
        // -----------------------------------------
        if url.startsWith(_string: "http") == false {
            
            // [콜백 반환]
            completion(false, "[ERROR] :: Url Http Not Start")
            return
        }
        // -----------------------------------------
        if String(describing: graphql ?? "").startsWith(_string: "query") == false {
            
            // [콜백 반환]
            completion(false, "[ERROR] :: graphql start string error")
            return
        }
        // -----------------------------------------
        
        
        
        // -----------------------------------------
        // [url 선언 실시]
        // -----------------------------------------
        let urlData = String(describing: url)
        // -----------------------------------------
        
        
        // -----------------------------------------
        // [body json 생성]
        // -----------------------------------------
        let params : Dictionary<String, Any> = ["query": String(describing: graphql ?? "")]
    
        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 = "POST"
        
        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._F_(description: "GraphQL Queries Http [요청] 수행", data: [
            "TAG :: " + String(describing: tag),
            "TYPE :: POST >> REQUEST",
            "URL :: " + String(describing: urlData),
            "HEADER :: " + String(describing: header),
            "PARAMS :: " + String(describing: params),
        ])
        
        
        // -----------------------------------------
        // [http 요쳥을 위한 URLSessionDataTask 생성]
        // -----------------------------------------
        let sessionConfig = URLSessionConfiguration.default
        sessionConfig.timeoutIntervalForRequest = C_GraphQL_Client_Module.TIME_OUT // [커넥션 타임 아웃 설정]
        sessionConfig.timeoutIntervalForResource = C_GraphQL_Client_Module.TIME_OUT // [리소스 읽기 , 쓰기]
        
        let session = URLSession(configuration: sessionConfig)
        
        S_FileManager.appHttpLogSave(description: String(describing: tag), request: requestURL, data: nil, response: nil, error: nil)
        
        let dataTask = session.dataTask(with: requestURL, completionHandler: { (data, response, error) in
            
            S_FileManager.appHttpLogSave(description: nil, request: nil, data: data, response: response as? HTTPURLResponse, error: error)

            // [error가 존재하면 종료]
            guard error == nil else {
                S_Log._F_(description: "GraphQL Queries Http [결과] 실패", data: [
                    "TAG :: " + String(describing: tag),
                    "TYPE :: POST >> FAIL",
                    "URL :: " + String(describing: urlData),
                    "HEADER :: " + String(describing: header),
                    "PARAMS :: " + String(describing: params),
                    "ERROR :: \(error?.localizedDescription ?? "")"
                ])
                
                // [콜백 반환]
                completion(false, "[ERROR] :: \(error?.localizedDescription ?? "")")
                return
            }

            
            // [status 코드 체크 실시]
            let successsRange = 200..<300
            guard let statusCode = (response as? HTTPURLResponse)?.statusCode, successsRange.contains(statusCode)
            else {
                S_Log._F_(description: "GraphQL Queries Http [결과] 에러", data: [
                    "TAG :: " + String(describing: tag),
                    "TYPE :: POST >> 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 ?? "")")
                return
            }

            
            // [response 데이터 획득]
            let resultCode = (response as? HTTPURLResponse)?.statusCode ?? 0 // [상태 코드]
            let resultData = String(data: data!, encoding: .utf8) ?? "" // [데이터 확인]
            
            S_Log._F_(description: "GraphQL Queries Http [결과] 확인", data: [
                "TAG :: " + String(describing: tag),
                "TYPE :: POST >> 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)
        })

        
        // [network 통신 실행]
        dataTask.resume()
    }
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : requestMutationHttp
    // -----------------------------------------------------------------------------------------
    func requestMutationHttp(tag: String, url: String, header: Dictionary<String, Any>?, graphql: String?, completion: @escaping (Bool, String)->()) {
        
        /*
         // -----------------------------------------
         [requestMutationHttp 메소드 설명]
         // -----------------------------------------
         1. 비동기 POST 방식 graphql HTTP 통신 수행 및 콜백 반환 실시
         // -----------------------------------------
         2. 호출 방법 :
         
         let tag_ = "GraphQL HTTP 요청"
         let url_ = "https://graphql.postman-echo.com/graphql"
         let header_ : Dictionary<String, Any> = [:]
         var graphql_ = ""
         graphql_ += "mutation CreatePerson {\n" +
                         "    createPerson(person: {name: \"Larry David\", age: 47}) {\n" +
                         "        age\n" +
                         "        id\n" +
                         "        name\n" +
                         "    }\n" +
                         "}"
         
         
         C_GraphQL_Client_Module().requestMutationHttp(tag: tag_, url: url_, header: header_, graphql: graphql_){(result, response) in
             
             S_Log._F_(description: "HTTP 콜백 결과 확인", data: [response])
             
         }
         // -----------------------------------------
         3. 사전 설정 사항 :
         
         - 필요 info plist 설정
         [1] http 허용 : App Transport Security Settings >> Allow Arbitrary Loads >> YES
         // -----------------------------------------
         */
        
        
        /*
         ================================================================
         LOG :: TYPE :: FILE :: 🔵
         -------------------------------------------------
         LOG :: CLASS PLACE :: C_GraphQL_Client_Module.swift :: requestMutationHttp(tag:url:header:graphql:completion:) :: 499
         -------------------------------------------------
         LOG :: NOW TIME :: 2024-09-06 21:28:35
         -------------------------------------------------
         LOG :: DESCRIPTION :: GraphQL Mutation Http [결과] 확인
         -------------------------------------------------
         LOG :: TAG :: GraphQL HTTP 요청
         -------------------------------------------------
         LOG :: TYPE :: POST >> RESPONSE
         -------------------------------------------------
         LOG :: URL :: https://graphql.postman-echo.com/graphql
         -------------------------------------------------
         LOG :: HEADER :: Optional([:])
         -------------------------------------------------
         LOG :: PARAMS :: ["query": "mutation CreatePerson {\n    createPerson(person: {name: \"Larry David\", age: 47}) {\n        age\n        id\n        name\n    }\n}"]
         -------------------------------------------------
         LOG :: STATUS CODE :: 200
         -------------------------------------------------
         LOG :: RESPONSE DATA :: {"data":{"createPerson":{"age":47,"id":"68","name":"Larry David"}}}
         ================================================================
        // */
        
        
        // -----------------------------------------
        // [사전 방어 로직 체크]
        // -----------------------------------------

        if url.startsWith(_string: "http") == false {
            
            // [콜백 반환]
            completion(false, "[ERROR] :: Url Http Not Start")
            return
        }
        // -----------------------------------------
        if String(describing: graphql ?? "").startsWith(_string: "mutation") == false {
            
            // [콜백 반환]
            completion(false, "[ERROR] :: graphql start string error")
            return
        }
        // -----------------------------------------
        
        
        
        // -----------------------------------------
        // [url 선언 실시]
        // -----------------------------------------
        let urlData = String(describing: url)
        // -----------------------------------------
        
        
        // -----------------------------------------
        // [body json 생성]
        // -----------------------------------------
        let params : Dictionary<String, Any> = ["query": String(describing: graphql ?? "")]
    
        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 = "POST"
        
        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._F_(description: "GraphQL Mutation Http [요청] 수행", data: [
            "TAG :: " + String(describing: tag),
            "TYPE :: POST >> REQUEST",
            "URL :: " + String(describing: urlData),
            "HEADER :: " + String(describing: header),
            "PARAMS :: " + String(describing: params),
        ])
        
        
        // -----------------------------------------
        // [http 요쳥을 위한 URLSessionDataTask 생성]
        // -----------------------------------------
        let sessionConfig = URLSessionConfiguration.default
        sessionConfig.timeoutIntervalForRequest = C_GraphQL_Client_Module.TIME_OUT // [커넥션 타임 아웃 설정]
        sessionConfig.timeoutIntervalForResource = C_GraphQL_Client_Module.TIME_OUT // [리소스 읽기 , 쓰기]
        
        let session = URLSession(configuration: sessionConfig)
        
        S_FileManager.appHttpLogSave(description: String(describing: tag), request: requestURL, data: nil, response: nil, error: nil)
        
        let dataTask = session.dataTask(with: requestURL, completionHandler: { (data, response, error) in
            
            S_FileManager.appHttpLogSave(description: nil, request: nil, data: data, response: response as? HTTPURLResponse, error: error)

            // [error가 존재하면 종료]
            guard error == nil else {
                S_Log._F_(description: "GraphQL Mutation Http [결과] 실패", data: [
                    "TAG :: " + String(describing: tag),
                    "TYPE :: POST >> FAIL",
                    "URL :: " + String(describing: urlData),
                    "HEADER :: " + String(describing: header),
                    "PARAMS :: " + String(describing: params),
                    "ERROR :: \(error?.localizedDescription ?? "")"
                ])
                
                // [콜백 반환]
                completion(false, "[ERROR] :: \(error?.localizedDescription ?? "")")
                return
            }

            
            // [status 코드 체크 실시]
            let successsRange = 200..<300
            guard let statusCode = (response as? HTTPURLResponse)?.statusCode, successsRange.contains(statusCode)
            else {
                S_Log._F_(description: "GraphQL Mutation Http [결과] 에러", data: [
                    "TAG :: " + String(describing: tag),
                    "TYPE :: POST >> 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 ?? "")")
                return
            }

            
            // [response 데이터 획득]
            let resultCode = (response as? HTTPURLResponse)?.statusCode ?? 0 // [상태 코드]
            let resultData = String(data: data!, encoding: .utf8) ?? "" // [데이터 확인]
            
            S_Log._F_(description: "GraphQL Mutation Http [결과] 확인", data: [
                "TAG :: " + String(describing: tag),
                "TYPE :: POST >> 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)
        })

        
        // [network 통신 실행]
        dataTask.resume()
    }
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [SEARCH FAST] : requestSubscriptionHttp
    // -----------------------------------------------------------------------------------------
    func requestSubscriptionHttp(tag: String, url: String, header: Dictionary<String, Any>?, graphql: String?, completion: @escaping (Bool, String)->()) {
        
        /*
         // -----------------------------------------
         [requestSubscriptionHttp 메소드 설명]
         // -----------------------------------------
         1. 비동기 POST 방식 graphql HTTP 통신 수행 및 콜백 반환 실시
         // -----------------------------------------
         2. 호출 방법 :
         
         let tag_ = "GraphQL HTTP 요청"
         let url_ = "https://graphql.postman-echo.com/graphql"
         let header_ : Dictionary<String, Any> = [:]
         var graphql_ = ""
         graphql_ += "subscription Greetings {\n" +
                                     "    greetings\n" +
                                     "}"
         
         
         C_GraphQL_Client_Module().requestSubscriptionHttp(tag: tag_, url: url_, header: header_, graphql: graphql_){(result, response) in
             
             S_Log._F_(description: "HTTP 콜백 결과 확인", data: [response])
             
         }
         // -----------------------------------------
         3. 사전 설정 사항 :
         
         - 필요 info plist 설정
         [1] http 허용 : App Transport Security Settings >> Allow Arbitrary Loads >> YES
         // -----------------------------------------
         */
        
        
        /*
         ================================================================
         LOG :: TYPE :: FILE :: 🔵
         -------------------------------------------------
         LOG :: CLASS PLACE :: C_GraphQL_Client_Module.swift :: requestSubscriptionHttp(tag:url:header:graphql:completion:) :: 720
         -------------------------------------------------
         LOG :: NOW TIME :: 2024-09-06 21:41:13
         -------------------------------------------------
         LOG :: DESCRIPTION :: GraphQL Subscription Http [결과] 확인
         -------------------------------------------------
         LOG :: TAG :: GraphQL HTTP 요청
         -------------------------------------------------
         LOG :: TYPE :: POST >> RESPONSE
         -------------------------------------------------
         LOG :: URL :: https://graphql.postman-echo.com/graphql
         -------------------------------------------------
         LOG :: HEADER :: Optional([:])
         -------------------------------------------------
         LOG :: PARAMS :: ["query": "subscription Greetings {\n    greetings\n}"]
         -------------------------------------------------
         LOG :: STATUS CODE :: 200
         -------------------------------------------------
         LOG :: RESPONSE DATA :: :

         event: next
         data: {"data":{"greetings":"Hi"}}

         event: next
         data: {"data":{"greetings":"Bonjour"}}

         event: next
         data: {"data":{"greetings":"Hola"}}

         event: next
         data: {"data":{"greetings":"Ciao"}}

         event: next
         data: {"data":{"greetings":"Zdravo"}}

         event: complete
         data:
         ================================================================
        // */
        
        
        // -----------------------------------------
        // [사전 방어 로직 체크]
        // -----------------------------------------
        if url.startsWith(_string: "http") == false {
            
            // [콜백 반환]
            completion(false, "[ERROR] :: Url Http Not Start")
            return
        }
        // -----------------------------------------
        if String(describing: graphql ?? "").startsWith(_string: "subscription") == false {
            
            // [콜백 반환]
            completion(false, "[ERROR] :: graphql start string error")
            return
        }
        // -----------------------------------------
        
        
        
        // -----------------------------------------
        // [url 선언 실시]
        // -----------------------------------------
        let urlData = String(describing: url)
        // -----------------------------------------
        
        
        // -----------------------------------------
        // [body json 생성]
        // -----------------------------------------
        let params : Dictionary<String, Any> = ["query": String(describing: graphql ?? "")]
    
        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 = "POST"
        
        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._F_(description: "GraphQL Subscription Http [요청] 수행", data: [
            "TAG :: " + String(describing: tag),
            "TYPE :: POST >> REQUEST",
            "URL :: " + String(describing: urlData),
            "HEADER :: " + String(describing: header),
            "PARAMS :: " + String(describing: params),
        ])
        
        
        // -----------------------------------------
        // [http 요쳥을 위한 URLSessionDataTask 생성]
        // -----------------------------------------
        let sessionConfig = URLSessionConfiguration.default
        sessionConfig.timeoutIntervalForRequest = C_GraphQL_Client_Module.TIME_OUT // [커넥션 타임 아웃 설정]
        sessionConfig.timeoutIntervalForResource = C_GraphQL_Client_Module.TIME_OUT // [리소스 읽기 , 쓰기]
        
        let session = URLSession(configuration: sessionConfig)
        
        S_FileManager.appHttpLogSave(description: String(describing: tag), request: requestURL, data: nil, response: nil, error: nil)
        
        let dataTask = session.dataTask(with: requestURL, completionHandler: { (data, response, error) in
            
            S_FileManager.appHttpLogSave(description: nil, request: nil, data: data, response: response as? HTTPURLResponse, error: error)

            // [error가 존재하면 종료]
            guard error == nil else {
                S_Log._F_(description: "GraphQL Subscription Http [결과] 실패", data: [
                    "TAG :: " + String(describing: tag),
                    "TYPE :: POST >> FAIL",
                    "URL :: " + String(describing: urlData),
                    "HEADER :: " + String(describing: header),
                    "PARAMS :: " + String(describing: params),
                    "ERROR :: \(error?.localizedDescription ?? "")"
                ])
                
                // [콜백 반환]
                completion(false, "[ERROR] :: \(error?.localizedDescription ?? "")")
                return
            }

            
            // [status 코드 체크 실시]
            let successsRange = 200..<300
            guard let statusCode = (response as? HTTPURLResponse)?.statusCode, successsRange.contains(statusCode)
            else {
                S_Log._F_(description: "GraphQL Subscription Http [결과] 에러", data: [
                    "TAG :: " + String(describing: tag),
                    "TYPE :: POST >> 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 ?? "")")
                return
            }

            
            // [response 데이터 획득]
            let resultCode = (response as? HTTPURLResponse)?.statusCode ?? 0 // [상태 코드]
            let resultData = String(data: data!, encoding: .utf8) ?? "" // [데이터 확인]
            
            S_Log._F_(description: "GraphQL Subscription Http [결과] 확인", data: [
                "TAG :: " + String(describing: tag),
                "TYPE :: POST >> 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)
        })

        
        // [network 통신 실행]
        dataTask.resume()
    }
    

    
} // [클래스 종료]

 

반응형
Comments