Skip to content

Commit eba288a

Browse files
Remove strongly typed error. Now it is easier to chain Promises.
1 parent 41c558d commit eba288a

File tree

6 files changed

+67
-49
lines changed

6 files changed

+67
-49
lines changed

Tests/swift-sdk-swift-tests/Mocks.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import UserNotifications
1111
@testable import IterableSDK
1212

1313
class MockNotificationStateProvider : NotificationStateProviderProtocol {
14-
var notificationsEnabled: Promise<Bool, Error> {
15-
let promise = Promise<Bool, Error>()
14+
var notificationsEnabled: Promise<Bool> {
15+
let promise = Promise<Bool>()
1616
DispatchQueue.main.async {
1717
promise.resolve(with: self.enabled)
1818
}

Tests/swift-sdk-swift-tests/PromiseTests.swift

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,16 @@ class PromiseTests: XCTestCase {
4141
expectation1.isInverted = true
4242
let expectation2 = expectation(description: "test map failure")
4343

44-
let f1: Future<String, MyError> = createFailureFuture(withError: MyError(message: "zeeErrorMessage"))
44+
let f1: Future<String> = createFailureFuture(withError: MyError(message: "zeeErrorMessage"))
4545
let f2 = f1.map {$0.count}
4646

4747
f2.onSuccess { (value) in
4848
expectation1.fulfill()
4949
}.onFailure { error in
50-
XCTAssertEqual(error.message, "zeeErrorMessage")
51-
expectation2.fulfill()
50+
if let myError = error as? MyError {
51+
XCTAssertEqual(myError.message, "zeeErrorMessage")
52+
expectation2.fulfill()
53+
}
5254
}
5355

5456
wait(for: [expectation1], timeout: testExpectationTimeoutForInverted)
@@ -84,17 +86,19 @@ class PromiseTests: XCTestCase {
8486
expectation1.isInverted = true
8587
let expectation2 = expectation(description: "test flatMap failure")
8688

87-
let f1: Future<String, MyError> = createFailureFuture(withError: MyError(message: "zeeErrorMessage"))
89+
let f1: Future<String> = createFailureFuture(withError: MyError(message: "zeeErrorMessage"))
8890

89-
let f2 = f1.flatMap { (firstValue) -> Future<String, MyError> in
91+
let f2 = f1.flatMap { (firstValue) -> Future<String> in
9092
return self.createSucessfulFuture(withValue: "zeeString")
9193
}
9294

9395
f2.onSuccess { (secondValue) in
9496
expectation1.fulfill()
9597
} .onFailure {(error) in
96-
XCTAssertEqual(error.message, "zeeErrorMessage")
97-
expectation2.fulfill()
98+
if let myError = error as? MyError {
99+
XCTAssertEqual(myError.message, "zeeErrorMessage")
100+
expectation2.fulfill()
101+
}
98102
}
99103

100104
wait(for: [expectation1], timeout: testExpectationTimeoutForInverted)
@@ -109,15 +113,17 @@ class PromiseTests: XCTestCase {
109113

110114
let f1 = createSucessfulFuture(withValue: "zeeString")
111115

112-
let f2 = f1.flatMap { (firstValue) -> Future<String, MyError> in
116+
let f2 = f1.flatMap { (firstValue) -> Future<String> in
113117
return self.createFailureFuture(withError: MyError(message: "zeeErrorMessage"))
114118
}
115119

116120
f2.onSuccess { (secondValue) in
117121
expectation1.fulfill()
118122
}.onFailure {(error) in
119-
XCTAssertEqual(error.message, "zeeErrorMessage")
120-
expectation2.fulfill()
123+
if let myError = error as? MyError {
124+
XCTAssertEqual(myError.message, "zeeErrorMessage")
125+
expectation2.fulfill()
126+
}
121127
}
122128

123129
wait(for: [expectation1], timeout: testExpectationTimeoutForInverted)
@@ -129,7 +135,7 @@ class PromiseTests: XCTestCase {
129135
let expectation2 = expectation(description: "test future init with success, inverted")
130136
expectation2.isInverted = true
131137

132-
let f1: Future<String, MyError> = Promise<String, MyError>(value: "zeeValue")
138+
let f1: Future<String> = Promise<String>(value: "zeeValue")
133139

134140
f1.onSuccess { (value) in
135141
XCTAssertEqual(value, "zeeValue")
@@ -147,22 +153,24 @@ class PromiseTests: XCTestCase {
147153
expectation1.isInverted = true
148154
let expectation2 = expectation(description: "test future init with failure")
149155

150-
let f1: Future<String, MyError> = Promise<String, MyError>(error: MyError(message: "zeeErrorMessage"))
156+
let f1: Future<String> = Promise<String>(error: MyError(message: "zeeErrorMessage"))
151157

152158
f1.onSuccess { (value) in
153159
expectation1.fulfill()
154160
}.onFailure { error in
155-
XCTAssertEqual(error.message, "zeeErrorMessage")
156-
expectation2.fulfill()
161+
if let myError = error as? MyError {
162+
XCTAssertEqual(myError.message, "zeeErrorMessage")
163+
expectation2.fulfill()
164+
}
157165
}
158166

159167
wait(for: [expectation1], timeout: testExpectationTimeoutForInverted)
160168
wait(for: [expectation2], timeout: testExpectationTimeout)
161169
}
162170

163171

164-
private func createSucessfulFuture<T>(withValue value: T) -> Future<T, MyError> {
165-
let future = Promise<T, MyError>()
172+
private func createSucessfulFuture<T>(withValue value: T) -> Future<T> {
173+
let future = Promise<T>()
166174

167175
DispatchQueue.main.async {
168176
future.resolve(with: value)
@@ -171,8 +179,8 @@ class PromiseTests: XCTestCase {
171179
return future
172180
}
173181

174-
private func createFailureFuture<T>(withError error: MyError) -> Future<T, MyError> {
175-
let future = Promise<T, MyError>()
182+
private func createFailureFuture<T>(withError error: MyError) -> Future<T> {
183+
let future = Promise<T>()
176184

177185
DispatchQueue.main.async {
178186
future.reject(with: error)

swift-sdk/Internal/IterableAPIInternal.swift

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,18 @@ final class IterableAPIInternal : NSObject, PushTrackerProtocol {
117117
}).onSuccess { (json) in
118118
onSuccess?(json)
119119
}.onFailure { (error) in
120-
onFailure?(error.errorMessage, error.data)
120+
if let sendError = error as? SendRequestError {
121+
onFailure?(sendError.errorMessage, sendError.data)
122+
} else {
123+
onFailure?("failed to create user", nil)
124+
}
121125
}
122126
} else {
123127
register(token: token, appName: appName, pushServicePlatform: config.pushPlatform, onSuccess: onSuccess, onFailure: onFailure)
124128
}
125129
}
126130

127-
@discardableResult private func register(token: Data, appName: String, pushServicePlatform: PushServicePlatform, onSuccess: OnSuccessHandler? = nil, onFailure: OnFailureHandler? = nil) -> Future<SendRequestValue, SendRequestError> {
131+
@discardableResult private func register(token: Data, appName: String, pushServicePlatform: PushServicePlatform, onSuccess: OnSuccessHandler? = nil, onFailure: OnFailureHandler? = nil) -> Future<SendRequestValue> {
128132
guard email != nil || userId != nil else {
129133
ITBError("Both email and userId are nil")
130134
onFailure?("Both email and userId are nil", nil)
@@ -232,7 +236,7 @@ final class IterableAPIInternal : NSObject, PushTrackerProtocol {
232236
}
233237
}
234238

235-
private func createUser(withUserId userId: String) -> Future<SendRequestValue, SendRequestError> {
239+
private func createUser(withUserId userId: String) -> Future<SendRequestValue> {
236240
var args = [AnyHashable : Any]()
237241
args[.ITBL_KEY_USER_ID] = userId
238242

@@ -526,11 +530,15 @@ final class IterableAPIInternal : NSObject, PushTrackerProtocol {
526530
return IterableRequestUtil.createPostRequest(forApiEndPoint: .ITBL_ENDPOINT_API, path: path, args: [AnyHashable.ITBL_KEY_API_KEY : apiKey], body: body)
527531
}
528532

529-
@discardableResult func sendRequest(_ request: URLRequest, onSuccess: OnSuccessHandler? = nil, onFailure: OnFailureHandler? = nil) -> Future<SendRequestValue, SendRequestError> {
533+
@discardableResult func sendRequest(_ request: URLRequest, onSuccess: OnSuccessHandler? = nil, onFailure: OnFailureHandler? = nil) -> Future<SendRequestValue> {
530534
return NetworkHelper.sendRequest(request, usingSession: networkSession).onSuccess { (json) in
531535
onSuccess?(json)
532536
}.onFailure { (failureInfo) in
533-
onFailure?(failureInfo.errorMessage, failureInfo.data)
537+
if let sendError = failureInfo as? SendRequestError {
538+
onFailure?(sendError.errorMessage, sendError.data)
539+
} else {
540+
onFailure?("send request failed", nil)
541+
}
534542
}
535543
}
536544

@@ -789,8 +797,10 @@ final class IterableAPIInternal : NSObject, PushTrackerProtocol {
789797
NetworkHelper.sendRequest(request, usingSession: networkSession).onSuccess { (json) in
790798
self.handleDDL(json: json)
791799
}.onFailure { (failureInfo) in
792-
if let errorMessage = failureInfo.errorMessage {
800+
if let sendError = failureInfo as? SendRequestError, let errorMessage = sendError.errorMessage {
793801
ITBError(errorMessage)
802+
} else {
803+
ITBError("failed to send handleDDl request")
794804
}
795805
}
796806
}

swift-sdk/Internal/IterableAppIntegrationInternal.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import UserNotifications
1111

1212
// Returns whether notifications are enabled
1313
protocol NotificationStateProviderProtocol {
14-
var notificationsEnabled : Promise<Bool, Error> {get}
14+
var notificationsEnabled : Promise<Bool> {get}
1515
func registerForRemoteNotifications()
1616
}
1717

1818
struct SystemNotificationStateProvider : NotificationStateProviderProtocol {
19-
var notificationsEnabled: Promise<Bool, Error> {
20-
let result = Promise<Bool, Error>()
19+
var notificationsEnabled: Promise<Bool> {
20+
let result = Promise<Bool>()
2121

2222
if #available(iOS 10.0, *) {
2323
UNUserNotificationCenter.current().getNotificationSettings { settings in

swift-sdk/Internal/NetworkHelper.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ struct SendRequestError : Error {
1717
self.data = data
1818
}
1919

20-
static func createFailedFuture(reason: String? = nil) -> Future<SendRequestValue, SendRequestError> {
21-
return Promise<SendRequestValue, SendRequestError>(error: SendRequestError(errorMessage: reason))
20+
static func createFailedFuture(reason: String? = nil) -> Future<SendRequestValue> {
21+
return Promise<SendRequestValue>(error: SendRequestError(errorMessage: reason))
2222
}
2323
}
2424

@@ -43,8 +43,8 @@ extension URLSession : NetworkSessionProtocol {
4343
}
4444

4545
struct NetworkHelper {
46-
static func sendRequest(_ request: URLRequest, usingSession networkSession: NetworkSessionProtocol) -> Future<SendRequestValue, SendRequestError> {
47-
let promise = Promise<SendRequestValue, SendRequestError>()
46+
static func sendRequest(_ request: URLRequest, usingSession networkSession: NetworkSessionProtocol) -> Future<SendRequestValue> {
47+
let promise = Promise<SendRequestValue>()
4848

4949
networkSession.makeRequest(request) { (data, response, error) in
5050
let result = createResultFromNetworkResponse(data: data, response: response, error: error)
@@ -59,7 +59,7 @@ struct NetworkHelper {
5959
return promise
6060
}
6161

62-
static func createResultFromNetworkResponse(data: Data?, response: URLResponse?, error: Error?) -> Result<SendRequestValue, SendRequestError> {
62+
static func createResultFromNetworkResponse(data: Data?, response: URLResponse?, error: Error?) -> Result<SendRequestValue> {
6363
if let error = error {
6464
return .error(SendRequestError(errorMessage: "\(error.localizedDescription)", data: data))
6565
}

swift-sdk/Internal/Promise.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@
88

99
import Foundation
1010

11-
enum Result<Value, ErrorType> {
11+
enum Result<Value> {
1212
case value(Value)
13-
case error(ErrorType)
13+
case error(Error)
1414
}
1515

1616
// This has only two public methods
1717
// either there is a success with result
1818
// or there is a failure with error
1919
// There is no way to set value a result in this class.
20-
class Future<Value, ErrorType> {
20+
class Future<Value> {
2121
fileprivate var successCallback: ((Value) -> Void)? = nil
22-
fileprivate var failureCallback: ((ErrorType) -> Void)? = nil
22+
fileprivate var failureCallback: ((Error) -> Void)? = nil
2323

24-
@discardableResult func onSuccess(block: ((Value) -> Void)? = nil) -> Future<Value, ErrorType> {
24+
@discardableResult func onSuccess(block: ((Value) -> Void)? = nil) -> Future<Value> {
2525
self.successCallback = block
2626

2727
// if a successful result already exists (from constructor), report it
@@ -32,7 +32,7 @@ class Future<Value, ErrorType> {
3232
return self
3333
}
3434

35-
@discardableResult func onFailure(block: ((ErrorType) -> Void)? = nil) -> Future<Value, ErrorType> {
35+
@discardableResult func onFailure(block: ((Error) -> Void)? = nil) -> Future<Value> {
3636
self.failureCallback = block
3737

3838
// if a failed result already exists (from constructor), report it
@@ -43,13 +43,13 @@ class Future<Value, ErrorType> {
4343
return self
4444
}
4545

46-
fileprivate var result: Result<Value, ErrorType>? {
46+
fileprivate var result: Result<Value>? {
4747
// Observe whenever a result is assigned, and report it
4848
didSet { result.map(report) }
4949
}
5050

5151
// Report success or error based on result
52-
private func report(result: Result<Value, ErrorType>) {
52+
private func report(result: Result<Value>) {
5353
switch result {
5454
case .value(let value):
5555
successCallback?(value)
@@ -63,8 +63,8 @@ class Future<Value, ErrorType> {
6363
}
6464

6565
extension Future {
66-
func flatMap<NextValue>(_ closure: @escaping (Value) -> Future<NextValue, ErrorType>) -> Future<NextValue, ErrorType> {
67-
let promise = Promise<NextValue, ErrorType>()
66+
func flatMap<NextValue>(_ closure: @escaping (Value) -> Future<NextValue>) -> Future<NextValue> {
67+
let promise = Promise<NextValue>()
6868

6969
onSuccess { (value) in
7070
let future = closure(value)
@@ -85,8 +85,8 @@ extension Future {
8585
return promise
8686
}
8787

88-
func map<NextValue>(_ closure: @escaping (Value) -> NextValue) -> Future<NextValue, ErrorType> {
89-
let promise = Promise<NextValue, ErrorType>()
88+
func map<NextValue>(_ closure: @escaping (Value) -> NextValue) -> Future<NextValue> {
89+
let promise = Promise<NextValue>()
9090

9191
onSuccess { value in
9292
let nextValue = closure(value)
@@ -103,13 +103,13 @@ extension Future {
103103

104104

105105
// This class takes the responsibility of setting value for Future
106-
class Promise<Value, ErrorType> : Future<Value, ErrorType> {
106+
class Promise<Value> : Future<Value> {
107107
init(value: Value? = nil) {
108108
super.init()
109109
result = value.map(Result.value)
110110
}
111111

112-
init(error: ErrorType) {
112+
init(error: Error) {
113113
super.init()
114114
result = Result.error(error)
115115
}
@@ -118,7 +118,7 @@ class Promise<Value, ErrorType> : Future<Value, ErrorType> {
118118
result = .value(value)
119119
}
120120

121-
func reject(with error: ErrorType) {
121+
func reject(with error: Error) {
122122
result = .error(error)
123123
}
124124
}

0 commit comments

Comments
 (0)