gokulnair2001/Pledge

main BranchesTags Go to file Code

Folders and files

Name| Name| Last commit message| Last commit date
---|---|---|---

Latest commit

History

30 Commits
.swiftpm/xcode/xcshareddata/xcschemes| .swiftpm/xcode/xcshareddata/xcschemes
Sources| Sources
Tests/PledgeTests| Tests/PledgeTests
.gitignore| .gitignore
CODE_OF_CONDUCT.md| CODE_OF_CONDUCT.md
LICENSE| LICENSE
Package.swift| Package.swift
README.md| README.md
View all files

Repository files navigation

PledgeBanner

Pledge

一款经过深思熟虑设计的 Swift 响应式编程框架。

Pledge 是一款轻量级、线程安全的 Swift 响应式编程框架,旨在简化状态管理和事件传播,并在应用程序中平衡强大功能与简洁性。其他框架可能会迫使您学习复杂的概念和操作符,但 Pledge 专注于解决开发者日常面临的实际问题:

概述

Pledge 提供了一种简洁、灵活的方式,在 Swift 应用程序中实现观察者模式。它使您能够创建可观察的值,并在值发生更改时通知订阅者,并提供强大的功能,例如:

安装

Swift Package Manager

将以下内容添加到您的 Package.swift 文件中:

dependencies: [
  .package(url: "https://github.com/gokulnair2001/Pledge.git", from: "1.0.0")
]

核心组件

PLObservable

PLObservablePledge 的核心,它代表一个值的线程安全容器,该值可以被观察以获取更改。

// 创建一个可观察的字符串
let messageObservable = PLObservable("Hello")
// 订阅更改
let subscription = messageObservable.subscribe { newMessage in
  print("Message changed to: \(newMessage)")
}
// 更新值
messageObservable.setValue("Hello World")

PLGlobalStore

PLGlobalStore 为可观察对象提供了一个集中式存储库,充当轻量级的状态管理解决方案。

// 访问共享实例
let store = PLGlobalStore.shared
// 获取或创建一个可观察对象
let userNameObservable = store.string(for: "userName", defaultValue: "Guest")
// 订阅更改
userNameObservable.subscribe { name in
  print("User name is now: \(name)")
}
// 从应用程序中的任何位置更新
PLGlobalStore.shared.string(for: "userName").setValue("John")

可观察对象的工作原理

HOW

上图说明了 Pledge 中的数据流:

  1. 一个可观察对象持有一个值,并维护一个订阅者列表
  2. 当值发生更改时,所有订阅者会按优先级顺序收到通知
  3. 订阅者可以执行转换器,并指定传递队列以实现线程安全
  4. 可选的速率限制可以控制通知频率

API 参考

PLObservable

创建一个可观察对象

// 使用一个值初始化
let counter = PLObservable(0)
let isEnabled = PLObservable(true)
let userData = PLObservable(["name": "Guest", "role": "User"])

订阅更改

// 基本订阅
let subscription = observable.subscribe { newValue in
  print("Value changed to: \(newValue)")
}
// 不再需要时取消订阅
observable.unsubscribe(subscription)
// 移除所有订阅者
observable.removeAllSubscribers()

控制传递

// 在特定的队列中传递
observable.deliver(on: myCustomQueue).subscribe { value in
  // 这个闭包在 myCustomQueue 上运行
}
// 在主队列中传递
observable.deliverOnMain().subscribe { value in
  // 这个闭包在主队列中运行
}
// 设置订阅优先级
observable.withPriority(.high).subscribe { value in
  // 高优先级订阅者首先收到通知
}

修改值

// 设置一个新值并通知订阅者
observable.setValue(newValue)
// 设置一个值,但不通知
observable.setValue(newValue, notify: false)
// 使用当前值触发通知
observable.notifyObservers()

批量更新

// 开始批量更新
observable.beginUpdates()
// 进行多次更改
observable.setValue(1)
observable.setValue(2)
observable.setValue(3)
// 结束批量更新 - 仅发送一个通知
observable.endUpdates()

