Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
ahmed3elshaer avatar

Combine Framework

  • 21 installs
  • 60 repo stars
  • Updated June 14, 2026
  • ahmed3elshaer/everything-claude-code-mobile

combine-framework is a Claude Code skill covering Apple's Combine framework for reactive programming with publishers, subscribers, and operators.

About

combine-framework is a Claude Code skill covering Apple's Combine reactive programming framework for iOS. It explains publishers and subscribers, publisher types like Just, Future, and PassthroughSubject, and common operators for transforming, filtering, and combining streams. It also covers error handling with catch, retry, and replaceError, and SwiftUI integration through @Published, assign, and cancellable storage.

  • Apple Combine reactive-programming patterns for iOS
  • Publishers, subjects, and operators for transform, filter, and combine
  • Error handling and SwiftUI integration with @Published and assign

Combine Framework by the numbers

  • 21 all-time installs (skills.sh)
  • Ranked #754 of 1,039 Mobile Development skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
At a glance

combine-framework capabilities & compatibility

Capabilities
combine framework · reactive programming · swiftui binding
Use cases
frontend
Pricing
Free
From the docs

What combine-framework says it does

Apple Combine framework for reactive programming. Publishers, subscribers, operators, and error handling.
SKILL.md
Reactive programming with Apple's Combine framework.
SKILL.md
npx skills add https://github.com/ahmed3elshaer/everything-claude-code-mobile --skill combine-framework

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs21
repo stars60
Last updatedJune 14, 2026
Repositoryahmed3elshaer/everything-claude-code-mobile

What it does

Use Apple Combine to build reactive data flows and bind publishers into SwiftUI view models on iOS.

Who is it for?

Building reactive data pipelines and binding publishers into SwiftUI view models on iOS.

Skip if: Android reactive frameworks or non-Apple reactive stacks; it is Combine specific.

When should I use this skill?

Working with Combine publishers, operators, error handling, or SwiftUI reactive bindings.

What you get

Correct Combine pipelines with proper operators, error recovery, and SwiftUI @Published bindings.

  • Reactive Combine pipeline code
  • SwiftUI-bound view models

Files

SKILL.mdMarkdownGitHub ↗

Combine Framework

Reactive programming with Apple's Combine framework.

Core Concepts

Publisher & Subscriber

// ✅ Basic subscription
let publisher = Just("Hello")
let subscriber = publisher.sink { value in
    print(value)  // "Hello"
}

Creating Publishers

// ✅ Just - single value
Just(42)

// ✅ Future - async result
Future { promise in
    promise(.success(42))
    // or
    promise(.failure(Error()))
}

// ✅ PassthroughSubject - broadcast
let subject = PassthroughSubject<String, Never>()
subject.send("Hello")
subject.send(completion: .finished)

// ✅ CurrentValueSubject - holds current value
let currentValue = CurrentValueSubject<Int, Never>(0)
currentValue.send(1)
print(currentValue.value)  // 1

// ✅ @Published in ObservableObject
class ViewModel: ObservableObject {
    @Published var count = 0
}

Common Operators

Transform

// ✅ map - transform values
[1, 2, 3].publisher
    .map { $0 * 2 }
    .sink { print($0) }  // 2, 4, 6

// ✅ flatMap - nested publishers
[1, 2, 3].publisher
    .flatMap { value in
        Future { promise in
            promise(.success(value * 2))
        }
    }
    .sink { print($0) }

// ✅ scan - accumulate
(1...10).publisher
    .scan(0, +)
    .sink { print($0) }  // 1, 3, 6, 10, 15...

Filter

// ✅ filter
(1...10).publisher
    .filter { $0 % 2 == 0 }
    .sink { print($0) }  // 2, 4, 6, 8, 10

// ✅ removeDuplicates
[1, 1, 2, 2, 3].publisher
    .removeDuplicates()
    .sink { print($0) }  // 1, 2, 3

// ✅ debounce - wait for pause
searchTextPublisher
    .debounce(for: .milliseconds(300), scheduler: RunLoop.main)
    .sink { text in
        performSearch(text)
    }

Combine

// ✅ combineLatest - waits for both
let namePublisher = CurrentValueSubject<String, Never>("")
let agePublisher = CurrentValueSubject<Int, Never>(0)

Publishers.CombineLatest(namePublisher, agePublisher)
    .sink { name, age in
        print("\(name), \(age)")
    }

