Skip to content

Commit

Permalink
Merge pull request #10 from nayanda1/Release-1.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
hainayanda authored Jan 13, 2021
2 parents 39c3109 + efd4a62 commit 56aa8a6
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 7 deletions.
75 changes: 75 additions & 0 deletions Example/Tests/IntegratedTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,81 @@ class IntegratedTestSpec: QuickSpec {
}
expect(sResult.isSucceed).to(beTrue())
}
it("should invoke observer method") {
let randomNumber: Int = .random(in: 0..<10)
var requestResult: URLResult?
var observer: SpyObserver<URLResult>!
let request = Ness(onDuplicated: .keepAllCompletion)
.httpRequest(.get, withUrl: "https://jsonplaceholder.typicode.com/todos/\(randomNumber)")
.prepareDataRequest(with: CounterRetryControl(maxRetryCount: 3))
.validate(statusCodes: 200..<300)
waitUntil(timeout: .seconds(15)) { done in
observer = SpyObserver { result in
requestResult = result
done()
}
request.then(observing: observer, call: SpyObserver.invoke(with:))
}
guard let result = requestResult else {
fail("Fail to get data")
return
}
expect(result.isSucceed).to(beTrue())
}
it("should invoke one of observer method") {
let randomNumber: Int = .random(in: 0..<10)
var requestResult: URLResult?
var observer: SpyObserver<URLResult>!
let request = Ness(onDuplicated: .keepAllCompletion)
.httpRequest(.get, withUrl: "https://jsonplaceholder.typicode.com/todos/\(randomNumber)")
.prepareDataRequest(with: CounterRetryControl(maxRetryCount: 3))
.validate(statusCodes: 200..<300)
waitUntil(timeout: .seconds(15)) { done in
observer = SpyObserver { result in
requestResult = result
done()
}
request.then(
observing: observer,
call: SpyObserver.invoke(with:),
whenFailedCall: SpyObserver.invoke(with:)
)
}
guard let result = requestResult else {
fail("Fail to get data")
return
}
expect(result.isSucceed).to(beTrue())
}
it("should invoke observer method twice") {
let randomNumber: Int = .random(in: 0..<10)
var requestResult: URLResult?
var observer: SpyObserver<URLResult>!
let request = Ness(onDuplicated: .keepAllCompletion)
.httpRequest(.get, withUrl: "https://jsonplaceholder.typicode.com/todos/\(randomNumber)")
.prepareDataRequest(with: CounterRetryControl(maxRetryCount: 3))
.validate(statusCodes: 200..<300)
waitUntil(timeout: .seconds(15)) { done in
observer = SpyObserver { result in
requestResult = result
if observer.invokedTime == 2 {
done()
}
}
request.then(
observing: observer,
call: SpyObserver.invoke(with:),
whenFailedCall: SpyObserver.invoke(with:),
finallyCall: SpyObserver.invoke(with:)
)
}
guard let result = requestResult else {
fail("Fail to get data")
return
}
expect(result.isSucceed).to(beTrue())
expect(observer.invokedTime).toEventually(equal(2))
}
it("should get json data") {
let randomNumber: Int = .random(in: 40..<50)
var requestResult: URLResult?
Expand Down
12 changes: 12 additions & 0 deletions Example/Tests/Mock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,15 @@ extension String {
return randomString
}
}

class SpyObserver<Result> {
var invokedTime: Int = 0
let invoked: (Result) -> Void
init(_ invoked: @escaping (Result) -> Void) {
self.invoked = invoked
}
func invoke(with result: Result) {
invokedTime += 1
invoked(result)
}
}
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,17 @@ Ness.default
.executeAndForget()
```

you can do something very readable like this by separating all closure using function:
you can do something very readable like this by using observer method call:

```swift
Ness.default
.httpRequest(.get, withUrl: "https://myurl.com")
.prepareDataRequest()
.then(
run: updateTheViewWithData,
whenFailed: showFailureAlert,
finally: removeLoading
observing: self,
call: Some.updateTheView(withResult:),
whenFailedCall: Some.showFailureAlert,
finallyCall: Some.removeLoading
)
```

Expand Down Expand Up @@ -269,7 +270,24 @@ Ness.default
)
```

With custom dispatcher which will be the thread where completion run:
You could do something similar with observer and its method reference. It will be weak refer to observer and do nothing if the observer is already deinitialised by ARC:
```swift
Ness.default
.httpRequest(.get, withUrl: "https://myurl.com")
..
..
.prepareDataRequest()
.then(
observing: self,
call: Some.updateTheView(withResult:),
whenFailedCall: Some.showFailureAlert,
finallyCall: Some.removeLoading
)
```

All of the complement method (whenFailedCall, finallyCall) are optional. Use it when you need it.