速率限制

// 节流:限制为每 0.5 秒一次通知
observable.throttle(for: 0.5).subscribe { value in
  // 最多每 0.5 秒调用一次
}
// 防抖:等待更新暂停 0.3 秒
observable.debounce(for: 0.3).subscribe { value in
  // 在 0.3 秒没有更新后调用
}

操作符

转换

// 将值映射到不同的类型
let stringCounter = counter.map { "Count: \($0)" }
// Flat-map 到另一个可观察对象
let userDetails = userIdObservable.flatMap { userId in
  return fetchUserDetails(userId)
}
// 解包可选值
let optionalValue = PLObservable<String?>("test")
let unwrapped = optionalValue.compactMap()

过滤

// 仅发出通过谓词的值
let evenNumbers = counter.filter { $0 % 2 == 0 }
// 跳过前 N 次发射
let skipFirst = counter.skip(2)
// 仅在值更改时发出
let distinct = values.distinctUntilChanged()

组合

// 合并两个相同类型的可观察对象
let allEvents = userEvents.merge(systemEvents)
// 组合两个可观察对象的最新值
let credentials = username.zip(password)

PLGlobalStore

// 获取/创建类型化的可观察对象
let counter = PLGlobalStore.shared.integer(for: "counter")
let userName = PLGlobalStore.shared.string(for: "userName")
let settings = PLGlobalStore.shared.dictionary(for: "settings")
let items = PLGlobalStore.shared.array(for: "items")
let isEnabled = PLGlobalStore.shared.boolean(for: "isEnabled")
// 移除特定的可观察对象
PLGlobalStore.shared.removeObservable(for: "counter")
// 清除所有可观察对象
PLGlobalStore.shared.removeAllObservables()

使用示例

表单验证

let username = PLObservable("")
let password = PLObservable("")
let isFormValid = PLObservable(false)

// 创建派生状态
let isUsernameValid = username.map { $0.count >= 3 }
let isPasswordValid = password.map { $0.count >= 8 }

// 组合验证
isUsernameValid.subscribe { usernameValid in
  isPasswordValid.subscribe { passwordValid in
    isFormValid.setValue(usernameValid && passwordValid)
  }
}

// 对表单有效性做出反应
isFormValid.subscribe { valid in
  submitButton.isEnabled = valid
}

网络状态管理

enum NetworkState {
  case idle, loading, success(Data), error(Error)
}

let networkState = PLObservable<NetworkState>(.idle)

// 处理不同的状态
networkState.subscribe { state in
  switch state {
  case .idle:
    // 隐藏指示器
  case .loading:
    // 显示加载指示器
  case .success(let data):
    // 使用数据更新 UI
  case .error(let error):
    // 显示错误消息
  }
}

// 加载数据的函数
func fetchData() {
  networkState.setValue(.loading)
  
  apiClient.fetchData { result in
    switch result {
    case .success(let data):
      networkState.setValue(.success(data))
    case .failure(let error):
      networkState.setValue(.error(error))
    }
  }
}

节流搜索

let searchQuery = PLObservable("")

// 节流以避免过多的 API 调用
searchQuery.throttle(for: 0.3).subscribe { query in
  if !query.isEmpty {
    performSearch(query)
  }
}

许可证

Pledge 在 MIT 许可证下可用。 有关更多信息,请参见 LICENSE 文件

关于

一款经过深思熟虑设计的 Swift 响应式编程框架。 pledge.framer.website

Topics

swift reactive reactiveswift reactive-programming

Resources

Readme

License

MIT license

Code of conduct

Code of conduct Activity

Stars

8 stars

Watchers

1 watching

Forks

0 forks Report repository

Releases 1

v1.0.0 Latest Mar 30, 2025

Packages 0

No packages published

Languages

Footer

© 2025 GitHub, Inc.

Footer navigation

You can’t perform that action at this time.