// ✅ merge - same type, interleaved
let p1 = PassthroughSubject<Int, Never>()
let p2 = PassthroughSubject<Int, Never>()

p1.merge(with: p2)
    .sink { print($0) }

// ✅ zip - pairs up
let names = PassthroughSubject<String, Never>()
let ages = PassthroughSubject<Int, Never>()

names.zip(ages)
    .sink { print("\($0) is \($1) years old") }

Error Handling

// ✅ catch - recover from error
failingPublisher
    .catch { error in
        return Just("Fallback value")
    }
    .sink { print($0) }

// ✅ retry - attempt on failure
failingPublisher
    .retry(3)
    .sink { print($0) }

// ✅ replaceError - replace with default
riskyPublisher
    .replaceError(with: "Default")
    .sink { print($0) }

// ✅ mapError - transform error
riskyPublisher
    .mapError { error in
        return MyError.custom(error)
    }
    .sink { _ in } receiveValue: { error in
        print(error)
    }

SwiftUI Integration

@Published

class HomeViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var isLoading = false
    @Published var errorMessage: String?

    private var cancellables = Set<AnyCancellable>()

    func loadUsers() {
        isLoading = true

        service.getUsers()
            .receive(on: DispatchQueue.main)
            .sink { [weak self] completion in
                self?.isLoading = false
                if case .failure(let error) = completion {
                    self?.errorMessage = error.localizedDescription
                }
            } receiveValue: { [weak self] users in
                self?.users = users
            }
            .store(in: &cancellables)
    }
}

Assign

// ✅ assign to property
publisher
    .map(\.name)
    .assign(to: &$viewModel.userName)

// ✅ assign to KVO-compliant property
publisher
    .map(\.text)
    .assign(to: \.text, on: label)

Subject Patterns

Behavior Subject Pattern

class SearchViewModel: ObservableObject {
    @Published var searchText = ""
    @Published var results: [Result] = []

    private let searchSubject = PassthroughSubject<String, Never>()
    private var cancellables = Set<AnyCancellable>()

    init() {
        $searchText
            .debounce(for: .milliseconds(300), scheduler: RunLoop.main)
            .removeDuplicates()
            .flatMap { query in
                self.search(query)
                    .catch { _ in Just([]) }
            }
            .assign(to: &$results)
    }

    private func search(_ query: String) -> AnyPublisher<[Result], Never> {
        // Perform search
    }
}

Custom Publishers

// ✅ Publisher for notifications
extension NotificationCenter {
    func publisher(for name: Notification.Name, object: AnyObject? = nil) -> NotificationCenter.Publisher {
        Publisher(center: self, name: name, object: object)
    }

    struct Publisher: Combine.Publisher {
        typealias Output = Notification
        typealias Failure = Never

        let center: NotificationCenter
        let name: Notification.Name
        let object: AnyObject?

        func receive<S>(subscriber: S) where S: Subscriber, Notification == S.Input, Never == S.Failure {
            let subscription = Subscription(
                subscriber: subscriber,
                center: center,
                name: name,
                object: object
            )
            subscriber.receive(subscription: subscription)
        }
    }
}

// Usage
NotificationCenter.default
    .publisher(for: UIApplication.didBecomeActiveNotification)
    .sink { notification in
        print("App became active")
    }
    .store(in: &cancellables)

Memory Management

class ViewModel {
    private var cancellables = Set<AnyCancellable>()

    func setup() {
        // ✅ Store subscription
        publisher
            .sink { value in
                print(value)
            }
            .store(in: &cancellables)

        // ✅ Or use retain cycle
        var cancellable: AnyCancellable? = publisher
            .sink { value in
                print(value)
            }
        // cancellable = nil when done
    }
}

Testing

func testPublisher_transformsValues() {
    let publisher = [1, 2, 3].publisher
    var results: [Int] = []

    publisher
        .map { $0 * 2 }
        .sink { results.append($0) }

    XCTAssertEqual(results, [2, 4, 6])
}

---

Remember: Combine is declarative. Describe your data flow chain, and let the framework handle execution.

Related skills

FAQ

What does combine-framework cover?

Publishers and subscribers, transform/filter/combine operators, error handling, and SwiftUI integration with @Published and assign.

Is it iOS-specific?

Yes, Combine is Apple's reactive framework, used here with SwiftUI on iOS.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.