투케이2K

133. (ios/swift) http get 방식 사용해 이미지 뷰에 이미지 (image) 표시 및 이미지 파일 사진 앱에 저장 실시 본문

IOS

133. (ios/swift) http get 방식 사용해 이미지 뷰에 이미지 (image) 표시 및 이미지 파일 사진 앱에 저장 실시

투케이2K 2022. 3. 19. 21:02

[개발 환경 설정]

개발 툴 : XCODE

개발 언어 : SWIFT

 

[사전 필요 설정]

 

[소스 코드]

import UIKit

// MARK: [import 추가 실시]
import AVFoundation
import Photos



class A_Image: UIViewController {
    
    
    
    // MARK: [클래스 설명]
    /*
    1. A_Image : 카메라, 앨범 접근 클래스
    2. info.plist 권한 등록 필요 :
       - Privacy - Camera Usage Description
       - Privacy - Photo Library Usage Description
       - Privacy - Access to a File Provide Domain Usage Description
       - Privacy - Microphone Usage Description
       - http 허용 : App Transport Security Settings >> Allow Arbitrary Loads >> YES
    */
    
    
    
    // MARK: [로직]
    /*
    1. http 통신을 사용해 이미지를 이미지 뷰에 표시 실시
    2. 이미지 뷰에 표시된 사진을 사진첩 앱에 저장 수행 실시
    */
    
    
    
    // MARK: - [전역 변수 선언 실시]
    @IBOutlet weak var imageView: UIImageView! // 이미지 뷰
    
    
    
    // MARK: - [뷰 로드 실시]
    override func viewDidLoad() {
        super.viewDidLoad()
        print("")
        print("===============================")
        print("[A_Image >> viewDidLoad() :: 뷰 로드 실시]")
        print("===============================")
        print("")
        
        
        // [초기 이미지 뷰 배경 색상 지정 실시]
        self.imageView.backgroundColor = UIColor.gray
    }
    
    
    
