투케이2K

165. (ios/swift) URLSession get 방식 파일 다운로드 및 커넥션 타임 아웃 설정 , response header Content-Disposition 확인 본문

IOS

165. (ios/swift) URLSession get 방식 파일 다운로드 및 커넥션 타임 아웃 설정 , response header Content-Disposition 확인

투케이2K 2022. 8. 12. 12:49

[개발 환경 설정]

개발 툴 : XCODE

개발 언어 : SWIFT

 

[소스 코드]

            // [http 비동기 방식을 사용해서 파일 다운로드 및 저장 수행 실시]
            var urlComponents = URLComponents(string: fileUrl)
            var requestURL = URLRequest(url: (urlComponents?.url)!)
            requestURL.httpMethod = "GET" // GET
            requestURL.addValue("application/x-www-form-urlencoded; charset=utf-8;", forHTTPHeaderField: "Content-Type") // GET
            print("")
            print("===============================")
            print("[C_Util >> submitDownloadFile() :: http 통신 파일 다운로드 요청 실시]")
            print("-------------------------------")
            print("주 소 :: ", requestURL)
            print("===============================")
            print("")
            
            
            // [http 요쳥을 위한 URLSessionDataTask 생성]
            let sessionConfig = URLSessionConfiguration.default
            sessionConfig.timeoutIntervalForRequest = 10.0 // [커넥션 타임 아웃 설정]
            let session = URLSession(configuration: sessionConfig)
            
            let dataTask = session.dataTask(with: requestURL, completionHandler: { (data, response, error) in

                // [error가 존재하면 종료]
                guard error == nil else {
                    print("")
                    print("===============================")
                    print("[C_Util >> submitDownloadFile() :: http 통신 파일 다운로드 요청 실패]")
                    print("-------------------------------")
                    print("주 소 :: ", requestURL)
                    print("-------------------------------")
                    print("fail :: ", error?.localizedDescription ?? "")
                    print("===============================")
                    print("")
                    return
                }

                // [status 코드 체크 실시]
                let successsRange = 200..<300
                guard let statusCode = (response as? HTTPURLResponse)?.statusCode, successsRange.contains(statusCode)
                else {
                    print("")
                    print("===============================")
                    print("[C_Util >> submitDownloadFile() :: http 통신 파일 다운로드 요청 에러]")
                    print("-------------------------------")
                    print("주 소 :: ", requestURL)
                    print("-------------------------------")
                    print("error :: ", (response as? HTTPURLResponse)?.statusCode ?? 0)
                    print("-------------------------------")
                    print("msg :: ", (response as? HTTPURLResponse)?.description ?? "")
                    print("===============================")
                    print("")
                    return
                }

                
                // [response 데이터 획득]
                let resultHeader : [AnyHashable : Any] = (response as? HTTPURLResponse)!.allHeaderFields
                let resultDic = resultHeader as! [String: Any]
                let resultCode = (response as? HTTPURLResponse)?.statusCode ?? 0
                let resultLen = data! // 데이터 길이
                
                
                // MARK: [파일 제목 파싱 실시 : "Content-Disposition": attachment;filename="test.png"]
                var fileName = "";
                if resultDic.keys.contains("Content-Disposition") == true {
                    fileName = String(describing: resultDic["Content-Disposition"] ?? "")
                }
                else {
                    print("")
                    print("===============================")
                    print("[C_Util >> submitDownloadFile() :: http 통신 파일 저장 [실패]]")
                    print("-------------------------------")
                    print("error :: ", "response header Content-Disposition is null")
                    print("===============================")
                    print("")
                    return
                }
                
                
                // MARK: [response header filename 포함 확인]
                if fileName.contains("filename=") == false { // [파일 이름 없음]
                    print("")
                    print("===============================")
                    print("[C_Util >> submitDownloadFile() :: http 통신 파일 저장 [실패]]")
                    print("-------------------------------")
                    print("error :: ", "Content-Disposition filename is null")
                    print("===============================")
                    print("")
                    return
                }
                
                
                // MARK: [파일 확장자가 포함 된 것 인지 확인]
                if fileName.contains(".") == false { // [파일 확장자 없음]
                    print("")
                    print("===============================")
                    print("[C_Util >> submitDownloadFile() :: http 통신 파일 저장 [실패]]")
                    print("-------------------------------")
                    print("error :: ", "file extensions is null [1]")
                    print("===============================")
                    print("")
                    return
                }
                
                
                // MARK: [데이터 파싱 수행 실시]
                fileName = fileName.replaceAll(_string: " ", _replace: "")
                //fileName = fileName.replaceAll(_string: "attachment;filename=", _replace: "")
                
                
                var arrayData = fileName.components(separatedBy: ";") // [attachment;filename="test.jpg"]
                //var arrayData : Array<String> = []

                
                if arrayData != nil && arrayData.isEmpty == false && arrayData.count>0 {
                    for i in stride(from: 0, through: arrayData.count-1, by: 1) {
                        let parseString = String(describing: arrayData[i])
                        if (parseString.contains("filename=")){ // [filename="peng.jpg"]
                            fileName = parseString.replaceAll(_string: "filename=", _replace: "") // ["test.jpg"]
                            
                            // [URL 디코딩 수행]
                            fileName = String(describing: fileName.removingPercentEncoding ?? "")
                        }
                    }
                }
                else {
                    print("")
                    print("===============================")
                    print("[C_Util >> submitDownloadFile() :: http 통신 파일 저장 [실패]]")
                    print("-------------------------------")
                    print("error :: ", "array data parsing size is null")
                    print("===============================")
                    print("")
                    return
                }
                
                
                if fileName.hasPrefix("\"") == true {
                    fileName = fileName.subString(_start: 1, _end: fileName.count-1)
                }
                if fileName.hasSuffix("\"") == true {
                    fileName = fileName.subString(_start: 0, _end: fileName.count-2)
                }
                fileName = fileName.trim()
                
                
                // [파일 확장자명 검사 실시]
                let extensionUrl = NSURL(fileURLWithPath: fileName)
                var fileExtension = String(describing: extensionUrl.pathExtension ?? "")
                fileExtension = fileExtension.trim()
                
                print("")
                print("===============================")
                print("[C_Util >> submitDownloadFile() :: http 통신 파일 다운로드 성공]")
                print("-------------------------------")
                print("주 소 :: ", requestURL)
                print("-------------------------------")
                print("responseHeader :: ", resultDic.description)
                print("-------------------------------")
                print("headerKey :: ", resultDic.keys.description)
                print("-------------------------------")
                print("resultCode :: ", resultCode)
                print("-------------------------------")
                print("fileName :: ", fileName)
                print("-------------------------------")
                print("fileExtension :: ", fileExtension)
                print("-------------------------------")
                print("fileLength :: ", resultLen)
                print("===============================")
                print("")
                
                
                // MARK: [파일 확장자 명이 널이 아닌 경우 다운로드 수행]
                if C_Util().stringNotNull(str: fileExtension) == true {
                    
                    // [파일 저장 경로에 파일 명 추가]
                    let fileSavePath = documentsUrl.appendingPathComponent(fileName) // 실제 저장되는 경로
                    
                    // [파일 저장 수행 실시]
                    //*
                    if let data = data {
                        
                        // [설정한 경로에 파일 저장]
                        if let _ = try? data.write(to: fileSavePath, options: Data.WritingOptions.atomic) {
                            print("")
                            print("===============================")
                            print("[C_Util >> submitDownloadFile() :: http 통신 파일 저장 [성공]]")
                            print("-------------------------------")
                            print("파일 저장 경로 :: ", fileSavePath)
                            print("===============================")
                            print("")
                            return
                        }
                        else {
                            print("")
                            print("===============================")
                            print("[C_Util >> submitDownloadFile() :: http 통신 파일 저장 [실패] [1]]")
                            print("-------------------------------")
                            print("파일 저장 경로 :: ", fileSavePath)
                            print("-------------------------------")
                            print("error :: ", "data write error")
                            print("===============================")
                            print("")
                            return
                        }
                    }
                    else {
                        print("")
                        print("===============================")
                        print("[C_Util >> submitDownloadFile() :: http 통신 파일 저장 [실패] [2]]")
                        print("-------------------------------")
                        print("파일 저장 경로 :: ", fileSavePath)
                        print("-------------------------------")
                        print("error :: ", "data parsing error")
                        print("===============================")
                        print("")
                        return
                    }
                    // */
                }
                else {
                    print("")
                    print("===============================")
                    print("[C_Util >> submitDownloadFile() :: http 통신 파일 저장 [실패] [3]]")
                    print("-------------------------------")
                    print("error :: ", "file extensions is null [2]")
                    print("===============================")
                    print("")
                    return
                }
            })

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

 

반응형
Comments