OpenFeature Logo

OpenFeature iOS SDK

Specification Release
Status

OpenFeature 是一个开放规范,它为功能标志提供了一个与供应商无关、社区驱动的 API,可以与您最喜欢的功能标志管理工具或内部解决方案一起使用。

🚀 快速开始

要求

请注意,此库旨在用于移动环境,尚未评估在其他类型的应用程序(例如,服务器应用程序、macOS、tvOS、watchOS 等)中的使用。

安装

Xcode 依赖项

您有两个选项,都从代码菜单中的 File > Add Packages... 开始。

首先,确保您已添加 GitHub 帐户作为选项(+ > Add Source Control Account...)。您将需要创建一个 个人访问令牌,其权限在 Xcode 界面中定义。

  1. 添加为远程仓库
    • 搜索 git@github.com:open-feature/swift-sdk.git 并点击 “Add Package”
  2. 本地克隆仓库
    • 使用您偏好的方法本地克隆
    • 使用 “Add Local...” 按钮选择本地文件夹

注意: 仅当您要更改客户端 SDK 时,才建议使用选项 2。

Swift Package Manager

如果您通过 SPM 管理依赖项,请在 Package.swift 的 dependencies 部分添加

.package(url: "git@github.com:open-feature/swift-sdk.git", from: "0.3.0")

并在 target dependencies 部分添加

.product(name: "OpenFeature", package: "swift-sdk"),

用法

import OpenFeature

Task {
    let provider = CustomProvider()
    // configure a provider, wait for it to complete its initialization tasks
    await OpenFeatureAPI.shared.setProviderAndWait(provider: provider)

    // get a bool flag value
    let client = OpenFeatureAPI.shared.getClient()
    let flagValue = client.getBooleanValue(key: "boolFlag", defaultValue: false)
}

🌟 功能特性

状态 功能 描述
提供程序 与商业、开源或内部功能管理工具集成。
目标定位 使用 评估上下文 进行上下文感知的功能标志评估。
钩子 在功能标志评估生命周期的各个阶段添加功能。
追踪 将用户操作与功能标志评估关联起来。
日志记录 与流行的日志记录包集成。
命名客户端 在单个应用程序中利用多个提供程序。
事件 对提供程序或功能标志管理系统中的状态更改做出反应。
关闭 在应用程序关闭期间优雅地清理提供程序。
扩展 使用自定义提供程序和钩子扩展 OpenFeature。

已实现:✅ | 进行中⚠️| 尚未实现:❌

提供程序

提供程序 是功能标志管理系统和 OpenFeature SDK 之间的抽象层。 点击此处 查看可用提供程序的完整列表。 如果您要查找的提供程序尚未创建,请参阅 开发提供程序 部分,了解如何自行构建。

一旦您将提供程序添加为依赖项,就可以像这样在 OpenFeature 中注册它

await OpenFeatureAPI.shared.setProviderAndWait(provider: MyProvider())

也提供无需等待的异步 API

目标定位

有时,功能标志的值必须考虑关于应用程序或用户的某些动态标准,例如用户的位置、IP、电子邮件地址或服务器的位置。 在 OpenFeature 中,我们将其称为 目标定位。 如果您使用的功能标志管理系统支持目标定位,您可以使用 评估上下文 提供输入数据。

// Configure your evaluation context and pass it to OpenFeatureAPI
let ctx = MutableContext(
    targetingKey: userId,
    structure: MutableStructure(attributes: ["product": Value.string(productId)]))
OpenFeatureAPI.shared.setEvaluationContext(evaluationContext: ctx)

钩子

钩子 允许在功能标志评估生命周期的明确定义的点添加自定义逻辑。 点击此处 查看可用钩子的完整列表。 如果您要查找的钩子尚未创建,请参阅 开发钩子 部分,了解如何自行构建。

一旦您将钩子添加为依赖项,就可以在全球、客户端或功能标志调用级别注册它。

// add a hook globally, to run on all evaluations
OpenFeatureAPI.shared.addHooks(hooks: ExampleHook())

// add a hook on this client, to run on all evaluations made by this client
val client = OpenFeatureAPI.shared.getClient()
client.addHooks(ExampleHook())

// add a hook for this evaluation only
_ = client.getValue(
    key: "key",
    defaultValue: false,
    options: FlagEvaluationOptions(hooks: [ExampleHook()]))

追踪

追踪在 iOS SDK 中尚不可用。

日志记录

日志记录自定义在 iOS SDK 中尚不可用。

命名客户端

对命名客户端的支持在 iOS SDK 中尚不可用。

事件

事件允许您对提供程序或底层功能标志管理系统中的状态更改做出反应,例如功能标志定义更改、提供程序就绪状态或错误情况。 初始化事件(成功时为 PROVIDER_READY,失败时为 PROVIDER_ERROR)会为每个提供程序分派。 一些提供程序支持其他事件,例如 PROVIDER_CONFIGURATION_CHANGED

请参阅您正在使用的提供程序的文档,以查看支持哪些事件。

let cancellable = OpenFeatureAPI.shared.observe().sink { event in
    switch event {
    case ProviderEvent.ready:
        // ...
    default:
        // ...
    }
}

关闭

关闭功能在 iOS SDK 中尚不可用。

扩展

开发提供程序

要开发提供程序,您需要创建一个新项目并将 OpenFeature SDK 作为依赖项包含在内。 然后,您需要通过实现 OpenFeature SDK 导出的 FeatureProvider 接口来编写提供程序。

import OpenFeature

final class CustomProvider: FeatureProvider {
    var hooks: [any Hook] = []
    var metadata: ProviderMetadata = CustomMetadata()

    func initialize(initialContext: EvaluationContext?) async {
        // add context-aware provider initialisation
    }

    func onContextSet(oldContext: EvaluationContext?, newContext: EvaluationContext) async {
        // add necessary changes on context change
    }

    func getBooleanEvaluation(
        key: String,
        defaultValue: Bool,
        context: EvaluationContext?
    ) throws -> ProviderEvaluation<Bool> {
        // resolve a boolean flag value
    }

    ...
}

构建了一个新的提供程序? 请告知我们,以便我们可以将其添加到文档中!

开发钩子

要开发钩子,您需要创建一个新项目并将 OpenFeature SDK 作为依赖项包含在内。 通过符合 Hook interface 来实现您自己的钩子。 为了满足接口要求,需要定义所有方法 (Before/After/Finally/Error)。

class BooleanHook: Hook {
    typealias HookValue = Bool

    func before<HookValue>(ctx: HookContext<HookValue>, hints: [String: Any]) {
        // do something
    }

    func after<HookValue>(ctx: HookContext<HookValue>, details: FlagEvaluationDetails<HookValue>, hints: [String: Any]) {
        // do something
    }

    func error<HookValue>(ctx: HookContext<HookValue>, error: Error, hints: [String: Any]) {
        // do something
    }

    func finally<HookValue>(ctx: HookContext<HookValue>, hints: [String: Any]) {
        // do something
    }
}

构建了一个新的钩子? 请告知我们,以便我们可以将其添加到文档中!

⭐️ 支持本项目

🤝 贡献

有兴趣贡献吗? 太好了,我们很乐意得到您的帮助! 要开始,请查看 CONTRIBUTING 指南。

感谢所有已经做出贡献的人

Pictures of the folks who have contributed to the project

使用 contrib.rocks 制作。