generated from GO-SOPT-iOS-Part/KimSeungChan
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[Feat] #7 - 4차 과제
- Loading branch information
Showing
30 changed files
with
944 additions
and
98 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
18 changes: 18 additions & 0 deletions
18
SOPTving/SOPTving.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
SOPTving/SOPTving/Data/Entity/Main/PopularMovieEntity.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// | ||
// PopularMovieEntity.swift | ||
// SOPTving | ||
// | ||
// Created by 김민재 on 2023/05/11. | ||
// | ||
|
||
import UIKit | ||
|
||
struct PopularMovieEntity: Decodable { | ||
let page: Int | ||
let results: [Result] | ||
let totalPages: Int | ||
let totalResults: Int | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case page, results | ||
case totalPages = "total_pages" | ||
case totalResults = "total_results" | ||
} | ||
} | ||
|
||
// MARK: - Result | ||
struct Result: Decodable { | ||
let adult: Bool | ||
let backdropPath: String | ||
let genreIDS: [Int] | ||
let id: Int | ||
let originalLanguage: OriginalLanguage | ||
let originalTitle, overview: String | ||
let popularity: Double | ||
let posterPath: String | ||
let releaseDate: String | ||
let title: String | ||
let video: Bool | ||
let voteAverage: Double | ||
let voteCount: Int | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case adult | ||
case backdropPath = "backdrop_path" | ||
case genreIDS = "genre_ids" | ||
case id | ||
case originalLanguage = "original_language" | ||
case originalTitle = "original_title" | ||
case overview, popularity | ||
case posterPath = "poster_path" | ||
case releaseDate = "release_date" | ||
case title, video | ||
case voteAverage = "vote_average" | ||
case voteCount = "vote_count" | ||
} | ||
} | ||
|
||
enum OriginalLanguage: String, Decodable { | ||
case en = "en" | ||
case fr = "fr" | ||
} | ||
|
||
// MARK: Entity -> Model | ||
|
||
extension PopularMovieEntity { | ||
func toDomain() -> [Movie] { | ||
return self.results.map { | ||
let url = TMDBImageURL.posterURL + $0.posterPath | ||
return Movie(title: $0.title, posterImagePath: url) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// | ||
// APIEventLogger.swift | ||
// SOPTving | ||
// | ||
// Created by 김민재 on 2023/05/11. | ||
// | ||
|
||
import Foundation | ||
|
||
import Alamofire | ||
|
||
final class APIEventLogger: EventMonitor { | ||
func requestDidFinish(_ request: Request) { | ||
|
||
print("🛰 NETWORK Reqeust LOG") | ||
print(request.description) | ||
|
||
print( | ||
"URL: " + (request.request?.url?.absoluteString ?? "") + "\n" | ||
+ "Method: " + (request.request?.httpMethod ?? "") + "\n" | ||
+ "Headers: " + "\(request.request?.allHTTPHeaderFields ?? [:])" + "\n" | ||
) | ||
print("Authorization: " + (request.request?.headers["Authorization"] ?? "")) | ||
print("Body: " + (request.request?.httpBody?.toPrettyPrintedString ?? "")) | ||
} | ||
|
||
func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value, AFError>) { | ||
print("🛰 NETWORK Response LOG") | ||
print( | ||
"URL: " + (request.request?.url?.absoluteString ?? "") + "\n" | ||
+ "Result: " + "\(response.result)" + "\n" | ||
+ "StatusCode: " + "\(response.response?.statusCode ?? 0)" + "\n" | ||
+ "Data: \(response.data?.toPrettyPrintedString ?? "")" | ||
) | ||
} | ||
} | ||
|
||
extension Data { | ||
var toPrettyPrintedString: String? { | ||
guard let object = try? JSONSerialization.jsonObject(with: self, options: []), | ||
let data = try? JSONSerialization.data(withJSONObject: object, options: [.prettyPrinted]), | ||
let prettyPrintedString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else { return nil } | ||
return prettyPrintedString as String | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// | ||
// Config.swift | ||
// SOPTving | ||
// | ||
// Created by 김민재 on 2023/05/11. | ||
// | ||
|
||
import Foundation | ||
|
||
enum Config { | ||
enum Keys { | ||
enum Plist { | ||
static let baseURL = "BASE_URL" | ||
static let apiKey = "API_KEY" | ||
} | ||
} | ||
|
||
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 | ||
}() | ||
|
||
static let apiKey: String = { | ||
guard let key = Config.infoDictionary[Keys.Plist.apiKey] as? String else { | ||
fatalError("Base URL is not set in plist for this configuration") | ||
} | ||
return key | ||
}() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// | ||
// HTTPHeaderField.swift | ||
// SOPTving | ||
// | ||
// Created by 김민재 on 2023/05/11. | ||
// | ||
|
||
import Foundation | ||
|
||
import Alamofire | ||
|
||
enum HTTPHeaderField: String { | ||
case authentication = "Authorization" | ||
case contentType = "Content-Type" | ||
case acceptType = "Accept" | ||
} | ||
|
||
enum ContentType: String { | ||
case json = "Application/json" | ||
} |
23 changes: 23 additions & 0 deletions
23
SOPTving/SOPTving/Data/Network/Model/Main/PopularMovieRequestDTO.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// | ||
// PopularMovieRequestDTO.swift | ||
// SOPTving | ||
// | ||
// Created by 김민재 on 2023/05/12. | ||
// | ||
|
||
import Foundation | ||
|
||
struct PopularMovieRequestDTO: Encodable { | ||
let apiKey: String | ||
let page: Int? | ||
let language: String? | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case apiKey = "api_key" | ||
case page, language | ||
} | ||
} | ||
|
||
enum Language { | ||
static let english = "en-US" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// | ||
// NetworkResult.swift | ||
// SOPTving | ||
// | ||
// Created by 김민재 on 2023/05/11. | ||
// | ||
|
||
import Foundation | ||
|
||
enum NetworkResult<T> { | ||
case success(T) // 서버 통신 성공 | ||
case requestErr(T) // 요청에러 발생 | ||
case pathErr // 경로 에러 | ||
case serverErr // 서버 내부 에러 | ||
case networkErr // 네트워크 연결 실패 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// MovieTarget.swift | ||
// SOPTving | ||
// | ||
// Created by 김민재 on 2023/05/11. | ||
// | ||
|
||
import Foundation | ||
|
||
import Alamofire | ||
|
||
enum MovieTarget { | ||
case getPopularMovie(_ dto: PopularMovieRequestDTO) | ||
} | ||
|
||
extension MovieTarget: TargetType { | ||
|
||
var method: HTTPMethod { | ||
switch self { | ||
case .getPopularMovie: | ||
return .get | ||
} | ||
} | ||
|
||
var path: String { | ||
switch self { | ||
case .getPopularMovie(_): | ||
return "/popular" | ||
} | ||
} | ||
|
||
var parameters: RequestParams { | ||
switch self { | ||
case .getPopularMovie(let dto): | ||
return .query(dto) | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// | ||
// BaseService.swift | ||
// SOPTving | ||
// | ||
// Created by 김민재 on 2023/05/11. | ||
// | ||
|
||
import Foundation | ||
|
||
import Alamofire | ||
|
||
|
||
class BaseService { | ||
|
||
static let shared = BaseService() | ||
private init() {} | ||
|
||
func requestObject<T: Decodable>(_ target: TargetType, completion: @escaping (NetworkResult<T>) -> Void) { | ||
let dataRequest = AF.request(target) | ||
dataRequest.responseData { response in | ||
switch response.result { | ||
case .success: | ||
guard let statusCode = response.response?.statusCode else { return } | ||
guard let value = response.value else { return } | ||
let networkResult = self.judgeStatus(by: statusCode, value, type: T.self) | ||
completion(networkResult) | ||
case .failure: | ||
completion(.networkErr) | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
private func judgeStatus<T: Decodable>(by statusCode: Int, _ data: Data, type: T.Type) -> NetworkResult<T> { | ||
switch statusCode { | ||
case 200: return isValidData(data: data, type: T.self) | ||
case 401...409: return isValidData(data: data, type: T.self) | ||
case 500: return .serverErr | ||
default: return .networkErr | ||
} | ||
} | ||
|
||
private func isValidData<T: Decodable>(data: Data, type: T.Type) -> NetworkResult<T> { | ||
let decoder = JSONDecoder() | ||
guard let decodedData = try? decoder.decode(T.self, from: data) else { | ||
print("json decoded failed !") | ||
return .pathErr | ||
} | ||
|
||
return .success(decodedData) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// | ||
// MovieService.swift | ||
// SOPTving | ||
// | ||
// Created by 김민재 on 2023/05/12. | ||
// | ||
|
||
import Foundation | ||
|
||
import Alamofire | ||
|
||
|
||
protocol MovieService { | ||
func getPopularMovies<T: Decodable>(queryDTO: PopularMovieRequestDTO, type: T.Type, completion: @escaping (NetworkResult<T>) -> Void) | ||
} | ||
|
||
extension BaseService: MovieService { | ||
func getPopularMovies<T: Decodable>(queryDTO: PopularMovieRequestDTO, type: T.Type, completion: @escaping (NetworkResult<T>) -> Void) { | ||
requestObject(MovieTarget.getPopularMovie(queryDTO), completion: completion) | ||
} | ||
} |
Oops, something went wrong.