Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7주차 실습 #5

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions DaangnMarket/Config.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Config.swift
// DaangnMarket
//
// Created by Gahyun Kim on 2024/04/27.
//

import Foundation

enum Config {
enum Keys {
enum Plist {
static let baseURL = "BASE_URL"
}
}

private static let infoDictionary: [String: Any] = {
guard let dict = Bundle.main.infoDictionary else {
fatalError("plist cannot found.")
}
return dict
}()
}

extension Config {

static let baseURL: String = {
guard let key = Config.infoDictionary[Keys.Plist.baseURL] as? String else {
fatalError("Base URL is not set in plist for this configuration.")
}
return key
}()
}
2 changes: 1 addition & 1 deletion DaangnMarket/DaangnMarket/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {

guard let windowScene = (scene as? UIWindowScene) else { return }
self.window = UIWindow(windowScene: windowScene)
let navigationController = UINavigationController(rootViewController: LoginViewController())
let navigationController = UINavigationController(rootViewController: SignUpViewController())
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}
Expand Down
7 changes: 7 additions & 0 deletions DaangnMarket/DaangnMarket/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BASE_URL</key>
<string>$(BASE_URL)</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UIAppFonts</key>
<array>
<string>Pretendard-Black.otf</string>
Expand Down
73 changes: 73 additions & 0 deletions DaangnMarket/DaangnMarket/Network/Base/MoyaLoggingPlugin.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// MoyaLoggingPlugin.swift
// DaangnMarket
//
// Created by Gahyun Kim on 2024/04/27.
//

import UIKit

import Moya

final class MoyaLoggingPlugin: PluginType {

// MARK: - Request 보낼 시 호출
func willSend(_ request: RequestType, target: TargetType) {
guard let httpRequest = request.request else {
print("--> 유효하지 않은 요청")
return
}
let url = httpRequest.description
let method = httpRequest.httpMethod ?? "메소드값이 nil입니다."
var log = "----------------------------------------------------\n1️⃣[\(method)] \(url)\n----------------------------------------------------\n"
log.append("2️⃣API: \(target)\n")
if let headers = httpRequest.allHTTPHeaderFields, !headers.isEmpty {
log.append("header: \(headers)\n")
}
if let body = httpRequest.httpBody, let bodyString = String(bytes: body, encoding: String.Encoding.utf8) {
log.append("\(bodyString)\n")
}
log.append("------------------- END \(method) -------------------")
print(log)
}

// MARK: - Response 받을 시 호출
func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
switch result {
case let .success(response):
self.onSucceed(response, target: target)
case let .failure(error):
self.onFail(error, target: target)
}
}

func onSucceed(_ response: Response, target: TargetType) {
let request = response.request
let url = request?.url?.absoluteString ?? "nil"
let statusCode = response.statusCode
var log = "------------------- Reponse가 도착했습니다. -------------------"
log.append("\n3️⃣[\(statusCode)] \(url)\n")
log.append("API: \(target)\n")
log.append("Status Code: [\(statusCode)]\n")
log.append("URL: \(url)\n")
log.append("response: \n")
if let reString = String(bytes: response.data, encoding: String.Encoding.utf8) {
log.append("4️⃣\(reString)\n")
}
log.append("------------------- END HTTP -------------------")
print(log)
}

func onFail(_ error: MoyaError, target: TargetType) {
if let response = error.response {
onSucceed(response, target: target)
return
}
var log = "네트워크 오류"
log.append("<-- \(error.errorCode)\n")
log.append("\(error.failureReason ?? error.errorDescription ?? "unknown error")\n")
log.append("<-- END HTTP")
print(log)
}
}

17 changes: 17 additions & 0 deletions DaangnMarket/DaangnMarket/Network/Base/NetworkResult.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// NetworkResult.swift
// DaangnMarket
//
// Created by Gahyun Kim on 2024/04/27.
//

import Foundation

enum NetworkResult<T> {
case success(T) // 서버 통신 성공했을 때,
case requestErr // 요청 에러 발생했을 때,
case decodedErr // 디코딩 오류 발생했을 때
case pathErr // 경로 에러 발생했을 때,
case serverErr // 서버의 내부적 에러가 발생했을 때,
case networkFail // 네트워크 연결 실패했을 때
}
81 changes: 81 additions & 0 deletions DaangnMarket/DaangnMarket/Network/UserService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// UserService.swift
// DaangnMarket
//
// Created by Gahyun Kim on 2024/04/27.
//

import Foundation

import Moya

final class UserService {
static let shared = UserService()
private var userProvider = MoyaProvider<UserTargetType>(plugins: [MoyaLoggingPlugin()])

private init() {}
}

