We build powerful and convenient features using Combine and Swift.
Support Network, Log, Functional, Asynchronous, Endpoint and more
Just("Value")
β
asyncMap
.asyncMap({ value in
await doSomething()
})
.sink(receiveCompletion: { _ in
}, receiveValue: { _ in
}).store(in: &store)
Just("Value")
β
asyncThrowsMap
.asyncThrowsMap({ user in
try await doSomething()
})
.sink(receiveCompletion: { _ in
}, receiveValue: { _ in
}).store(in: &store)
Just("Value")
.setFailureType(to: TestError.self)
β
mapToResult
.mapToResult()
.sink { result in
switch result {
case .success(let success):
print(success) // "Value"
case .failure(_):
}
expectation.fulfill()
}.store(in: &store)
Fail<Any, TestError>(error: TestError.testError)
β
mapToResult
.mapToResult()
.sink { result in
switch result {
case .success(_):
case .failure(let failure):
print(failure) // TestError.testError
}
expectation.fulfill()
}.store(in: &store)
Task {
β
asyncThrows
let result = try? await Just("Value").asyncThrows
print(result) // Optional("Value")
β
asyncOptionalTry
let result = await Fail(error: TestError.testError).asyncOptionalTry
print(result) // nil
β
asyncReplaceError
let result = await Fail(error: TestError.testError).asyncReplaceError(with: 10)
print(result) // 10
β
async
let result = await Just(1).async
print(result) // 1
β
asyncResult - Success
let result = await Just("Value).asyncResult
print(result) // success("Value")
β
asyncResult - Failure
let result = await Fail<Any, TestError>(error: TestError.testError).asyncResult
print(result) // failure(TestSource.TestError.testError)
}
β
EndPoint - GET
EndPoint
.init("https://api.github.com")
.urlPaths(["/users", "/octocat"])
β
responseHandler
.responseHandler(handleResponse(_:))
β
requestPublisher
.requestPublisher(expect: User.self)
.sink { _ in
} receiveValue: { user in
print(user)
}.store(in: &store)
β
EndPoint - POST
struct RequestBody: Encodable {
let id: Int
}
let dictionary = ["id": 123]
let encodableTypeBody = RequestBody(id: 123)
EndPoint
.init("https://api.github.com")
.urlPaths(["/users", "/octocat"])
.httpMethod(.post)
βοΈ body with Encodable Type
.httpBody(encodableTypeBody)
βοΈ body with Dictionary
.httpBody(dictionary)
β
responseHandler
.responseHandler(handleResponse(_:))
β
requestPublisher
.requestPublisher(expect: User.self)
.sink { _ in
} receiveValue: { user in
print(user)
}.store(in: &store)
// We support the body parameters of the Codable type and the [String: Any] type.
let formData = MultiPartFormData()
let bodyData = formData.bodyData(
data: data,
parameters: parameters,
name: "image",
filename: "imagename.png",
mimeType: "image/png"
)
EndPoint
.init(basURL)
.urlPaths(paths)
.httpHeaders(formData.headers)
.httpMethod(.post)
.uploadPublisher(from: bodyData, expect: Response.self)
.sink { _ in
} receiveValue: { _ in
}.store(in: &store)
// Given
let sut: UserNetwork = .init()
β
inject fail
sut.getUser = { _ in .inject(.failure(NSError())) }
// When
β
asyncThrows
let user = try? await sut.getUser("octopus").asyncThrows
// Then
XCTAssertNil(user)
// Given
let sut: UserNetwork = .init()
let mockData = User(login: "octopus", id: 112233)
β
inject success
sut.getUser = { _ in .inject(.success(mockData)) }
// When
β
asyncThrows
let user = try? await sut.getUser("octopus").asyncThrows
// Then
XCTAssertNotNil(user)
if let user {
XCTAssertEqual(mockData.id, user.id)
}
let url = URL(string: "https://api.github.com/users/octopus")!
β
inject HTTPURLResponse
let response = HTTPURLResponse(
url: url,
statusCode: 500,
httpVersion: nil,
headerFields: nil
)
β
MockURLSession
let mockSession = MockURLSession(response: response)
β
printLog
URLSession.printLog = true
β
logStyle
URLSession.requestLogStyle = .string
URLSession.responseLogStyle = .string
EndPoint
.init(basURL)
.urlPaths(paths)
β
logStyle for each endpoint
.requestLogStyle(.json) // request data will print pretty json
.responseLogStyle(.non) // will not print body
.requestPublisher(expect: User.self)
URLRequest(url: url)
β
requestPublisher
.requestPublisher(expect: User.self)
.sink { _ in
} receiveValue: { user in
print(user)
}.store(in: &store)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .keyDecodingStrategy
URLSession.decoder = decoder
β
eventPublisher
button.eventPublisher(for: .touchUpInside).sink { _ in
print("TAP")
}.store(in: &store)
β
textPublisher
textField.textPublisher.sink { text in
print(text)
}.store(in: &store)
β
controlPublisher
tableRefresh.controlPublisher(for: .valueChanged).sink { _ in
print("Pulled")
}.store(in: &store)
β
tapGesturePublisher
uiView.tapGesturePublisher.sink { _ in
print("Tap")
}.store(in: &store)
β
switchPublisher
uiSwitch.switchPublisher.sink {
print($0)
}.store(in: &store)
let users: [User] = [.....]
β
find
let user = users.find(\.login, "octocat") // Optional(User(login: "octocat"))
let optionalValue: Int? = nil
β
replaceNil
let result = optionalValue.replaceNil(with: 10)
print(result) // 10
let urlRequest = URLRequest
.init("https://api.github.com")
β
urlPaths
.urlPaths(["/users", "/octocat"])
β
and more
// .urlQueries
// .httpMethod
// .httpBody
// .httpHeaders
// .requestPublisher
final class DefaultViewController: UIViewController, SelfReturnable { }
let controller = DefaultViewController()
.with(\.title, "Hello")
.with(\.hidesBottomBarWhenPushed, true)