Skip to content

Commit 2644c57

Browse files
docs: Update README to latest template
Signed-off-by: Fabrizio Demaria <[email protected]> Signed-off-by: Fabrizio Demaria <[email protected]>
1 parent 5ddf45d commit 2644c57

File tree

1 file changed

+160
-66
lines changed

1 file changed

+160
-66
lines changed

README.md

+160-66
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,56 @@
1+
<!-- TODO: This is a template SDK README.md.
2+
It's structured to fit nicely into openfeature.dev, which is configured to include SDK READMEs.
3+
Complete all the TODOs applicable for your implementation and then create an issue in https://github.com/open-feature/openfeature.dev
4+
-->
5+
16
<!-- markdownlint-disable MD033 -->
7+
<!-- x-hide-in-docs-start -->
28
<p align="center">
39
<picture>
4-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/white/openfeature-horizontal-white.svg">
5-
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/black/openfeature-horizontal-black.svg">
6-
<img align="center" alt="OpenFeature Logo">
10+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/white/openfeature-horizontal-white.svg" />
11+
<img align="center" alt="OpenFeature Logo" src="https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/black/openfeature-horizontal-black.svg" />
712
</picture>
813
</p>
914

10-
<h2 align="center">OpenFeature Swift SDK</h2>
15+
<h2 align="center">OpenFeature <!-- TODO: your language SDK --> SDK</h2>
1116

