Skip to content

Commit 25e90c4

Browse files
author
Oleh
committed
Created NetworkSessionManager so Auth can be implemented if needed outside of NetworkingService.
1 parent 7dd1d41 commit 25e90c4

File tree

6 files changed

+65
-60
lines changed

6 files changed

+65
-60
lines changed

ExampleMVVM.xcodeproj/project.pbxproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
1F9034C82306FF2D00DEA4BD /* NetworkConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1FC48822E3693100BCBA8D /* NetworkConfig.swift */; };
4040
1F9034CE230713FC00DEA4BD /* DataTransferServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F9034CD230713FC00DEA4BD /* DataTransferServiceTests.swift */; };
4141
1F9034D1230714B900DEA4BD /* NetworkConfigurableMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F9034D0230714B900DEA4BD /* NetworkConfigurableMock.swift */; };
42-
1F9034D32307161D00DEA4BD /* NetworkSessionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F9034D22307161D00DEA4BD /* NetworkSessionMock.swift */; };
42+
1F9034D32307161D00DEA4BD /* NetworkSessionManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F9034D22307161D00DEA4BD /* NetworkSessionManagerMock.swift */; };
4343
1F9034DA2307238C00DEA4BD /* MoviesQueriesListViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F9034D92307238C00DEA4BD /* MoviesQueriesListViewModelTests.swift */; };
4444
1F9034DC2307291800DEA4BD /* FetchRecentMovieQueriesUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F84DECF23006BDA00139F73 /* FetchRecentMovieQueriesUseCase.swift */; };
4545
1F9034DF2307464700DEA4BD /* MoviesQueriesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F9034DE2307464700DEA4BD /* MoviesQueriesStorage.swift */; };
@@ -128,7 +128,7 @@
128128
1F9034C32306FDFE00DEA4BD /* NetworkServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkServiceTests.swift; sourceTree = "<group>"; };
129129
1F9034CD230713FC00DEA4BD /* DataTransferServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataTransferServiceTests.swift; sourceTree = "<group>"; };
130130
1F9034D0230714B900DEA4BD /* NetworkConfigurableMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConfigurableMock.swift; sourceTree = "<group>"; };
131-
1F9034D22307161D00DEA4BD /* NetworkSessionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkSessionMock.swift; sourceTree = "<group>"; };
131+
1F9034D22307161D00DEA4BD /* NetworkSessionManagerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkSessionManagerMock.swift; sourceTree = "<group>"; };
132132
1F9034D92307238C00DEA4BD /* MoviesQueriesListViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoviesQueriesListViewModelTests.swift; sourceTree = "<group>"; };
133133
1F9034DE2307464700DEA4BD /* MoviesQueriesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoviesQueriesStorage.swift; sourceTree = "<group>"; };
134134
1F9035262307528F00DEA4BD /* CoreDataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataStorage.swift; sourceTree = "<group>"; };
@@ -307,7 +307,7 @@
307307
isa = PBXGroup;
308308
children = (
309309
1F9034D0230714B900DEA4BD /* NetworkConfigurableMock.swift */,
310-
1F9034D22307161D00DEA4BD /* NetworkSessionMock.swift */,
310+
1F9034D22307161D00DEA4BD /* NetworkSessionManagerMock.swift */,
311311
);
312312
path = Mocks;
313313
sourceTree = "<group>";
@@ -919,7 +919,7 @@
919919
1F474F2B22356C7F0092DB4B /* MovieQuery.swift in Sources */,
920920
1F474F2D22356C7F0092DB4B /* SearchMoviesUseCase.swift in Sources */,
921921
1F9034C52306FF2D00DEA4BD /* NetworkService.swift in Sources */,
922-
1F9034D32307161D00DEA4BD /* NetworkSessionMock.swift in Sources */,
922+
1F9034D32307161D00DEA4BD /* NetworkSessionManagerMock.swift in Sources */,
923923
1F84DECE2300677B00139F73 /* Observable.swift in Sources */,
924924
1F474F3022356C7F0092DB4B /* MoviesQueriesRepository.swift in Sources */,
925925
1F9034D1230714B900DEA4BD /* NetworkConfigurableMock.swift in Sources */,