    // MARK: - [뷰 로드 완료]
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("")
        print("===============================")
        print("[A_Image >> viewWillAppear() :: 뷰 로드 완료]")
        print("===============================")
        print("")
    }
        
    
    
    // MARK: - [뷰 화면 표시]
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print("")
        print("===============================")
        print("[A_Image >> viewDidAppear() :: 뷰 화면 표시]")
        print("===============================")
        print("")
        // -----------------------------------------
        // [뷰 컨트롤러 포그라운드, 백그라운드 상태 체크 설정 실시]
        NotificationCenter.default.addObserver(self, selector: #selector(self.checkForeground), name: UIApplication.willEnterForegroundNotification, object: nil) // [포그라운드]
        NotificationCenter.default.addObserver(self, selector: #selector(self.checkBackground), name: UIApplication.didEnterBackgroundNotification, object: nil) // [백그라운드]
        // -----------------------------------------
        // [포그라운드 처리 실시]
        self.checkForeground()
        // -----------------------------------------
    }
        
    
    
    // MARK: - [뷰 정지 상태]
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        print("")
        print("===============================")
        print("[A_Image >> viewWillDisappear() :: 뷰 정지 상태]")
        print("===============================")
        print("")
    }
        
    
    
    // MARK: - [뷰 종료 상태]
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        print("")
        print("===============================")
        print("[A_Image >> viewDidDisappear() :: 뷰 종료 상태]")
        print("===============================")
        print("")
        // -----------------------------------------
        // [뷰 컨트롤러 포그라운드, 백그라운드 상태 체크 해제 실시]
        NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil) // [포그라운드]
        NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil) // [백그라운드]
        // -----------------------------------------
    }
    
    
    
    // MARK: - [포그라운드 및 백그라운드 상태 처리 메소드 작성]
    @objc func checkForeground() {
        print("")
        print("===============================")
        print("[A_Image >> checkForeground() :: 뷰 컨트롤러 포그라운드]")
        print("===============================")
        print("")
    }
    @objc func checkBackground() {
        print("")
        print("===============================")
        print("[A_Image >> checkBackground() :: 뷰 컨트롤러 백그라운드]")
        print("===============================")
        print("")
    }
    
    
    
    // MARK: - [이미지 다운로드 수행 버튼]
    @IBAction func buttonDown(_ sender: Any) {
        print("")
        print("===============================")
        print("[A_Image >> buttonDown() :: 이미지 다운 버튼 클릭 이벤트 발생]")
        print("===============================")
        print("")
        
        
        // [이미지 다운로드 및 이미지 뷰에 표시 수행 실시]
        self.requestGet()
    }
    
    
    
    
    // MARK: - [이미지 저장 수행 버튼]
    @IBAction func buttonSave(_ sender: Any) {
        print("")
        print("===============================")
        print("[A_Image >> buttonSave() :: 이미지 저장 버튼 클릭 이벤트 발생]")
        print("===============================")
        print("")

        
        DispatchQueue.main.async {
            // [앨범의 사진에 대한 접근 권한 확인 실시]
            PHPhotoLibrary.requestAuthorization( { status in
                switch status{
                case .authorized:
                    print("")
                    print("===============================")
                    print("[A_Image >> buttonAction() :: 앨범의 사진에 대한 접근 권한 확인 실시]")
                    print("상태 :: 앨범 권한 허용")
                    print("===============================")
                    print("")
                    
                    DispatchQueue.main.async {
                        
                        // MARK: [http 통신으로 얻은 데이터 >> 이미지 뷰에 표시 >> 이미지 뷰 데이터 사진첩 앱에 저장]
                        UIImageWriteToSavedPhotosAlbum(self.imageView.image!, self, #selector(self.image(_:didFinishSavingWithError:contextInfo:)), nil)
                    }
                    break
                    
                case .denied:
                    print("")
                    print("===============================")
                    print("[A_Image >> buttonAction() :: 앨범의 사진에 대한 접근 권한 확인 실시]")
                    print("상태 :: 앨범 권한 거부")
                    print("===============================")
                    print("")
                    break
                    
                case .notDetermined:
                    print("")
                    print("===============================")
                    print("[A_Image >> buttonAction() :: 앨범의 사진에 대한 접근 권한 확인 실시]")
                    print("상태 :: 앨범 권한 선택하지 않음")
                    print("===============================")
                    print("")
                    break
                    
                case .restricted:
                    print("")
                    print("===============================")
                    print("[A_Image >> buttonAction() :: 앨범의 사진에 대한 접근 권한 확인 실시]")
                    print("상태 :: 앨범 접근 불가능, 권한 변경이 불가능")
                    print("===============================")
                    print("")
                    break
                    
                default:
                    break
                }
            })
        }
    }
    
    
    
    // MARK: - [URL Session Get 사진 데이터 다운로드]
    func requestGet() {
        
        
        // MARK: [http 통신 수행 필요 info plist 권한]
        // MARK: [App Transport Security Settings >> Allow Arbitrary Loads >> YES]
        
        
        // [URL 지정 및 파라미터 값 지정 실시]
        var urlComponents = URLComponents(string: "https://smart.test.ac.kr/profile_image?")
        let paramQuery_1 = URLQueryItem(name: "u", value: "12345")
        urlComponents?.queryItems?.append(paramQuery_1) // 파라미터 지정
        
        
        // [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("[A_Image >> requestGet :: http get 요청 실시]")
        print("url : ", requestURL)
        print("===============================")
        print("")
        let dataTask = URLSession.shared.dataTask(with: requestURL) { (data, response, error) in

            // [error가 존재하면 종료]
            guard error == nil else {
                print("")
                print("===============================")
                print("[A_Image >> requestGet :: http get 요청 실패]")
                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("[A_Image >> requestGet :: http get 요청 에러]")
                print("error :: ", (response as? HTTPURLResponse)?.statusCode ?? 0)
                print("msg :: ", (response as? HTTPURLResponse)?.description ?? "")
                print("===============================")
                print("")
                return
            }

            // [response 데이터 획득]
            let resultCode = (response as? HTTPURLResponse)?.statusCode ?? 0
            let resultLen = data! // 데이터 길이
            let mimeType = response?.mimeType // 응답 데이터 타입 확인
            
            
            // [응답 데이터 타입이 이미지 파일 인지 확인 실시]
            if ((mimeType?.lowercased().contains("image")) != nil) {
                print("")
                print("===============================")
                print("[A_Image >> requestGet :: http get 요청 성공]")
                print("resultCode :: ", resultCode)
                print("resultLen :: ", resultLen)
                print("mimeType :: ", mimeType ?? "")
                print("===============================")
                print("")
                
                
                DispatchQueue.main.async {
                    // [응답 데이터를 이미지로 받음]
                    let image = UIImage(data: data!)
                    
                    // [이미지 뷰에 표시 수행 실시]
                    self.imageView.image = image
                }
            }
            else {
                print("")
                print("===============================")
                print("[A_Image >> requestGet :: http get 요청 에러]")
                print("resultCode :: ", resultCode)
                print("error :: ", "파일 형식이 이미지 파일이 아닙니다")
                print("mimeType :: ", mimeType ?? "")
                print("===============================")
                print("")
            }
        }

        // network 통신 실행
        dataTask.resume()
    }
    
    
    
    // MARK: - [Device 사진 앱에 이미지 파일 저장 실시 후 >> 응답 상태 확인 부분]
    @objc func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) {
        
        // [사진 저장 한후]
        if let error = error {
            print("")
            print("===============================")
            print("[A_Image >> image() :: 이미지 저장 에러]")
            print("error :: ", "이미지 파일 저장 실패")
            print("message :: ", error.description ?? "")
            print("===============================")
            print("")
        }
        else {
            print("")
            print("===============================")
            print("[A_Image >> image() :: 이미지 저장 성공]")
            print("message :: ", "이미지 파일 저장에 성공하였습니다")
            print("===============================")
            print("")
        }
    }

} // [클래스 종료]
 

[결과 출력]

 

 
반응형
Comments