diff --git a/Gemfile.lock b/Gemfile.lock index 1bba1f3..603ea96 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -190,7 +190,6 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) - fastlane-plugin-firebase_app_distribution (0.3.6) ffi (1.15.5) fourflusher (2.3.1) fuzzy_match (2.0.4) @@ -346,7 +345,6 @@ DEPENDENCIES danger-xcode_summary danger-xcov fastlane - fastlane-plugin-firebase_app_distribution xcov BUNDLED WITH diff --git a/Podfile b/Podfile index ae18b24..035a8c2 100644 --- a/Podfile +++ b/Podfile @@ -17,7 +17,7 @@ end target 'WeatherToday' do # Rx - pod 'RxAlamofire' + pod 'Moya/RxSwift' pod 'RxCocoa' pod 'RxDataSources' pod 'RxSwift' diff --git a/Podfile.lock b/Podfile.lock index 886e4ad..5712011 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,13 +1,13 @@ PODS: - Alamofire (5.6.2) - Differentiator (5.0.0) + - Moya/Core (15.0.0): + - Alamofire (~> 5.0) + - Moya/RxSwift (15.0.0): + - Moya/Core + - RxSwift (~> 6.0) - Nimble (10.0.0) - Quick (5.0.1) - - RxAlamofire (6.1.1): - - RxAlamofire/Core (= 6.1.1) - - RxAlamofire/Core (6.1.1): - - Alamofire (~> 5.4) - - RxSwift (~> 6.0) - RxBlocking (6.5.0): - RxSwift (= 6.5.0) - RxCocoa (6.5.0): @@ -38,9 +38,9 @@ PODS: - SwiftLint (0.49.1) DEPENDENCIES: + - Moya/RxSwift - Nimble - Quick - - RxAlamofire - RxCocoa - RxDataSources - RxNimble/RxBlocking @@ -54,9 +54,9 @@ SPEC REPOS: trunk: - Alamofire - Differentiator + - Moya - Nimble - Quick - - RxAlamofire - RxBlocking - RxCocoa - RxDataSources @@ -71,9 +71,9 @@ SPEC REPOS: SPEC CHECKSUMS: Alamofire: d368e1ff8a298e6dde360e35a3e68e6c610e7204 Differentiator: e8497ceab83c1b10ca233716d547b9af21b9344d + Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee Nimble: 5316ef81a170ce87baf72dd961f22f89a602ff84 Quick: 749aa754fd1e7d984f2000fe051e18a3a9809179 - RxAlamofire: beb75a1c452d0de225651db4903f5d29d034a620 RxBlocking: 04b5fd28bb5ea49f7d64b80db8bbfe50d9cc1c7d RxCocoa: 94f817b71c07517321eb4f9ad299112ca8af743b RxDataSources: aa47cc1ed6c500fa0dfecac5c979b723542d79cf @@ -85,6 +85,6 @@ SPEC CHECKSUMS: SwiftFormat: 2402d29b26746f169cce5454d5af88314cbb2e35 SwiftLint: 32ee33ded0636d0905ef6911b2b67bbaeeedafa5 -PODFILE CHECKSUM: 004de57fcc92d3d8885727f0f0cb45fdfa900f9c +PODFILE CHECKSUM: d029468dba72b7c5b0d8ffd1bfe4dcae870bf226 COCOAPODS: 1.11.3 diff --git a/WeatherToday.xcodeproj/project.pbxproj b/WeatherToday.xcodeproj/project.pbxproj index c5ecd0f..4d6de1b 100644 --- a/WeatherToday.xcodeproj/project.pbxproj +++ b/WeatherToday.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 040DBD7A28F411F600462092 /* WeatherApiRequestConfigurations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 040DBD7928F411F600462092 /* WeatherApiRequestConfigurations.swift */; }; 0410B9C728F028630048F9B2 /* WeatherRepositoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0410B9C628F028630048F9B2 /* WeatherRepositoryProtocol.swift */; }; 0410B9C928F029D10048F9B2 /* Weather.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0410B9C828F029D10048F9B2 /* Weather.swift */; }; 0410B9CB28F02CA70048F9B2 /* WeatherViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0410B9CA28F02CA70048F9B2 /* WeatherViewModel.swift */; }; @@ -95,7 +94,6 @@ /* Begin PBXFileReference section */ 03ED63CB7BC911BF24D982E6 /* NetworkAPIProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkAPIProtocol.swift; sourceTree = ""; }; - 040DBD7928F411F600462092 /* WeatherApiRequestConfigurations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherApiRequestConfigurations.swift; sourceTree = ""; }; 0410B9C628F028630048F9B2 /* WeatherRepositoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherRepositoryProtocol.swift; sourceTree = ""; }; 0410B9C828F029D10048F9B2 /* Weather.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Weather.swift; sourceTree = ""; }; 0410B9CA28F02CA70048F9B2 /* WeatherViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherViewModel.swift; sourceTree = ""; }; @@ -332,7 +330,6 @@ 3B0B1253902AC48D789561D9 /* RequestConfigurations */ = { isa = PBXGroup; children = ( - 040DBD7928F411F600462092 /* WeatherApiRequestConfigurations.swift */, ); path = RequestConfigurations; sourceTree = ""; @@ -980,7 +977,6 @@ files = ( 27FC6FEAD6990B1FFB30104C /* AppDelegate.swift in Sources */, 70038E46024D488F68AF19A6 /* Constants+API.swift in Sources */, - 040DBD7A28F411F600462092 /* WeatherApiRequestConfigurations.swift in Sources */, 0410B9CD28F02DA80048F9B2 /* WeatherRepository.swift in Sources */, 18A82EAF62230112C12EA34C /* Constants.swift in Sources */, 0410B9CF28F04B430048F9B2 /* WeatherApi.swift in Sources */, diff --git a/WeatherToday/Sources/Data/NetworkAPI/Core/NetworkAPIProtocol.swift b/WeatherToday/Sources/Data/NetworkAPI/Core/NetworkAPIProtocol.swift index 743b22e..ab3e693 100644 --- a/WeatherToday/Sources/Data/NetworkAPI/Core/NetworkAPIProtocol.swift +++ b/WeatherToday/Sources/Data/NetworkAPI/Core/NetworkAPIProtocol.swift @@ -2,8 +2,7 @@ // NetworkAPIProtocol.swift // -import Alamofire -import RxAlamofire +import Moya import RxSwift protocol NetworkAPIProtocol { @@ -12,34 +11,13 @@ protocol NetworkAPIProtocol { } extension NetworkAPIProtocol { - func request( - session: Session, + provider: MoyaProvider, configuration: RequestConfiguration, decoder: JSONDecoder ) -> Single { - return session.rx.request( - configuration.method, - configuration.url, - parameters: configuration.parameters, - encoding: configuration.encoding, - headers: configuration.headers, - interceptor: configuration.interceptor - ) - .validate(statusCode: 200 ..< 300) - .responseData() - .flatMap { _, data -> Observable in - Observable.create { observer in - do { - let decodable = try decoder.decode(T.self, from: data) - observer.on(.next(decodable)) - } catch { - observer.on(.error(error)) - } - observer.on(.completed) - return Disposables.create() - } + provider.rx.request(configuration) + .filterSuccessfulStatusAndRedirectCodes() + .map(T.self) } - .asSingle() - } } diff --git a/WeatherToday/Sources/Data/NetworkAPI/Core/RequestConfiguration.swift b/WeatherToday/Sources/Data/NetworkAPI/Core/RequestConfiguration.swift index 32ddb9d..5f30a07 100644 --- a/WeatherToday/Sources/Data/NetworkAPI/Core/RequestConfiguration.swift +++ b/WeatherToday/Sources/Data/NetworkAPI/Core/RequestConfiguration.swift @@ -2,38 +2,55 @@ // RequestConfiguration.swift // -import Alamofire import Foundation +import Moya -protocol RequestConfiguration { - - var baseURL: String { get } - - var endpoint: String { get } - - var method: HTTPMethod { get } - - var url: URLConvertible { get } - - var parameters: Parameters? { get } +enum RequestConfiguration { + case weather(cityName: String) +} - var encoding: ParameterEncoding { get } +extension RequestConfiguration: TargetType { - var headers: HTTPHeaders? { get } + var baseURL: URL { URL(string: Configuration.baseWeatherURL)! } - var interceptor: RequestInterceptor? { get } -} + var path: String { + switch self { + case .weather: + return "data/2.5/weather" + } + } -extension RequestConfiguration { + var method: Moya.Method { + switch self { + case .weather: + return .get + } + } - var url: URLConvertible { - let url = URL(string: baseURL)?.appendingPathComponent(endpoint) - return url?.absoluteString ?? "\(baseURL)\(endpoint)" + var task: Moya.Task { + + switch self { + case .weather(let cityName): + return Task.requestParameters( + parameters: [ + "q": cityName, + "appid": Configuration.weatherApiKey, + "units": "metric" + ], + encoding: URLEncoding.default + ) + } } - var parameters: Parameters? { nil } + var headers: [String : String]? { ["Content-Type": "application/json"] } - var headers: HTTPHeaders? { nil } + // Optional Stub + var sampleData: Data { + return Data() + } - var interceptor: RequestInterceptor? { nil } + // Optional Stub + var validationType: ValidationType { + return .successCodes + } } diff --git a/WeatherToday/Sources/Data/NetworkAPI/RequestConfigurations/WeatherApiRequestConfigurations.swift b/WeatherToday/Sources/Data/NetworkAPI/RequestConfigurations/WeatherApiRequestConfigurations.swift deleted file mode 100644 index 1e90a9d..0000000 --- a/WeatherToday/Sources/Data/NetworkAPI/RequestConfigurations/WeatherApiRequestConfigurations.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// WeatherApiRequestConfigurations.swift -// WeatherToday -// -// Created by Taher on 10/10/22. -// Copyright © 2022 Nimble. All rights reserved. -// - -import Alamofire -import Foundation - -enum WeatherApiRequestConfigurations: RequestConfiguration { - - case get(cityName: String) - - var baseURL: String { - Configuration.baseWeatherURL - } - - var endpoint: String { - "data/2.5/weather" - } - - var method: HTTPMethod { - switch self { - case .get: return HTTPMethod.get - } - } - - var encoding: ParameterEncoding { - URLEncoding.default - } - - var parameters: Parameters? { - switch self { - case let .get(cityName): - return [ - "q": cityName, - "appid": Configuration.weatherApiKey, - "units": "metric" - ] - } - } -} diff --git a/WeatherToday/Sources/Data/NetworkAPI/WeatherNetworkAPI.swift b/WeatherToday/Sources/Data/NetworkAPI/WeatherNetworkAPI.swift index aedd118..825ce97 100644 --- a/WeatherToday/Sources/Data/NetworkAPI/WeatherNetworkAPI.swift +++ b/WeatherToday/Sources/Data/NetworkAPI/WeatherNetworkAPI.swift @@ -2,24 +2,20 @@ // WeatherNetworkAPI.swift // -import Alamofire +import Moya import Foundation import RxSwift final class WeatherNetworkAPI: NetworkAPIProtocol { private let decoder: JSONDecoder - private let session: Session = .init() + private let provider = MoyaProvider() init(decoder: JSONDecoder = JSONDecoder()) { self.decoder = decoder } func performRequest(_ configuration: RequestConfiguration, for type: T.Type) -> Single { - request( - session: session, - configuration: configuration, - decoder: decoder - ) + request(provider: provider, configuration: configuration, decoder: decoder) } } diff --git a/WeatherToday/Sources/Data/Repositories/WeatherRepository.swift b/WeatherToday/Sources/Data/Repositories/WeatherRepository.swift index d0443b5..4361419 100644 --- a/WeatherToday/Sources/Data/Repositories/WeatherRepository.swift +++ b/WeatherToday/Sources/Data/Repositories/WeatherRepository.swift @@ -18,7 +18,7 @@ final class WeatherRepository: WeatherRepositoryProtocol { } func getWeatherData(cityName: String) -> Single { - let weatherApiConfiguration = WeatherApiRequestConfigurations.get(cityName: cityName) + let weatherApiConfiguration = RequestConfiguration.weather(cityName: cityName) return networkApi .performRequest( weatherApiConfiguration,