ExampleMVVM/Application/DIContainer/AppDIContainer.swift

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@ final class AppDIContainer {
1717
let config = ApiDataNetworkConfig(baseURL: URL(string: appConfigurations.apiBaseURL)!,
1818
queryParameters: ["api_key": appConfigurations.apiKey])
1919

20-
let apiDataNetwork = DefaultNetworkService(session: URLSession.shared,
20+
let apiDataNetwork = DefaultNetworkService(sessionManager: networkSessionManager,
2121
config: config)
2222
return DefaultDataTransferService(with: apiDataNetwork)
2323
}()
2424
lazy var imageDataTransferService: DataTransferService = {
2525
let config = ApiDataNetworkConfig(baseURL: URL(string: appConfigurations.imagesBaseURL)!)
26-
let carrierLogosDataNetwork = DefaultNetworkService(session: URLSession.shared,
26+
let carrierLogosDataNetwork = DefaultNetworkService(sessionManager: networkSessionManager,
2727
config: config)
2828
return DefaultDataTransferService(with: carrierLogosDataNetwork)
2929
}()
30+
lazy var networkSessionManager = DefaultNetworkSessionManager()
3031

3132
// DIContainers of scenes
3233
func makeMoviesSceneDIContainer() -> MoviesSceneDIContainer {

ExampleMVVM/Infrastructure/Network/NetworkService.swift

+24-20
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,19 @@ public protocol NetworkCancellable {
1919
func cancel()
2020
}
2121

22+
extension URLSessionTask: NetworkCancellable { }
23+
2224
public protocol NetworkService {
2325
typealias CompletionHandler = (Result<Data?, NetworkError>) -> Void
2426

2527
func request(endpoint: Requestable, completion: @escaping CompletionHandler) -> NetworkCancellable?
2628
}
2729

28-
public protocol NetworkSession {
30+
public protocol NetworkSessionManager {
2931
typealias CompletionHandler = (Data?, URLResponse?, Error?) -> Void
3032

31-
func loadData(from request: URLRequest,
32-
completion: @escaping CompletionHandler) -> NetworkCancellable
33-
}
34-
35-
extension URLSessionTask: NetworkCancellable { }
36-
37-
extension URLSession: NetworkSession {
38-
public func loadData(from request: URLRequest,
39-
completion: @escaping CompletionHandler) -> NetworkCancellable {
40-
let task = dataTask(with: request) { data, response, error in
41-
completion(data, response, error)
42-
}
43-
task.resume()
44-
return task
45-
}
33+
func request(_ request: URLRequest,
34+
completion: @escaping CompletionHandler) -> NetworkCancellable
4635
}
4736

4837
public protocol NetworkErrorLogger {
@@ -55,21 +44,21 @@ public protocol NetworkErrorLogger {
5544

5645
final public class DefaultNetworkService {
5746

58-
private let session: NetworkSession
47+
private let sessionManager: NetworkSessionManager
5948
private let config: NetworkConfigurable
6049
private let logger: NetworkErrorLogger
6150

62-
public init(session: NetworkSession,
51+
public init(sessionManager: NetworkSessionManager,
6352
config: NetworkConfigurable,
6453
logger: NetworkErrorLogger = DefaultNetworkErrorLogger()) {
65-
self.session = session
54+
self.sessionManager = sessionManager
6655
self.config = config
6756
self.logger = logger
6857
}
6958

7059
private func request(request: URLRequest, completion: @escaping CompletionHandler) -> NetworkCancellable {
7160

72-
let sessionDataTask = session.loadData(from: request) { data, response, requestError in
61+
let sessionDataTask = sessionManager.request(request) { data, response, requestError in
7362

7463
if let requestError = requestError {
7564
var error: NetworkError
@@ -115,6 +104,21 @@ extension DefaultNetworkService: NetworkService {
115104
}
116105
}
117106

107+
// MARK: - Default Network Session Manager
108+
// Note: If authorization is needed NetworkSessionManager can be implemented by using,
109+
// for example, Alamofire SessionManager with its RequestAdapter and RequestRetrier.
110+
// And it can be incjected into NetworkService instead of default one.
111+
112+
public class DefaultNetworkSessionManager: NetworkSessionManager {
113+
public init() {}
114+
public func request(_ request: URLRequest,
115+
completion: @escaping CompletionHandler) -> NetworkCancellable {
116+
let task = URLSession.shared.dataTask(with: request, completionHandler: completion)
117+
task.resume()
118+
return task
119+
}
120+
}
121+
118122
// MARK: - Logger
119123

120124
final public class DefaultNetworkErrorLogger: NetworkErrorLogger {

ExampleMVVMTests/Infrastructure/Network/DataTransferServiceTests.swift

+12-12
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ class DataTransferServiceTests: XCTestCase {
2323
let expectation = self.expectation(description: "Should decode mock object")
2424

2525
let responseData = #"{"name": "Hello"}"#.data(using: .utf8)
26-
let networkService = DefaultNetworkService(session: NetworkSessionMock(response: nil,
27-
data: responseData,
28-
error: nil),
26+
let networkService = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: nil,
27+
data: responseData,
28+
error: nil),
2929
config: config)
3030

3131
let sut = DefaultDataTransferService(with: networkService)
@@ -49,9 +49,9 @@ class DataTransferServiceTests: XCTestCase {
4949
let expectation = self.expectation(description: "Should not decode mock object")
5050

5151
let responseData = #"{"age": 20}"#.data(using: .utf8)
52-
let networkService = DefaultNetworkService(session: NetworkSessionMock(response: nil,
53-
data: responseData,
54-
error: nil),
52+
let networkService = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: nil,
53+
data: responseData,
54+
error: nil),
5555
config: config)
5656

5757
let sut = DefaultDataTransferService(with: networkService)
@@ -78,9 +78,9 @@ class DataTransferServiceTests: XCTestCase {
7878
statusCode: 500,
7979
httpVersion: "1.1",
8080
headerFields: nil)
81-
let networkService = DefaultNetworkService(session: NetworkSessionMock(response: response,
82-
data: responseData,
83-
error: DataTransferErrorMock.someError),
81+
let networkService = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: response,
82+
data: responseData,
83+
error: DataTransferErrorMock.someError),
8484
config: config)
8585

8686
let sut = DefaultDataTransferService(with: networkService)
@@ -111,9 +111,9 @@ class DataTransferServiceTests: XCTestCase {
111111
statusCode: 200,
112112
httpVersion: "1.1",
113113
headerFields: [:])
114-
let networkService = DefaultNetworkService(session: NetworkSessionMock(response: response,
115-
data: nil,
116-
error: nil),
114+
let networkService = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: response,
115+
data: nil,
116+
error: nil),
117117
config: config)
118118

119119
let sut = DefaultDataTransferService(with: networkService)

ExampleMVVMTests/Infrastructure/Network/Mocks/NetworkSessionMock.swift renamed to ExampleMVVMTests/Infrastructure/Network/Mocks/NetworkSessionManagerMock.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
//
2-
// NetworkSessionMock.swift
2+
// NetworkSessionManagerMock.swift
33
// ExampleMVVMTests
44
//
55
// Created by Oleh Kudinov on 16.08.19.
66
//
77

88
import Foundation
99

10-
struct NetworkSessionMock: NetworkSession {
10+
struct NetworkSessionManagerMock: NetworkSessionManager {
1111
let response: HTTPURLResponse?
1212
let data: Data?
1313
let error: Error?
1414

15-
func loadData(from request: URLRequest,
16-
completion: @escaping (Data?, URLResponse?, Error?) -> Void) -> NetworkCancellable {
15+
func request(_ request: URLRequest,
16+
completion: @escaping CompletionHandler) -> NetworkCancellable {
1717
completion(data, response, error)
1818
return URLSessionDataTask()
1919
}

ExampleMVVMTests/Infrastructure/Network/NetworkServiceTests.swift

+18-18
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ class NetworkServiceTests: XCTestCase {
4141
let expectation = self.expectation(description: "Should return correct data")
4242

4343
let expectedResponseData = "Response data".data(using: .utf8)!
44-
let sut = DefaultNetworkService(session: NetworkSessionMock(response: nil,
45-
data: expectedResponseData,
46-
error: nil),
44+
let sut = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: nil,
45+
data: expectedResponseData,
46+
error: nil),
4747
config: config)
4848
//when
4949
_ = sut.request(endpoint: EndpointMock(path: "http://mock.test.com", method: .get)) { result in
@@ -64,9 +64,9 @@ class NetworkServiceTests: XCTestCase {
6464
let expectation = self.expectation(description: "Should return hasStatusCode error")
6565

6666
let cancelledError = NSError(domain: "network", code: NSURLErrorCancelled, userInfo: nil)
67-
let sut = DefaultNetworkService(session: NetworkSessionMock(response: nil,
68-
data: nil,
69-
error: cancelledError as Error),
67+
let sut = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: nil,
68+
data: nil,
69+
error: cancelledError as Error),
7070
config: config)
7171
//when
7272
_ = sut.request(endpoint: EndpointMock(path: "http://mock.test.com", method: .get)) { result in
@@ -92,9 +92,9 @@ class NetworkServiceTests: XCTestCase {
9292
let expectation = self.expectation(description: "Should return correct data")
9393

9494
let expectedResponseData = "Response data".data(using: .utf8)!
95-
let sut = DefaultNetworkService(session: NetworkSessionMock(response: nil,
96-
data: expectedResponseData,
97-
error: nil),
95+
let sut = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: nil,
96+
data: expectedResponseData,
97+
error: nil),
9898
config: config)
9999
//when
100100
_ = sut.request(endpoint: EndpointMock(path: "-;@,?:ą", method: .get)) { result in
@@ -123,9 +123,9 @@ class NetworkServiceTests: XCTestCase {
123123
statusCode: 500,
124124
httpVersion: "1.1",
125125
headerFields: [:])
126-
let sut = DefaultNetworkService(session: NetworkSessionMock(response: response,
127-
data: nil,
128-
error: NetworkErrorMock.someError),
126+
let sut = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: response,
127+
data: nil,
128+
error: NetworkErrorMock.someError),
129129
config: config)
130130
//when
131131
_ = sut.request(endpoint: EndpointMock(path: "http://mock.test.com", method: .get)) { result in
@@ -149,9 +149,9 @@ class NetworkServiceTests: XCTestCase {
149149
let expectation = self.expectation(description: "Should return hasStatusCode error")
150150

151151
let error = NSError(domain: "network", code: NSURLErrorNotConnectedToInternet, userInfo: nil)
152-
let sut = DefaultNetworkService(session: NetworkSessionMock(response: nil,
153-
data: nil,
154-
error: error as Error),
152+
let sut = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: nil,
153+
data: nil,
154+
error: error as Error),
155155
config: config)
156156

157157
//when
@@ -195,9 +195,9 @@ class NetworkServiceTests: XCTestCase {
195195

196196
let error = NSError(domain: "network", code: NSURLErrorNotConnectedToInternet, userInfo: nil)
197197
let networkErrorLogger = NetworkErrorLoggerMock()
198-
let sut = DefaultNetworkService(session: NetworkSessionMock(response: nil,
199-
data: nil,
200-
error: error as Error),
198+
let sut = DefaultNetworkService(sessionManager: NetworkSessionManagerMock(response: nil,
199+
data: nil,
200+
error: error as Error),
201201
config: config,
202202
logger: networkErrorLogger)
203203
//when

0 commit comments

Comments
 (0)