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"))
✅ asnycMap
let result = await users.asyncMap { $0.someAsyncTask }let optionalValue: Int? = nil
✅ replaceNil
let result = optionalValue.replaceNil(with: 10)
print(result) // 10let urlRequest = URLRequest
    .init("https://api.github.com")
    ✅ urlPaths
    .urlPaths(["/users", "/octocat"])
    ✅ and more
    // .urlQueries
    // .httpMethod
    // .httpBody
    // .httpHeaders
    // .requestPublisherfinal class DefaultViewController: UIViewController, SelfReturnable { }
    let controller = DefaultViewController()
        .with(\.title, "Hello")
        .with(\.hidesBottomBarWhenPushed, true)