개발 - iOS SwiftUI

iOS SwiftUI HTTP Multipart POST 예제

개미v 2023. 10. 27. 16:59

SwiftUI에서 HTTP Multipart/form-data POST 예제 입니다.

 

import Foundation
import SwiftUI
import PhotosUI

struct UserProfileView: View {
    // 사진 선택
    @State private var selectedPhotosPickerItem: PhotosPickerItem? = nil
    @State private var selectedPhotosData: Data? = nil
    
    var body: some View {
        VStack {
        }
        .task() {
        }
    }
    
    // 사용자 정보 저장
    func btnSave() {
        
        // 랜덤 boundary
        let boundary = "boundary-\(UUID().uuidString)"
        
        // 요청 파라미터
        let userId = "hong99"
        let userNickname = "홍길동"
        
        // 문자열 데이터
        let httpBody = NSMutableData()
        httpBody.appendString(convertStringData(fieldName: "userId", value: userId, boundary: boundary))
        httpBody.appendString(convertStringData(fieldName: "userNickname", value: userNickname, boundary: boundary))
        
        // 이미지 데이터
        if let selectedPhotosData = selectedPhotosData {
            httpBody.append(convertFileData(fieldName: "userPicture", fileName: "userPicture.jpg", mimeType: "image/jpeg", fileData: selectedPhotosData, boundary: boundary))
        }
        
        httpBody.appendString("--\(boundary)--")
        
        // HTTP 요청
        let url = URL(string: Define.serverUrl + "/member/update.ajax")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        request.addValue("UTF-8", forHTTPHeaderField: "Accept-Charset")
        
        // HTTP 요청 결과 처리
        let dataTask = URLSession.shared.uploadTask(with: request, from: httpBody as Data) {data, response, error in
           ...
        }
        dataTask.resume()
    }
    
    // 문자열 데이터
    func convertStringData(fieldName: String, value: String, boundary: String) -> String {
        var fieldString = "--\(boundary)\r\n"
        fieldString += "Content-Disposition: form-data; name=\"\(fieldName)\"\r\n"
        fieldString += "\r\n"
        fieldString += "\(value)\r\n"
        return fieldString
    }
    
    // 이미지 데이터
    func convertFileData(fieldName: String, fileName: String, mimeType: String, fileData: Data, boundary: String) -> Data {
        let data = NSMutableData()
        data.appendString("--\(boundary)\r\n")
        data.appendString("Content-Disposition: form-data; name=\"\(fieldName)\"; filename=\"\(fileName)\"\r\n")
        data.appendString("Content-Type: \(mimeType)\r\n\r\n")
        data.append(fileData)
        data.appendString("\r\n")
        return data as Data
    }
}

 

그리고 NSMutableData에 appendString 메소드가 없어서 추가해줘야 합니다.

extension NSMutableData {
    func appendString(_ string: String) {
        let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
        append(data!)
    }
}