Alamofire를 이용하여 서버 통신을 위한 기초 코드를 작성해보자!
제일 먼저 CocoaPods 혹은 Swift Package Manager를 이용하여 Alamofire를 설치한다.
import Foundation
struct APIConstants {
//MARK: - Base URL
static let baseURL = "http://3.34.192.134:8000"
//MARK: - Feature URL
// 게시글 전체를 가져오기 위한 URL
static let getPostsURL = baseURL + "/post"
// 댓글 작성 URL
static let postCommentURL = baseURL + "/review/post"
}
APIConstants.getPostsURL
처럼 사용할 수 있다.import Foundation
enum NetworkResult<T> {
case success(T) //서버 통신 성공했을 때
case requestErr(T) // 요청 에러 발생했을 때
case pathErr(T) // 경로 에러 발생했을 때
case serverErr // 서버의 내부 에러가 발생했을 때
case networkFail // 네트워크 연결 실패했을 때
}
{
"status": 201,
"success": true,
"message": "회원가입 성공",
"data": {
"id": 133
}
}
import Foundation
struct BaseResponse<T: Codable>: Codable {
let status: Int
let success: Bool
let message: String
let data: T?
}
struct SignUpData: Codable {
let id: Int
}
import Foundation
import Alamofire
struct UserService {
static let shared = UserService()
private init() {}
// 회원가입
func signUp(name: String, email: String, password: String, completion: @escaping (NetworkResult<Any>) -> Void) {
let url = APIConstants.signUpURL
let header: HTTPHeaders = ["Content-Type" : "application/json"]
let body: Parameters = [
"name": name,
"email": email,
"password": password
]
// Request 생성
// get통신에서는 encoding에 URLEncoding.default 사용
let dataRequest = AF.request(url, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header)
// Request 시작
dataRequest.responseData { response in
switch response.result {
// 성공 시 상태코드와 데이터(value) 수신
case .success:
guard let statusCode = response.response?.statusCode else { return }
guard let value = response.value else { return }
let networkResult = NetworkHelper.parseJSON(by: statusCode, data: value, type: SignUpData.self)
completion(networkResult)
// 실패 시 networkFail(통신 실패)신호 전달
case .failure:
completion(.networkFail)
}
}
}
}
import Foundation
struct NetworkHelper {
private init() {}
// 상태 코드와 데이터, decoding type을 가지고 통신의 결과를 핸들링하는 함수
static func parseJSON<T: Codable> (by statusCode: Int, data: Data, type: T.Type) -> NetworkResult<Any> {
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(BaseResponse<T>.self, from: data) else { return .pathErr }
switch statusCode {
case 200..<300: return .success(decodedData)
case 400..<500: return .requestErr(decodedData)
case 500..<600: return .serverErr
default: return .networkFail
}
}
}
//MARK: - UserService
extension LoginConfirmController {
func signUp() {
guard let name = name else { return }
let email = name
guard let password = password else { return }
UserService.shared.signUp(name: name, email: email, password: password) { respose in
switch respose {
case .success(_):
self.alert(withTitle: "회원가입 성공", message: "Instagram에 오신 것을 환영합니다.") { _ in
self.dismiss(animated: true)
}
case .requestErr(_):
self.alert(withTitle: "회원 가입 실패", message: "이미 등록된 유저가 존재합니다.") { _ in
self.dismiss(animated: true)
}
case .pathErr:
self.alert(withTitle: "회원가입 실패", message: "Can not decode...")
case .serverErr:
print("serverError")
case .networkFail:
print("networkFail")
}
}
}
}
UserSerivce.shared.signUp(…)
을 호출하는 방식을 사용하였다.case .success(let data):
guard let testData = data as? SomeDataModel else { return }
dataArray = testData.anyDataList
위처럼 data를 원하는 모델로 캐스팅하고 VC에 생성해 놓은 어레이에 담아주면 된다. 해당 어레이에 담긴 값을 UI로 뿌려주면 서버 통신 완료!