상세 페이지 우측 상단의 버튼을 클릭 후 alert창에서 패스워드 입력을 한 뒤 입력한 값이 서버에 존재하는 password값과 일치할 경우 수정페이지로 화면을 전환하는 작업을 하는 중이었습니다.
isPasswordValid()
메서드를 활용해서 말이죠
private func isPasswordValid(_ passwordKeyAndValue: [String: String?]) {
networkManager.patchSingleItem(url: "\(OpenMarketAPI.urlForSingleItemToGetPatchOrDelete)\(itemID)", texts: passwordKeyAndValue, images: nil) { response in
if (200...299).contains(response.statusCode) {
print("valid password")
// 수정페이지로 전환
} else {
print("invalid password")
// 패스워드 재입력 alert창 띄우기
}
}
}
그런데....죽어도 response
코드가 안불리는거에요...
그래서 해당 메서드 안에 있는 networkManager
의 메서드도 살펴보았죠.
func patchSingleItem(url: String, texts: [String : Any?], images: [UIImage]?, completionHandler: @escaping (HTTPURLResponse) -> Void) {
openMarketItemMultipartFormDataTask(httpMethod: .patch, url: url, texts: texts, imageList: images, completionHandler: { result in
switch result {
case .success(let response):
NSLog("item patch succeeded with response code: \(response.statusCode)")
completionHandler(response)
case .failure(let networkError):
NSLog(networkError.description)
}
})
}
흠.. patch
메서드는 정상적으로 HTTPURLSession
을 가져오는 것 같은데. 더 밑으로 들어가 봐야겠습니다. openMarketItemMultipartFormDataTask()
가 문제일까요?
private func openMarketItemMultipartFormDataTask(httpMethod: HTTPMethods, url: String, texts: [String : Any?], imageList: [UIImage]?, completionHandler: @escaping(_ result: Result <HTTPURLResponse, NetworkResponseError>) -> Void) {
guard let validURL = URL(string: url) else { return }
var request = URLRequest(url: validURL)
request.httpMethod = httpMethod.description
request.httpBody = buildMultipartFormData(texts, imageList)
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
dataTask = urlSession.dataTask(with: request) { data, response, error in
if let error = error {
NSLog(error.localizedDescription)
}
guard let successfulResponse = response as? HTTPURLResponse,
(200...299).contains(successfulResponse.statusCode) else {
let failedResponse = response as? HTTPURLResponse
completionHandler(.failure(NetworkResponseError.failed))
return
}
if let mimeType = successfulResponse.mimeType,
mimeType == "multipart/form-data" {
completionHandler(.success(successfulResponse))
}
}
dataTask?.resume()
}
이 메서드가 문제인 것 같아서 한 번 디버깅을 해 봤습니다. breakpoint를 한 번 도배 해 보겠습니다😆
오마이갓; mime Type을 체크하는 부분에서 서버에서 보내온 mimeType은 application/json
타입인데 저는 서버에서 보내주는 데이터가 multipart/form-data
인 줄 알고 있었네요..
그래서 오랜만에 서버 API문서를 확인 해 봤습니다...
역시나 좌측의 request body는 multipart/form-data
가 맞지만...우측에 보이는 response 같은 경우 json object네요.
Common MIME types 문서를 확인 해 보니 역시나 mimetype이 application/json이어야겠네요.
if let mimeType = successfulResponse.mimeType,
mimeType == "application/json" {
completionHandler(.success(successfulResponse))
}
mimeType이 application.json
타입인지 확인 하도록 로직을 수정하니 정상적으로 completionHandler가 호출이 되면서 응답을 정상적으로 받아 올 수 있었습니다.
API문서를 제대로 숙지하지 않은 제 탓입니다 ㅠㅜ. 반성 많이하였고 앞으로는 더 꼼꼼하게 API문서를 읽고 개발하는 개발자가 되도록 노력하겠습니다.