Skip to content

Instantly share code, notes, and snippets.

/*
Usage:
Store(
initialState: .init(),
reducer: UserRecipesListReducer().relay { [unowned self] featureAction in
// Handle action here
}
)
*/
@simme
simme / StoreControllerDialogs.swift
Created April 4, 2023 08:44
UIKit helpers for presenting alerts and confirmation dialogs
/*
Example usage:
confirmationDialog(
store: store.scope(state: \.destination, action: UserRecipesListReducer.Action.destination),
state: /UserRecipesListReducer.Destination.State.confirmation,
action: UserRecipesListReducer.Destination.Action.confirmation
).store(in: &subscriptions)
alert(
import CloudKit
import Combine
/// A publisher that wraps a `CKFetchRecordZoneChangesOperation` and emits events as the operation completes.
///
/// The `FetchRecordZoneChangesPublisher` fetches changes from the given record zones. New and deleted records are
/// posted individually via the `.recordChanged` and `.recordDeleted` actions.
///
/// Errors are automatically retried if possible. Resetting the change token in case it expired is also automatically
/// handled. Because emitting errors fails a publisher all errors are posted as actions. There may still be running

Given these two tables

lists

id name weight
1 Groceries 0
2 Pharmacy 1
3 Misc 2
extension Reducer {
/// Wraps a reducer to inject a debounced action back into the reducer.
///
/// Use this higher order reducer when you want to schedule some work to happen after any other action is recieved by
/// the reducer.
///
/// **Usage:**
/// ```
/// otherReducer.debounceReactiveAction(
/// id: DebounceID(),
@simme
simme / CKError.swift
Created June 9, 2021 14:05
CloudKit publishers
import CloudKit
extension Error {
/// `true` if the error represents a CloudKit conflict.
var isCloudKitConflictError: Bool {
(self as? CKError).map { $0.code == CKError.Code.serverRecordChanged } ?? false
}
/// `true` if the error represents a CloudKit zone deleted error.
@simme
simme / StateStoreCell.swift
Created December 10, 2020 14:40
Composable Architecutre helpers
import Combine
import ComposableArchitecture
import UIKit
/// The state store cell is a cell superclass designed to work with Composable Architecture state stores. It removes
/// much of the boiler plate involved with creating a custom cell subclass.
open class StateStoreCell<State: Equatable, Action>: UICollectionViewCell {
// MARK: Properties
import CloudKit
import Combine
/// Fetches the user's CloudKit Account status.
///
/// - Parameter container: The container to check the status in.
///
/// - Returns: A deferred future that resolves to the user's CloudKit Account status.
func getAccountStatus(for container: CKContainer) -> AnyPublisher<CKAccountStatus, Error> {
Deferred {
import UIKit
public protocol CellConfinable: UIView {
associatedtype Item
var isSelected: Bool { get set }
var isHighlighted: Bool { get set }
func prepareForReuse()
func configure(for item: Item)
}
private final class OfferingButton: UIViewController {
@Published private var frame: CGRect = .zero
private var subscriptions: [AnyCancellable] = []
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
$frame.removeDuplicates()