본문 바로가기
Developer/iOS, Swift

[Swift] 갤러리에 저장된 이미지 파일, 서버에 POST하기

by Doony 2020. 2. 24.

앱에서 흔히 볼 수 있는 이미지 업로드 기능을 생각해보면, 먼저 사진첩 즉 갤러리에 접근해서 가져오는 것을 알 수 있습니다. 이번 포스팅에서는 갤러리에 접근하여 선택된 이미지 데이터를 불러오고, 간단한 전처리 방법 등을 통해 용량을 축소시킨 뒤 서버에 POST하는 방법에 대해 알아보겠습니다.

갤러리 띄우기

  • UIImagePickerController을 선언하고, viewDidLoad에 다음과 같이 delegate를 선언합니다.
1
2
3
4
5
6
7
8
let picker = UIImagePickerController()
 
override func viewDidLoad() {
 
        super.viewDidLoad()
        picker.delegate = self
        
}
cs
  • 특정 버튼을 실행했을 때, 다음과 같은 함수가 실행되도록 합니다. (저는 UITabGestureRecognizer을 써서 한 예제입니다.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@objc func viewProfileChangeClicked(sender: UITapGestureRecognizer) {
        // 특정 버튼 클릭 시 실행되는 
        let alert =  UIAlertController(title: "프로필 사진 변경", message: "", preferredStyle: .actionSheet)
 
 
        let library =  UIAlertAction(title: "사진앨범", style: .default) { (action) in self.openLibrary()
 
        }
 
 
        let cancel = UIAlertAction(title: "취소", style: .cancel, handler: nil)
 
 
        alert.addAction(library)
 
 
        alert.addAction(cancel)
 
        present(alert, animated: true, completion: nil)
 
    }
    
    func openLibrary(){
 
      picker.sourceType = .photoLibrary
 
      present(picker, animated: false, completion: nil)
 
    }
cs

이와 같이 진행하면, 특정 버튼을 눌렀을 때 갤러리가 뜨는 모습을 볼 수 있습니다. 그렇다면 이제 갤러리에서 특정 사진을 선택했을 때, 이벤트 관리하는 방법에 대해 알아보겠습니다. ### 갤러리에서 사진 선택 시 이벤트 관리 및 서버 POST

  • extension을 이용해 두 가지 delegate들을 상속하고 함수를 만들어줍니다.
  • AlamoFire을 이용해 서버에 올리는 방식으로 구현했습니다. 서버 토큰값과 주소를 바꿔서 넣으시면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
extension ViewControllerModifyProfile: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
 
        
        
        guard let selectedImage = info[.originalImage] as? UIImage else {
            fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
        }
        
        let token = "서버 토큰키 (Auth)"
        let header: HTTPHeaders = [
            "Authorization": token
        ]
        
        
        let resizedImage = resizeImage(image: selectedImage, newWidth: 300)
        
        let imageData = resizedImage.jpegData(compressionQuality: 0.5)
        
 
        Alamofire.upload(
            
            multipartFormData: { MultipartFormData in
                if((imageData) != nil){
                    
                    
                    
                    MultipartFormData.append(imageData!, withName: "서버 필드명", fileName: "profileImage.jpeg", mimeType: "image/jpeg")
                }
 
        }, to: "서버 주소", method: .patch, headers: header) { (result) in
 
            switch result {
            case .success(let upload, _, _):
                
                upload.responseJSON { response in
                   // getting success
                    if (response.response?.statusCode)! >= 200 {
                        
                        self.imgProfile.image = resizedImage
                        self.dismiss(animated: true, completion: nil)
                    }
                    
                }
 
            case .failure(let encodingError): break
                // getting error
                
            }
 
        }
        
    }
        
        
}
    
 
cs
  • 중간에 이미지 용량을 줄이는 코드가 들어가 있습니다.
  • resizeImage: 이미지 크기를 조절합니다. 크기를 줄이는 것만으로도 용량을 대폭 축소시킬 수 있습니다. 저는 width를 300px로 설정했고, height는 비율대로 자동 조절됩니다.
  • jpegData(compressionQuality): jpeg 압축 품질을 결정합니다. 0~1 사이의 적당한 값을 통해 마찬가지로 용량을 축소시킬 수 있습니다.
1
2
3
let resizedImage = resizeImage(image: selectedImage, newWidth: 300)
let imageData = resizedImage.jpegData(compressionQuality: 0.5)
        
cs

댓글