extension UserService {
func getUserInfo(memberId: String, completion: @escaping (NetworkResult<Any>) -> Void) {
userProvider.request(.getUserInfo(memberId: memberId)) { result in
switch result {
case .success(let response):
let statusCode = response.statusCode
let data = response.data

let networkResult = self.judgeStatus(by: statusCode, data, UserInfoResponseModel.self)
completion(networkResult)

case .failure:
completion(.networkFail)
}
}
}


func signUp(request: SignUpRequestModel, completion: @escaping (NetworkResult<Any>) -> Void) {
userProvider.request(.signUp(request: request)) { result in
switch result {
case .success(let response):
print("🫶 memberID는 \(String(describing: response.response?.allHeaderFields["Location"]))")

let statusCode = response.statusCode
let data = response.data

let networkResult = self.judgeStatus(by: statusCode, data, SignUpResponseModel.self)
completion(networkResult)

case .failure:
completion(.networkFail)
}
}
}



//서버통신 자체는 성공을 해도 응답 실패로 우리가 원하는 데이터를 받지 못한 상태일 떄를 분기처리하기 위한 메소드
public func judgeStatus<T: Codable>(by statusCode: Int, _ data: Data, _ object: T.Type) -> NetworkResult<Any> {

switch statusCode {
case 200..<205:
return isValidData(data: data, T.self)
case 400..<500:
return .requestErr
case 500:
return .serverErr
default:
return .networkFail
}
}

// 통신이 성공하고 원하는 데이터가 올바르게 들어왔을 때 데이터 처리를 위한 메소드
private func isValidData<T: Codable>(data: Data, _ object: T.Type) -> NetworkResult<Any> {
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(T.self, from: data) else {
print("⛔️ \(self)애서 디코딩 오류가 발생했습니다 ⛔️")
return .pathErr }

return .success(decodedData as Any)
}
}
61 changes: 61 additions & 0 deletions DaangnMarket/DaangnMarket/Network/UserTargetType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// UserTargetType.swift
// DaangnMarket
//
// Created by Gahyun Kim on 2024/04/27.
//

import Foundation

import Moya


enum UserTargetType {
case getUserInfo(memberId: String)
case signUp(request: SignUpRequestModel)
}

extension UserTargetType: TargetType {
var baseURL: URL {
return URL(string: Config.baseURL)!
}

var path: String {
switch self {
case .signUp:
return "/member/join"
case .getUserInfo(memberId: let memberId):
return "/member/info"
}
}

var method: Moya.Method {
switch self {
case .signUp:
return .post
case .getUserInfo:
return .get
}
}

var task: Moya.Task {
switch self {
case .signUp(let request):
return .requestJSONEncodable(request)
case .getUserInfo:
return .requestPlain
}
}

var headers: [String : String]? {
switch self {
case.signUp:
return ["Content-Type": "application/json"]
case .getUserInfo(let memberId):
return ["Content-Type": "application/json",
"memberId" : memberId]
}

}
}

4 changes: 2 additions & 2 deletions DaangnMarket/DaangnMarket/Present/Chat/Model/ChatModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ struct ChatModel {
extension ChatModel {
static func dummy() -> [ChatModel] {
return [
ChatModel(profileImg: .imgUser1, name: "류희재", place: "성북구", message: "나는 바보다!", itemImg: .imgTotoro),
ChatModel(profileImg: .imgUser2, name: "류희재", place: "성북구", message: "나는 바보다!", itemImg: .imgTotoro),
ChatModel(profileImg: .imgUser2, name: "윤희슬", place: "여의도", message: "나는 공주일걸?", itemImg: .imgCinamon),
ChatModel(profileImg: .imgUser3, name: "김가현", place: "잠실", message: "어쩌라고요", itemImg: .imgMymelody),
ChatModel(profileImg: .imgUser4, name: "김선우", place: "회기", message: "두산 화이팅!", itemImg: .imgKuromi),
ChatModel(profileImg: .imgUser5, name: "서은수", place: "미국", message: "하암냐 지각 안 할게요", itemImg: .imgMymelody2),
ChatModel(profileImg: .imgUser6, name: "김민서", place: "중국", message: "곽성준 나락나락ㄴ나라가나락", itemImg: .imgChikawa),
ChatModel(profileImg: .imgUser7, name: "한지석", place: "태국", message: "젊을때사랑은돈주고도못산다", itemImg: .imgMymelody3),
ChatModel(profileImg: .imgUser8, name: "조혜린", place: "명왕성", message: "뒷풀이좀갑시다선생님", itemImg: .imgFriend),
ChatModel(profileImg:.imgMymelody2, name: "조혜린", place: "명왕성", message: "뒷풀이좀갑시다선생님", itemImg: .imgFriend),
ChatModel(profileImg: .imgUser9, name: "정민지", place: "일본", message: "응애저는갓기입니다", itemImg: .imgKuromi2),
ChatModel(profileImg: .imgUser10, name: "박신영", place: "안드로메다", message: "소주를마시지않겠습니다", itemImg: .imgFriend2)
]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// UserInfoResponseModel.swift
// DaangnMarket
//
// Created by Gahyun Kim on 2024/04/27.
//


import Foundation

// MARK: - UserInfoResponseModel
struct UserInfoResponseModel: Codable {
let code: Int
let message: String
let data: DataClass
}

// MARK: - DataClass
struct DataClass: Codable {
let authenticationId, nickname, phone: String
}
Loading