Skip to content

Commit 7affc27

Browse files
committed
Add initial support for Combine, tests still need to be added
1 parent 889918a commit 7affc27

3 files changed

Lines changed: 59 additions & 0 deletions

File tree

Sources/ObservableNetworking/Protocols/Network.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,17 @@
77

88
import Foundation
99
import RxSwift
10+
import Combine
1011

1112
public protocol Network {
1213
// RxSwift
1314
func request(method: HTTPMethod, endpoint: String, parameters: [String : Any]?, headers: [String : String]?) -> Observable<Result<Data, NetworkError>>
1415
func authenticatedRequest(method: HTTPMethod, endpoint: String, parameters: [String : Any]?, headers: [String : String]?) -> Observable<Result<Data, NetworkError>>
16+
17+
// Combine
18+
@available(iOS 13.0, *)
19+
func request(method: HTTPMethod, endpoint: String, parameters: [String : Any]?, headers: [String : String]?) -> AnyPublisher<Data, NetworkError>
20+
@available(iOS 13.0, *)
21+
func authenticatedRequest(method: HTTPMethod, endpoint: String, parameters: [String : Any]?, headers: [String : String]?) -> AnyPublisher<Data, NetworkError>
1522
}
1623

Sources/ObservableNetworking/Protocols/Session.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,27 @@
66
//
77

88
import Foundation
9+
import Combine
910

1011
/// Protocol that allows dependecy injection for the express purpose of mocking `URLSession` during testing. This should not be used elsewhere
1112
public protocol Session {
1213
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
1314
func dataTask(with request: NSURLRequest, completionHandler: @escaping DataTaskResult) -> DataTask
15+
16+
@available(iOS 13.0, *)
17+
func dataTaskPublisher<T: TaskPublisher>(for request: URLRequest) -> T
1418
}
1519

1620
// Make URLSession connform to Session protocol
1721
extension URLSession: Session {
1822
public func dataTask(with request: NSURLRequest, completionHandler: @escaping DataTaskResult) -> DataTask {
1923
return dataTask(with: request, completionHandler: completionHandler) as DataTask
2024
}
25+
26+
@available(iOS 13.0, *)
27+
public func dataTaskPublisher<T: TaskPublisher>(for request: URLRequest) -> T {
28+
return dataTaskPublisher(for: request) as T
29+
}
2130
}
2231

2332
/// Protocol that allows dependecy injection for the express purpose of mocking `URLSession` during testing. This should not be used elsewhere
@@ -27,3 +36,15 @@ public protocol DataTask {
2736

2837
// Make URLSessionDataTask conform to DataTask protocol
2938
extension URLSessionDataTask: DataTask {}
39+
40+
/// Protocol that allows dependecy injection for the express purpose of mocking `URLSession` during testing. This should not be used elsewhere
41+
@available(iOS 13.0, *)
42+
public protocol TaskPublisher: Publisher {
43+
}
44+
45+
// Make DataTaskPublisher conform to TaskPublisher protocol
46+
@available(iOS 13.0, *)
47+
extension URLSession.DataTaskPublisher: TaskPublisher {}
48+
49+
@available(iOS 13.0, *)
50+
extension AnyPublisher: TaskPublisher {}

Tests/ObservableNetworkingTests/MockURLSession.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import Foundation
99
import ObservableNetworking
10+
import Combine
1011

1112
class MockURLSession: Session {
1213

@@ -45,6 +46,12 @@ class MockURLSession: Session {
4546
return dataTask
4647
}
4748

49+
@available(iOS 13.0, *)
50+
func dataTaskPublisher<T>(for request: URLRequest) -> T where T : TaskPublisher {
51+
lastURL = request.url
52+
return MockDataTaskPublisher() as! T
53+
}
54+
4855
private func createCookieHeader(for url: URL?) -> [String : String] {
4956
guard let cookieURL = url else { return [:] }
5057

@@ -70,3 +77,27 @@ class MockURLSessionDataTask: DataTask {
7077
resumeWasCalled = true
7178
}
7279
}
80+
81+
class MockDataTaskPublisher: TaskPublisher {
82+
typealias Output = Data
83+
typealias Failure = NetworkError
84+
85+
@available(iOS 13.0, *)
86+
func receive<S>(subscriber: S) where S : Subscriber, MockDataTaskPublisher.Failure == S.Failure, MockDataTaskPublisher.Output == S.Input {}
87+
}
88+
89+
@available(iOS 13.0, *)
90+
extension Data: Subscriber {
91+
public typealias Input = Self
92+
public typealias Failure = NetworkError
93+
94+
public var combineIdentifier: CombineIdentifier {
95+
CombineIdentifier()
96+
}
97+
98+
public func receive(subscription: Subscription) {}
99+
100+
public func receive(completion: Subscribers.Completion<NetworkError>) {}
101+
102+
public func receive(_ input: Data) -> Subscribers.Demand { .unlimited }
103+
}

0 commit comments

Comments
 (0)