12-
![Status](https://img.shields.io/badge/lifecycle-alpha-a0c3d2.svg)
17+
<!-- x-hide-in-docs-end -->
18+
<!-- The 'github-badges' class is used in the docs -->
19+
<p align="center" class="github-badges">
20+
<!-- TODO: update this with the version of the SDK your implementation supports -->
1321

14-
## 👋 Hey there! Thanks for checking out the OpenFeature Swift SDK
22+
<a href="https://github.com/open-feature/spec/releases/tag/v0.7.0">
23+
<img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.7.0&color=yellow&style=for-the-badge" />
24+
</a>
25+
<!-- TODO: update the Release Please config to include the readme -->
26+
<!-- x-release-please-start-version -->
1527

16-
### What is OpenFeature?
28+
<!-- TODO: update with your SDK repo and the latest release version
29+
<a href="https://github.com/open-feature/my-sdk/releases/tag/v0.0.1">
30+
<img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.0.1&color=blue&style=for-the-badge" />
31+
</a>
32+
-->
1733

18-
[OpenFeature][openfeature-website] is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool.
34+
<!-- x-release-please-end -->
35+
<br/>
36+
<img alt="Status" src="https://img.shields.io/badge/lifecycle-alpha-a0c3d2.svg" />
37+
</p>
38+
<!-- x-hide-in-docs-start -->
1939

20-
### Why standardize feature flags?
40+
[OpenFeature](https://openfeature.dev) is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool or in-house solution.
2141

22-
Standardizing feature flags unifies tools and vendors behind a common interface which avoids vendor lock-in at the code level. Additionally, it offers a framework for building extensions and integrations and allows providers to focus on their unique value proposition.
42+
<!-- x-hide-in-docs-end -->
43+
## 🚀 Quick start
2344

24-
## 🔍 Requirements
45+
### Requirements
2546

2647
- The minimum iOS version supported is: `iOS 14`.
2748

2849
Note that this library is intended to be used in a mobile context, and has not been evaluated for use in other type of applications (e.g. server applications, macOS, tvOS, watchOS, etc.).
2950

30-
## 📦 Installation
51+
### Install
3152

32-
### Xcode Dependencies
53+
#### Xcode Dependencies
3354

3455
You have two options, both start from File > Add Packages... in the code menu.
3556

@@ -43,7 +64,7 @@ First, ensure you have your GitHub account added as an option (+ > Add Source Co
4364

4465
**Note:** Option 2 is only recommended if you are making changes to the client SDK.
4566

46-
### Swift Package Manager
67+
#### Swift Package Manager
4768

4869
If you manage dependencies through SPM, in the dependencies section of Package.swift add:
4970

@@ -58,14 +79,7 @@ and in the target dependencies section add:
5879
.product(name: "OpenFeature", package: "swift-sdk"),
5980
```
6081

61-
## 🌟 Features
62-
63-
- Support for various backend [providers](https://openfeature.dev/docs/reference/concepts/provider)
64-
- Easy integration and extension via [hooks](https://openfeature.dev/docs/reference/concepts/hooks)
65-
- Bool, string, numeric, and object flag types
66-
- [Context-aware](https://openfeature.dev/docs/reference/concepts/evaluation-context) evaluation
67-
68-
## 🚀 Usage
82+
### Usage
6983

7084
```swift
7185
import OpenFeature
@@ -85,24 +99,105 @@ let client = OpenFeatureAPI.shared.getClient()
8599
let flagValue = client.getBooleanValue(key: "boolFlag", defaultValue: false)
86100
```
87101

88-
Setting a new provider or setting a new evaluation context are synchronous operations. The provider might execute I/O operations as part of these method calls (e.g. fetching flag evaluations from the backend and store them in a local cache). It's advised to not interact with the OpenFeature client until the relevant event has been emitted (see events below).
102+
Setting a new provider or setting a new evaluation context might trigger asynchronous operations (e.g. fetching flag evaluations from the backend and store them in a local cache). It's advised to not interact with the OpenFeature client until the `ProviderReady` event has been emitted (see [Eventing](#eventing) below).
103+
104+
## 🌟 Features
105+
106+
107+
| Status | Features | Description |
108+
| ------ | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
109+
|| [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. |
110+
|| [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). |
111+
|| [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. |
112+
|| [Logging](#logging) | Integrate with popular logging packages. |
113+
|| [Named clients](#named-clients) | Utilize multiple providers in a single application. |
114+
|| [Eventing](#eventing) | React to state changes in the provider or flag management system. |
115+
|| [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
116+
|| [Extending](#extending) | Extend OpenFeature with custom providers and hooks. |
117+
118+
<sub>Implemented: ✅ | In-progress: ⚠️ | Not implemented yet: ❌</sub>
119+
120+
### Providers
121+
122+
[Providers](https://openfeature.dev/docs/reference/concepts/provider) are an abstraction between a flag management system and the OpenFeature SDK.
123+
Look [here](https://openfeature.dev/ecosystem?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Provider&instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=Swift) for a complete list of available providers.
124+
If the provider you're looking for hasn't been created yet, see the [develop a provider](#develop-a-provider) section to learn how to build it yourself.
125+
126+
Once you've added a provider as a dependency, it can be registered with OpenFeature like this:
127+
128+
```swift
129+
OpenFeatureAPI.shared.setEvaluationContext(evaluationContext: ctx)
130+
```
131+
132+
### Targeting
133+
134+
Sometimes, the value of a flag must consider some dynamic criteria about the application or user, such as the user's location, IP, email address, or the server's location.
135+
In OpenFeature, we refer to this as [targeting](https://openfeature.dev/specification/glossary#targeting).
136+
If the flag management system you're using supports targeting, you can provide the input data using the [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context).
137+
138+
```swift
139+
// Configure your evaluation context and pass it to OpenFeatureAPI
140+
let ctx = MutableContext(
141+
targetingKey: userId,
142+
structure: MutableStructure(attributes: ["product": Value.string(productId)]))
143+
OpenFeatureAPI.shared.setEvaluationContext(evaluationContext: ctx)
144+
```
145+
146+
### Hooks
147+
148+
[Hooks](https://openfeature.dev/docs/reference/concepts/hooks) allow for custom logic to be added at well-defined points of the flag evaluation life-cycle.
149+
Look [here](https://openfeature.dev/ecosystem/?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Hook&instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=Swift) for a complete list of available hooks.
150+
If the hook you're looking for hasn't been created yet, see the [develop a hook](#develop-a-hook) section to learn how to build it yourself.
89151

90-
Please refer to our [documentation on static-context APIs](https://github.com/open-feature/spec/pull/171) for further information on how these APIs are structured for the use-case of mobile clients.
152+
Once you've added a hook as a dependency, it can be registered at the global, client, or flag invocation level.
91153

92-
### Events
154+
```swift
155+
// add a hook globally, to run on all evaluations
156+
OpenFeatureAPI.shared.addHooks(hooks: ExampleHook())
157+
158+
// add a hook on this client, to run on all evaluations made by this client
159+
val client = OpenFeatureAPI.shared.getClient()
160+
client.addHooks(ExampleHook())
161+
162+
// add a hook for this evaluation only
163+
_ = client.getValue(
164+
key: "key",
165+
defaultValue: false,
166+
options: FlagEvaluationOptions(hooks: [ExampleHook()]))
167+
```
168+
169+
### Eventing
93170

94171
Events allow you to react to state changes in the provider or underlying flag management system, such as flag definition changes, provider readiness, or error conditions.
95-
Initialization events (`PROVIDER_READY` on success, `PROVIDER_ERROR` on failure) are emitted for every provider.
172+
Initialization events (`PROVIDER_READY` on success, `PROVIDER_ERROR` on failure) are dispatched for every provider.
96173
Some providers support additional events, such as `PROVIDER_CONFIGURATION_CHANGED`.
97-
Please refer to the documentation of the provider you're using to see what events are supported and when they are emitted.
98174

99-
To register a handler for API level provider events, use the `OpenFeatureAPI` `addHandler(observer:selector:event:)` function. Event handlers can also be removed using the equivalent `removeHandler` function. `Client`s also provide add and remove functions for listening to that specific client. A `ProviderEvent` enum is defined to ease subscription.
175+
Please refer to the documentation of the provider you're using to see what events are supported.
100176

101-
Events can contain extra information in the `userInfo` dictionary of the notification. All events will contain a reference to the provider that emitted the event (under the `providerEventDetailsKeyProvider` key). Error events will also provide a reference to the underlying error (under the `providerEventDetailsKeyError` key). Finally, client specific events will contain a reference to the client (under the `providerEventDetailsKeyClient` key)
177+
```swift
178+
OpenFeatureAPI.shared.addHandler(
179+
observer: self, selector: #selector(readyEventEmitted(notification:)), event: .ready
180+
)
102181

103-
### Providers
182+
func readyEventEmitted(notification: NSNotification) {
183+
// to something now that the provider is ready
184+
}
185+
```
186+
187+
### Shutdown
188+
189+
The OpenFeature API provides a close function to perform a cleanup of all registered providers.
190+
This should only be called when your application is in the process of shutting down.
191+
192+
<!-- TODO: code example for global shutdown -->
104193

105-
To develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency. This can be a new repository or included in the existing contrib repository available under the OpenFeature organization. Finally, you’ll then need to write the provider itself. This can be accomplished by implementing the `FeatureProvider` protocol exported by the OpenFeature SDK.
194+
## Extending
195+
196+
### Develop a provider
197+
198+
To develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency.
199+
This can be a new repository or included in [the existing contrib repository](https://github.com/open-feature/swift-sdk-contrib) available under the OpenFeature organization.
200+
You’ll then need to write the provider by implementing the `FeatureProvider` interface exported by the OpenFeature SDK.
106201

107202
```swift
108203
import OpenFeature
@@ -127,64 +222,63 @@ final class CustomProvider: FeatureProvider {
127222
// resolve a boolean flag value
128223
}
129224

130-
func getStringEvaluation(
131-
key: String,
132-
defaultValue: String,
133-
context: EvaluationContext?
134-
) throws -> ProviderEvaluation<String> {
135-
// resolve a string flag value
225+
...
226+
}
227+
228+
```
229+
> Built a new provider? [Let us know](https://github.com/open-feature/openfeature.dev/issues/new?assignees=&labels=provider&projects=&template=document-provider.yaml&title=%5BProvider%5D%3A+) so we can add it to the docs!
230+
231+
### Develop a hook
232+
233+
To develop a hook, you need to create a new project and include the OpenFeature SDK as a dependency.
234+
This can be a new repository or included in [the existing contrib repository](https://github.com/open-feature/swift-sdk-contrib) available under the OpenFeature organization.
235+
Implement your own hook by conforming to the `Hook interface`.
236+
To satisfy the interface, all methods (`Before`/`After`/`Finally`/`Error`) need to be defined.
237+
To avoid defining empty functions, make use of the `UnimplementedHook` struct (which already implements all the empty functions).
238+
239+
```swift
240+
class BooleanHook: Hook {
241+
typealias HookValue = Bool
242+
243+
func before<HookValue>(ctx: HookContext<HookValue>, hints: [String: Any]) {
244+
// do something
136245
}
137246

138-
func getIntegerEvaluation(
139-
key: String,
140-
defaultValue: Int64,
141-
context: EvaluationContext?
142-
) throws -> ProviderEvaluation<Int64> {
143-
// resolve an integer flag value
247+
func after<HookValue>(ctx: HookContext<HookValue>, details: FlagEvaluationDetails<HookValue>, hints: [String: Any]) {
248+
// do something
144249
}
145250

146-
func getDoubleEvaluation(
147-
key: String,
148-
defaultValue: Double,
149-
context: EvaluationContext?
150-
) throws -> ProviderEvaluation<Double> {
151-
// resolve a double flag value
251+
func error<HookValue>(ctx: HookContext<HookValue>, error: Error, hints: [String: Any]) {
252+
// do something
152253
}
153254

154-
func getObjectEvaluation(
155-
key: String,
156-
defaultValue: Value,
157-
context: EvaluationContext?
158-
) throws -> ProviderEvaluation<Value> {
159-
// resolve an object flag value
255+
func finallyAfter<HookValue>(ctx: HookContext<HookValue>, hints: [String: Any]) {
256+
// do something
160257
}
161258
}
162-
163259
```
164260

261+
> Built a new hook? [Let us know](https://github.com/open-feature/openfeature.dev/issues/new?assignees=&labels=hook&projects=&template=document-hook.yaml&title=%5BHook%5D%3A+) so we can add it to the docs!
262+
263+
<!-- x-hide-in-docs-start -->
165264
## ⭐️ Support the project
166265

167266
- Give this repo a ⭐️!
168267
- Follow us on social media:
169-
- Twitter: [@openfeature](https://twitter.com/openfeature)
170-
- LinkedIn: [OpenFeature](https://www.linkedin.com/company/openfeature/)
268+
- Twitter: [@openfeature](https://twitter.com/openfeature)
269+
- LinkedIn: [OpenFeature](https://www.linkedin.com/company/openfeature/)
171270
- Join us on [Slack](https://cloud-native.slack.com/archives/C0344AANLA1)
172-
- For more check out our [community page](https://openfeature.dev/community/)
271+
- For more, check out our [community page](https://openfeature.dev/community/)
173272

174273
## 🤝 Contributing
175274

176275
Interested in contributing? Great, we'd love your help! To get started, take a look at the [CONTRIBUTING](CONTRIBUTING.md) guide.
177276

178-
### Thanks to everyone that has already contributed
277+
### Thanks to everyone who has already contributed
179278

180279
<a href="https://github.com/open-feature/swift-sdk/graphs/contributors">
181280
<img src="https://contrib.rocks/image?repo=open-feature/swift-sdk" alt="Pictures of the folks who have contributed to the project" />
182281
</a>
183282

184283
Made with [contrib.rocks](https://contrib.rocks).
185-
186-
## 📜 License
187-
188-
[Apache License 2.0](LICENSE)
189-
190-
[openfeature-website]: https://openfeature.dev
284+
<!-- x-hide-in-docs-end -->

0 commit comments

Comments
 (0)