회원가입을 할 때 사용자가 프로필 이미지로 지정한 사진을 서버에 전송해 주어야 하는데 검색해 보니 이를 위해서는 form-data
형식으로 전달해 주어야 한다고 한다.
✍️ multipart/form-data는 파일 업로드가 있는 양식 요소에 사용되는 enctype 속성의 값 중 하나이고, multipart는 폼 데이터가 여러 부분으로 나뉘어 서버로 전송되는 것을 의미한다.
Alamofire 라이브러리에서는 이 형식을 제공해 주고 있으며, 이미지를 데이터로 변환하여 전송하는 것이다.
let header: HTTPHeaders = [ "Content-Type" : "multipart/form-data" ]
let params: Parameters = [
"user_id": userId,
"pwd": pwd,
"name": name,
"age": age
]
AF.upload(multipartFormData: { MultipartFormData in
for (key, value) in params {
MultipartFormData.append("\(value)".data(using: .utf8)!, withName: key)
}
// 이미지 추가
if let image = imgData?.pngData() {
MultipartFormData.append(image, withName: "image", fileName: "\(name).jpg", mimeType: "image/jpg")
}
}, to: signUpURL, usingThreshold: UInt64.init(), method: .post, headers: header).responseData { response in
switch response.result {
case .success:
guard let statusCode = response.response?.statusCode else { return }
guard let data = response.value else { return }
completion(judgeSignUpData(status: statusCode, data: data))
case .failure(let err):
print(err)
completion(.networkFail)
}
}
func signUp(userId: String, pwd: String, name: String, age: String, imgData: Data) {
// 헤더 작성 (Content-type 지정)
let header: HTTPHeaders = [ "Content-Type" : "multipart/form-data" ]
// 파라미터
let params: Parameters = [
"user_id": userId,
"pwd": pwd,
"name": name,
"age": age
]
AF.upload(multipartFormData: { MultipartFormData in
for (key, value) in params {
MultipartFormData.append("\(value)".data(using: .utf8)!, withName: key)
}
// 이미지 추가 (이미지 없을 경우 고려)
if let image = imgData?.pngData() {
MultipartFormData.append(image, withName: "image", fileName: "\(name).jpg", mimeType: "image/jpg")
}
}, to: signUpURL, usingThreshold: UInt64.init(), method: .post, headers: header).responseData { response in
switch response.result {
case .success:
guard let statusCode = response.response?.statusCode else { return }
guard let data = response.value else { return }
completion(judgeSignUpData(status: statusCode, data: data))
case .failure(let err):
print(err)
completion(.networkFail)
}
}
}
private func judgeSignUpData(status: Int, data: Data) -> NetworkResult<Any> {
// 통신을 통해 전달받은 데이터를 decode
switch status {
case 200:
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(TokenModel.self, from: data) else { return .pathErr }
print("회원가입 :: Success")
return .success(decodedData)
case 400..<500:
return .requestErr
case 500:
return .serverErr
default:
return .networkFail
}
}
form-data 형식으로 보내는 것은 처음이라 걱정했는데, 하다보니까 그냥 post, get 형식과 비슷한 것 같았다.
서버에 이미지 보내기 성공 👏