Skip to content

Instantly share code, notes, and snippets.

View wotjd's full-sized avatar

wotjd wotjd

  • Seoul, South Korea
View GitHub Profile
@wotjd
wotjd / MoyaProvider+Extension.swift
Created April 1, 2024 16:39
Moya async request with handling cancellation
import Foundation
import Moya
struct AsyncRequestError: Error {
// TODO: add Description
}
extension MoyaProvider {
// method #1 - using AsyncThrowingStream
func request(_ target: Target) async throws -> Response {
protocol AProtocol {
func callAsFunction()
}
class AClass: AProtocol {
func callAsFunction() { print("hi there") }
}
let a: any AProtocol = AClass()
a() // prints "hi there"
@wotjd
wotjd / SampleView.swift
Last active February 25, 2023 13:08
Present UIKit based sheet as simple as SwiftUI
import SwiftUI
struct SampleView: View {
@State presentsSheet = false
var body: some View {
Button { presentsSheet.toggle() } label: { Text("Toggle Sheet") }
.uiKitSheet(
isPresented: $presentsSheet,
onDismiss: { print("dismissed!") },
import Combine
extension Publisher {
func makeHot() -> AnyPublisher<Output, Failure> {
let subject = PassthroughSubject<Void, Never>()
let publisher = map(Result.success)
.catch { Just(.failure($0)) }
.prefix(untilOutputFrom: subject)
.makeConnectable()
let connection = publisher.connect()
@wotjd
wotjd / compositional_waterfall_layout.swift
Created October 26, 2022 11:37
a simple implementation of waterfall layout using compositional layout
import UIKit
extension UICollectionViewCompositionalLayout {
static func waterfall(
columnCount: Int,
interItemSpacing: CGFloat = 0,
lineSpacing: CGFloat = 0,
itemCountProvider: @escaping (Int) -> Int,
itemSizeProvider: @escaping (IndexPath) -> CGSize,
sectionConfigurator: @escaping (inout NSCollectionLayoutSection) -> Void = { _ in },
import Foundation
import Combine
// shareWhileConnected using Combine Proof of Concept
extension Publisher {
func shareWhileConnected() -> Publishers.ShareWhileConnected<Self, PassthroughSubject<Output, Failure>> {
.init(upstream: self)
}
}
@wotjd
wotjd / ASAuthorizationController+Combine.swift
Created October 4, 2022 17:38
Sign in with Apple + Combine (CombineCocoa)
import AuthenticationServices
import Combine
import CombineCocoa
extension ASAuthorizationController {
private var delegateProxy: AuthorizationControllerDelegateProxy {
.createDelegateProxy(for: self)
}
var didCompleteWithAuthroizationPublisher: AnyPublisher<ASAuthorization, Never> {
@wotjd
wotjd / AsyncStream+Extension.swift
Last active September 2, 2022 11:42
some utility operators for AsyncStream inspired by RxSwift
import Foundation
extension AsyncStream {
init(
_ elementType: Element.Type = Element.self,
bufferingPolicy limit: AsyncStream<Element>.Continuation.BufferingPolicy = .unbounded,
_ build: @escaping (AsyncStream<Element>.Continuation) async -> Void
) {
self = AsyncStream(elementType, bufferingPolicy: limit) { continuation in
Task { await build(continuation) }
// poor arrow function expression implementation like javascript's using infix operator and closure
precedencegroup ArrowFunctionExpressionPrecedence {
associativity: left
higherThan: BitwiseShiftPrecedence
}
infix operator =>: ArrowFunctionExpressionPrecedence
infix operator ==>: ArrowFunctionExpressionPrecedence