You could give custom dispatcher which will be the thread where completion run:

```swift
Ness.default
Expand Down
2 changes: 1 addition & 1 deletion iONess.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Pod::Spec.new do |s|
s.name = 'iONess'
s.version = '1.2.2'
s.version = '1.2.3'
s.summary = 'iOS Network Session'

# This description is used to generate tags and improve search results.
Expand Down
3 changes: 2 additions & 1 deletion iONess/Classes/DropableAndResumable/DropableURLRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ extension BaseDropableURLRequest {
) { retryStatus in
switch retryStatus {
case .retryAfter(let delay):
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: onRetry)
let dispatcher: DispatchQueue = OperationQueue.current?.underlyingQueue ?? .main
dispatcher.asyncAfter(deadline: .now() + delay, execute: onRetry)
case .retry:
onRetry()
case .noRetry:
Expand Down
76 changes: 76 additions & 0 deletions iONess/Classes/Thenable/Thenable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,31 @@ public protocol Thenable {
/// - deferClosure: closure which will be run after closure or failClosure
@discardableResult
func then(run closure: @escaping (Result) -> Void, whenFailed failClosure: @escaping (Result) -> Void, finally deferClosure: @escaping (Result) -> Void) -> DropablePromise


/// Method to execute request and then run any method passed
/// - Parameters:
/// - observer: object that observe request
/// - method: observer method to call when request completed
@discardableResult
func then<Observer: AnyObject>(observing observer: Observer, call method: @escaping (Observer) -> ((Result) -> Void)) -> DropablePromise

/// Method to execute request and then run any method passed
/// - Parameters:
/// - observer: object that observe request
/// - method: observer method to call when succeed
/// - failMethod: observer method to call when fail
@discardableResult
func then<Observer: AnyObject>(observing observer: Observer, call method: @escaping (Observer) -> ((Result) -> Void), whenFailedCall failMethod: @escaping (Observer) -> ((Result) -> Void)) -> DropablePromise

/// Method to execute request and then run any method passed
/// - Parameters:
/// - observer: object that observe request
/// - method: observer method to call when succeed
/// - failMethod: observer method to call when fail
/// - finalMethod: observer method to call when request completed
@discardableResult
func then<Observer: AnyObject>(observing observer: Observer, call method: @escaping (Observer) -> ((Result) -> Void), whenFailedCall failMethod: @escaping (Observer) -> ((Result) -> Void), finallyCall finalMethod: @escaping (Observer) -> ((Result) -> Void)) -> DropablePromise
}

public extension Thenable {
Expand All @@ -54,4 +79,55 @@ public extension Thenable {
}
)
}

/// Method to execute request and then run any method passed
/// - Parameters:
/// - observer: object that observe task
/// - method: observer method to call when task completed
/// - Returns: DropablePromise object
@discardableResult
func then<Observer: AnyObject>(observing observer: Observer, call method: @escaping (Observer) -> ((Result) -> Void)) -> DropablePromise {
return then { [weak observer] result in
guard let observer = observer else { return }
method(observer)(result)
}
}

/// Method to execute request and then run any method passed
/// - Parameters:
/// - observer: object that observe task
/// - method: observer method to call when succeed
/// - failMethod: observer method to call when fail
/// - Returns: DropablePromise object
@discardableResult
func then<Observer: AnyObject>(observing observer: Observer, call method: @escaping (Observer) -> ((Result) -> Void), whenFailedCall failMethod: @escaping (Observer) -> ((Result) -> Void)) -> DropablePromise {
return then(run: { [weak observer] result in
guard let observer = observer else { return }
method(observer)(result)
}, whenFailed: { [weak observer] result in
guard let observer = observer else { return }
failMethod(observer)(result)
})
}

/// Method to execute request and then run any method passed
/// - Parameters:
/// - observer: object that observe task
/// - method: observer method to call when succeed
/// - failMethod: observer method to call when fail
/// - finalMethod: observer method to call when task completed
/// - Returns: DropablePromise object
@discardableResult
func then<Observer: AnyObject>(observing observer: Observer, call method: @escaping (Observer) -> ((Result) -> Void), whenFailedCall failMethod: @escaping (Observer) -> ((Result) -> Void), finallyCall finalMethod: @escaping (Observer) -> ((Result) -> Void)) -> DropablePromise {
return then(run: { [weak observer] result in
guard let observer = observer else { return }
method(observer)(result)
}, whenFailed: { [weak observer] result in
guard let observer = observer else { return }
failMethod(observer)(result)
}, finally: { [weak observer] result in
guard let observer = observer else { return }
finalMethod(observer)(result)
})
}
}

0 comments on commit 56aa8a6

Please sign in to comment.