Skip to content

MightyCombine/MightyCombine

Repository files navigation

πŸ’ͺ MightyCombine

XCTest License: MIT Static Badge Static Badge

We build powerful and convenient features using Combine and Swift.

Support Network, Log, Functional, Asynchronous, Endpoint and more

βœ” Support Operaters

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)

βœ” Support async/ await and throws

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)
}

βœ” Support EndPoint

βœ… 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.

βœ” Support File Upload and MultiPartFormData

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)

βœ” Support XCTest

// 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)

βœ” Support Network Log

βœ… 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)

βœ” Support URLRequest

URLRequest(url: url)
    βœ… requestPublisher
    .requestPublisher(expect: User.self)
    .sink { _ in
        
    } receiveValue: { user in
        print(user)
    }.store(in: &store)

βœ” Config JSONDecoder

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .keyDecodingStrategy

URLSession.decoder = decoder 

βœ” Support UIKit

βœ… 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)

πŸ’ͺ MightySwift

βœ” Array Extension

let users: [User] = [.....]
βœ… find
let user = users.find(\.login, "octocat") // Optional(User(login: "octocat"))

βœ” Optional Extension

let optionalValue: Int? = nil
βœ… replaceNil
let result = optionalValue.replaceNil(with: 10)
print(result) // 10

βœ” URLRequest Extension

let urlRequest = URLRequest
    .init("https://api.github.com")
    βœ… urlPaths
    .urlPaths(["/users", "/octocat"])
    βœ… and more
    // .urlQueries
    // .httpMethod
    // .httpBody
    // .httpHeaders
    // .requestPublisher

βœ” SelfReturnable

final class DefaultViewController: UIViewController, SelfReturnable { }

    let controller = DefaultViewController()
        .with(\.title, "Hello")
        .with(\.hidesBottomBarWhenPushed, true)

About

We build powerful and convenient features using Combine and Swift. Support Network, Log, Functional, Asynchronous, Endpoint and more

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages