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

[FEAT] Coordinator로 화면전환 구현하기 #13

Open
wants to merge 30 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7e9468f
[FEAT] APIEnvironment 추가
Suyeon9911 May 16, 2022
a4ac963
[FEAT] Constants 추가
Suyeon9911 May 16, 2022
fd2298c
[ADD] Genaral Response 추가
Suyeon9911 May 16, 2022
fc35acf
[ADD] Network Result 추가
Suyeon9911 May 16, 2022
6ff2896
[FEAT] GeneralService 구현
Suyeon9911 May 16, 2022
0187bc8
[FEAT] 네트워크 기본 파일 세팅
Suyeon9911 May 16, 2022
42758bf
[ADD] Alamofire 추가
Suyeon9911 May 16, 2022
1f01fdc
[ADD] Alert Extension 추가
Suyeon9911 May 16, 2022
b85a509
[FEAT] Network 상수 파일
Suyeon9911 May 16, 2022
fbadde4
[FEAT] URL 상수 파일 추가
Suyeon9911 May 16, 2022
31663d8
[FEAT] BaseRouter 구현
Suyeon9911 May 16, 2022
f94b904
[FEAT] AuthRouter 구현
Suyeon9911 May 16, 2022
bbf490a
[FEAT] AuthService 파일 구현
Suyeon9911 May 16, 2022
5126757
[FEAT] SignIn 네트워크 함수 구현
Suyeon9911 May 16, 2022
5a4adec
[ADD] alert 익스텐션 추가
Suyeon9911 May 16, 2022
57c6039
[CHORE] 서버설정
Suyeon9911 May 16, 2022
e595d9b
[CHORE] 서버코드 수정
Suyeon9911 May 16, 2022
f2eab99
[CHORE] 서버통신 코드 수정
Suyeon9911 May 16, 2022
a1bca48
[FEAT] Alert 구현해주기
Suyeon9911 May 17, 2022
4b5c27e
[FEAT] Service 파일 상속관계 수정
Suyeon9911 May 17, 2022
1e13cb7
[FEAT] 회원가입 서버통신 구현
Suyeon9911 May 17, 2022
666e2e0
[CHORE] 주석 추가 및 리팩토링
Suyeon9911 May 19, 2022
5c69b2a
[ADD] 코디네이터 전체 폴더 구조 세팅
Suyeon9911 May 19, 2022
94b4623
[CHORE] 탭바 잠시 수정
Suyeon9911 May 21, 2022
fb04b0a
[FEAT] SceneDelegate 설정
Suyeon9911 May 21, 2022
a626e15
[FEAT] Appcoordinator 추가
Suyeon9911 May 21, 2022
eebe8b4
[FEAT] 코디네이터 프로토콜 추가
Suyeon9911 May 21, 2022
0beb13e
[FEAT] 화면전환할 코디네이터들 추가
Suyeon9911 May 21, 2022
7bf6e68
[FEAT] Transition Model 추가
Suyeon9911 May 21, 2022
4e7bf57
[FEAT] 코디네이터로 화면전환 구현
Suyeon9911 May 21, 2022
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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
{
"pins" : [
{
"identity" : "alamofire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire",
"state" : {
"revision" : "354dda32d89fc8cd4f5c46487f64957d355f53d8",
"version" : "5.6.1"
}
},
{
"identity" : "snapkit",
"kind" : "remoteSourceControl",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// UIViewController+.swift
// 30th-Assignment
//
// Created by 김수연 on 2022/05/17.
//

import UIKit

extension UIViewController {

/// 확인 버튼 1개, 취소 버튼 1개 Alert 메서드
func makeAlertWithCancel(okTitle: String, okStyle: UIAlertAction.Style = .default,
cancelTitle: String = "취소",
okAction : ((UIAlertAction) -> Void)?, cancelAction : ((UIAlertAction) -> Void)? = nil,
completion : (() -> Void)? = nil) {

let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()

let alertViewController = UIAlertController(title: nil, message: nil,
preferredStyle: .actionSheet)

let okAction = UIAlertAction(title: okTitle, style: okStyle, handler: okAction)
alertViewController.addAction(okAction)

let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel, handler: cancelAction)
alertViewController.addAction(cancelAction)

self.present(alertViewController, animated: true, completion: completion)
}

/// 확인 버튼 Alert 메서드
func makeAlert(title : String, message : String? = nil,
okTitle: String = "확인", okAction : ((UIAlertAction) -> Void)? = nil,
completion : (() -> Void)? = nil) {
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()
let alertViewController = UIAlertController(title: title, message: message,
preferredStyle: .alert)
let okAction = UIAlertAction(title: okTitle, style: .default, handler: okAction)
alertViewController.addAction(okAction)
self.present(alertViewController, animated: true, completion: completion)
}

/// 확인 버튼 누르면 화면전환되는 Alert 메서드
func makePresentAlert(title : String, message : String? = nil,
okTitle: String = "확인", nextVC: UIViewController) {
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()
let alertViewController = UIAlertController(title: title, message: message,
preferredStyle: .alert)
alertViewController.addAction(UIAlertAction(title: okTitle, style: .default) { action in
nextVC.modalPresentationStyle = .fullScreen
self.present(nextVC, animated: true)
})
self.present(alertViewController, animated: true, completion: nil)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {


func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
// guard let windowScene = (scene as? UIWindowScene) else { return }
//
// let rootViewController = LoginViewController()
// let navigationController = UINavigationController(rootViewController: rootViewController)
// let window = UIWindow(windowScene: windowScene)
// window.rootViewController = navigationController
// self.window = window
// window.backgroundColor = .white
// window.makeKeyAndVisible()

let rootViewController = LoginViewController()
let navigationController = UINavigationController(rootViewController: rootViewController)
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = navigationController
self.window = window
window.backgroundColor = .white
window.makeKeyAndVisible()

let coordinator = AppCoordinator(window: window)
coordinator.start()
}

func sceneDidDisconnect(_ scene: UIScene) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// NetworkConstants.swift
// 30th-Assignment
//
// Created by 김수연 on 2022/05/16.
//

import Foundation
import Alamofire

/*
NetworkConstants : 서버통신과정에서 필요한 상수들을 관리 -> header 관련 상수들
*/

enum HeaderType {
case basic
case auth
case multiPart
case multiPartWithAuth
}

enum HTTPHeaderField: String {
case authentication = "Authorization"
case contentType = "Content-Type"
case accesstoken = "accesstoken"
}

enum ContentType: String {
case json = "Application/json"
case tokenSerial = ""
case multiPart = "multipart/form-data"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// URLConstants.swift
// 30th-Assignment
//
// Created by 김수연 on 2022/05/16.
//

import Foundation

/*
URLConstants : 각 API 별 URL상수 관리
*/

struct URLConstants {

static let signUp = "/auth/signup"
static let signIn = "/auth/signin"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// APIEnvironment.swift
// 30th-Assignment
//
// Created by 김수연 on 2022/05/16.
//

import Foundation

/*
APIEnvironment: baseURL 및 토큰 관리, 추후 배포를 고려하여 development와 production 분리
*/

enum APIEnvironment: String, CaseIterable {
case development
case production
}

extension APIEnvironment {
var baseUrl: String {
switch self {
case .development:
return "http://13.124.62.236"
case .production:
return ""
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//
// NeworkRequest.swift
// 30th-Assignment
//
// Created by 김수연 on 2022/05/16.
//

import Foundation
import Alamofire

/*
BaseRouter : URLRequestConvertible을 채택한 프로토콜, 실제 각 Endpont에 해당하는 Router들이
BaseRouter를 채택하여 request 과정을 모듈화.
*/

protocol BaseRouter: URLRequestConvertible {
var baseURL: String { get }
var method: HTTPMethod { get }
var path: String { get }
var parameters: RequestParams { get }
var header: HeaderType { get }
}

extension BaseRouter {
var baseURL: String {
return APIEnvironment.development.baseUrl
}

// URLRequestConvertible 구현
func asURLRequest() throws -> URLRequest {
let url = try baseURL.asURL()
var urlRequest = try URLRequest(url: url.appendingPathComponent(path), method: method)

urlRequest = self.makeHeaderForRequest(to: urlRequest)

return try self.makeParameterForRequest(to: urlRequest, with: url)
}

private func makeHeaderForRequest(to request: URLRequest) -> URLRequest {
var request = request

switch header {
case .basic:
request.setValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.contentType.rawValue)

case .auth:
request.setValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.contentType.rawValue)
request.setValue(ContentType.tokenSerial.rawValue, forHTTPHeaderField: HTTPHeaderField.accesstoken.rawValue)

case .multiPart:
request.setValue(ContentType.multiPart.rawValue, forHTTPHeaderField: HTTPHeaderField.contentType.rawValue)

case .multiPartWithAuth:
request.setValue(ContentType.multiPart.rawValue, forHTTPHeaderField: HTTPHeaderField.contentType.rawValue)
request.setValue(ContentType.tokenSerial.rawValue, forHTTPHeaderField: HTTPHeaderField.accesstoken.rawValue)
}

return request
}

private func makeParameterForRequest(to request: URLRequest, with url: URL) throws -> URLRequest {
var request = request

switch parameters {
case .query(let query):
let params = query?.toDictionary() ?? [:]
let queryParams = params.map { URLQueryItem(name: $0.key, value: "\($0.value)") }
var components = URLComponents(string: url.appendingPathComponent(path).absoluteString)
components?.queryItems = queryParams
request.url = components?.url

case .body(let body):
let params = body?.toDictionary() ?? [:]
request.httpBody = try JSONSerialization.data(withJSONObject: params, options: [])

case .requestParameters(let requestParams):
let params = requestParams
request.httpBody = try JSONSerialization.data(withJSONObject: params, options: [])
}

return request
}
}

enum RequestParams {
case query(_ parameter: Codable?)
case body(_ parameter: Codable?)
case requestParameters(_ parameter: [String : Any])
}

extension Encodable {
func toDictionary() -> [String: Any] {
guard let data = try? JSONEncoder().encode(self),
let jsonData = try? JSONSerialization.jsonObject(with: data),
let dictionaryData = jsonData as? [String: Any] else { return [:] }
return dictionaryData
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// GeneralResponse.swift
// 30th-Assignment
//
// Created by 김수연 on 2022/05/16.
//

import Foundation

import Alamofire

class BaseService {

enum TimeOut {
static let requestTimeOut: Float = 30
static let resourceTimeOut: Float = 30
}

let AFmanager: Session = {
var session = AF
let configuration = URLSessionConfiguration.af.default
configuration.timeoutIntervalForRequest = TimeInterval(TimeOut.requestTimeOut)
configuration.timeoutIntervalForResource = TimeInterval(TimeOut.resourceTimeOut)

session = Session(configuration: configuration)
return session
}()

func judgeStatus<T: Codable>(by statusCode: Int, _ data: Data, _ type: T.Type) -> NetworkResult<Any> {
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(GeneralResponse<T>.self, from: data)
else { return .pathErr }
print(decodedData)
switch statusCode {
case 200:
return .success(decodedData.data ?? "None-Data")
case 201..<300:
return .success(decodedData.status)
case 400..<500:
return .requestErr(decodedData.status)
case 500:
return .serverErr
default:
return .networkFail
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// NetworkResult.swift
// 30th-Assignment
//
// Created by 김수연 on 2022/05/16.
//

import Foundation

/*
NetworkResult : 네트워크 결과 나누기
*/

enum NetworkResult<T> {
case success(T)
case requestErr(T)
case pathErr
case serverErr
case networkFail
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Auth.swift
// 30th-Assignment
//
// Created by 김수연 on 2022/05/16.
//

import Foundation

struct SignIn: Codable {
let name, email: String
}

struct SignUp: Codable {
let id: Int
}
Loading