orange-opensource/ouds-ios/ouds-ios-framework-usage

Claude Code and agent skill by orange-opensource/ouds-ios

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Setup and general usage of the OUDS iOS framework — imports, themes, token namespaces, view modifiers, image rules, shared control patterns and custom font registration. Load this first; then load the matching `ouds-ios-components-*` skill for a specific component family (actions, content-display, controls, dialogs, foundations, indicators, layouts, navigations).

Install

npx vskill@latest install orange-opensource/ouds-ios/ouds-ios-framework-usage

SKILL.md

OUDS Framework Usage

1. Basic setup

swift
import OUDSSwiftUI // Always use the umbrella import
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
OUDSThemeableView(theme: OrangeTheme()) {
ContentView()
}
}
}
}
struct ContentView: View {
@Environment(\.theme) private var theme
var body: some View {
VStack(spacing: theme.spaces.fixedMedium) {
OUDSButton(text: "Action", appearance: .default) {}
}
.padding(theme.spaces.fixedLarge)
}
}

2. Imports

Can import internal modules, but for developer experience there are umbrella products:

ProductThemesWhen
OUDSSwiftUIAllDefault
OUDSSwiftUIOrangeOrange + OrangeCompactOrange apps only
OUDSSwiftUIOrangeSoshOrange + SoshMulti-brand
OUDSSwiftUIWireframeWireframePrototyping
OUDSSwiftUIWhiteLabelWhiteLabelWhite label or gray label branded apps

Internal modules: OUDSComponents, OUDSTokensRaw, OUDSTokensSemantic, OUDSTokensComponent, OUDSThemesOrange, OUDSThemesSosh, OUDSFoundations, etc.


3. Themes

swift
OUDSThemeableView(theme: OrangeTheme()) { … } // inject at root
@Environment(\.theme) private var theme // consume anywhere

Available: OrangeTheme, OrangeCompact, SoshTheme, WireframeTheme, WhiteLabel.


4. Token namespaces

NamespaceContent
theme.colorsColor semantic tokens
theme.colorModesColor-mode tokens (for OUDSColoredSurface)
theme.bordersBorder style / width / radius
theme.fontsTypography
theme.sizesSizes
theme.spacesSpacing
theme.dimensionsDimensions
theme.elevationsShadows / elevation
theme.gridsGrid
theme.opacitiesOpacity
theme.effectsVisual effects

5. View modifiers

swift
Text("Hello")
.font(theme.fonts.bodyDefaultMedium) // typography — use view modifier with token
.foregroundColor(theme.colors.contentDefault)
.background(theme.colors.bgPrimary)
.border(style: theme.borders.styleDefault,
width: theme.borders.widthThin,
radius: theme.borders.radiusMedium,
color: theme.colors.actionEnabled)
.shadow(theme.elevations.emphasized)

For Shape types, use fill(_:style:) with a color token — the light/dark variant is resolved automatically:

swift
Circle()
.fill(theme.colors.actionEnabled) // shape fill with token
RoundedRectangle(cornerRadius: 8)
.fill(theme.colors.bgPrimary, style: FillStyle(eoFill: true)) // with custom fill style

6. Images in OUDS components

Never call SwiftUI modifiers on an `Image` that is wrapped in an `OUDSImage` and passed to an OUDS component.

OUDS components accept an OUDSImage (which wraps the bare SwiftUI Image with its flip flag, accessibility label and rendering mode), through parameters named image:. Calling any modifier on the Image (including .accessibilityHidden(true)) changes its type to some View and produces a compile error.

The component handles the accessibility of its own images internally. You must not alter them from the call site.

Never do this:

swift
OUDSButton(
text: "Add",
image: OUDSImage(asset: Image(systemName: "plus").accessibilityHidden(true)), // ❌ compile error: Image modifier → some View
appearance: .default) {}
OUDSLink(
text: "Back",
image: OUDSImage(asset: Image(systemName: "chevron.left").accessibilityHidden(true)), // ❌ compile error: Image modifier → some View
size: .default) {}

Always do this — pass a bare `Image` inside `OUDSImage`, swiftlint comment on the line before:

swift
// swiftlint:disable:next accessibility_label_for_image
OUDSButton(text: "Add", image: OUDSImage(asset: Image(systemName: "plus")), appearance: .default) {}
// swiftlint:disable:next accessibility_label_for_image
OUDSLink(text: "Back", image: OUDSImage(asset: Image(systemName: "chevron.left")), size: .default) {}
// Exception: OUDSToolBarItem still takes a bare `Image`
// swiftlint:disable:next accessibility_label_for_image
OUDSToolBarItem(icon: Image("ic_share"), accessibilityLabel: "Share") {}

The // swiftlint:disable:next accessibility_label_for_image comment must appear on the line immediately before the component call, never on the line of the Image(...) itself.

Exception: Image(decorative: "name") suppresses the linter rule automatically and needs no comment.


7. Registering custom fonts

To use a custom font family with OUDS, two steps are required after adding the TTF files to your project:

Step 1 — Register the font files (Core Text, call once at app startup):

swift
private static var fontsAlreadyRegistered = false
private func registerFonts() {
guard !Self.fontsAlreadyRegistered else { return }
Bundle.main.urls(forResourcesWithExtension: "ttf", subdirectory: nil)?
.forEach { CTFontManagerRegisterFontsForURL($0 as CFURL, .process, nil) }
Self.fontsAlreadyRegistered = true
}

Step 2 — Register PostScript names for each family + weight combination you use:

swift
registerFont(postScript: "WinkyRough-Regular_Light", forCombination: PSFNMK("Winky Rough", Font.Weight.light))
registerFont(postScript: "WinkyRough-Regular", forCombination: PSFNMK("Winky Rough", Font.Weight.regular))
registerFont(postScript: "WinkyRough-Regular_Medium", forCombination: PSFNMK("Winky Rough", Font.Weight.medium))
registerFont(postScript: "WinkyRough-Regular_SemiBold",forCombination: PSFNMK("Winky Rough", Font.Weight.semibold))
registerFont(postScript: "WinkyRough-Regular_Bold", forCombination: PSFNMK("Winky Rough", Font.Weight.bold))
registerFont(postScript: "WinkyRough-Regular_Black", forCombination: PSFNMK("Winky Rough", Font.Weight.black))

kApplePostScriptFontNames exposes the full map (read-only). OUDS uses it internally to resolve Font objects from theme font tokens. Unregistered combinations fall back to the family name without spaces.


8. Styled AttributedString with hyperlinks

OUDS provides utilities to create styled AttributedString from plain text or Markdown, with custom styling for links based on their text or URL.

Font tokens (e.g. theme.fonts.bodyDefaultMedium) are MultipleFontCompositeSemanticToken values, not SwiftUI Font. Convert them with Font.makeFont(family:from:isCompact:) before using them in AttributedStringUrlConfiguration or AttributedString.from(...).

Basic usage — Markdown
swift
import OUDSComponents
import SwiftUI
let markdown = "Read our [terms of service](https://example.com/terms) and [privacy policy](https://example.com/privacy)"
let textColor = theme.colors.contentDefault.color(for: colorScheme)
let textFont = Font(Font.makeFont(family: theme.fontFamily,
from: theme.fonts.bodyDefaultMedium,
isCompact: horizontalSizeClass == .compact || verticalSizeClass == .compact))
let urlColor = theme.colors.contentBrandPrimary.color(for: colorScheme)
let urlFont = Font(Font.makeFont(family: theme.fontFamily,
from: theme.fonts.bodyStrongMedium,
isCompact: horizontalSizeClass == .compact || verticalSizeClass == .compact))
let configurations: [AttributedStringUrlConfiguration] = [
AttributedStringUrlConfiguration(
text: "terms of service",
color: urlColor,
font: urlFont
),
AttributedStringUrlConfiguration(
text: "privacy policy",
urlToOpen: URL(string: "https://example.com/privacy")!,
color: urlColor,
font: urlFont
),
AttributedStringUrlConfiguration(
color: urlColor,
font: urlFont
)
]
let attributedString = AttributedString.from(
markdown: markdown,
foregroundColor: textColor,
font: textFont,
urlConfigurations: configurations
)
Basic usage — plain text

Use AttributedString.from(text:foregroundColor:font:urlConfigurations:) when the text and the words to turn into hyperlinks are known upfront (no Markdown syntax). Each configuration must provide both text and urlToOpen, otherwise it is ignored:

swift
let attributedString = AttributedString.from(
text: "You must read the terms of service before continuing",
foregroundColor: textColor,
font: textFont,
urlConfigurations: [
AttributedStringUrlConfiguration(
text: "terms of service",
urlToOpen: URL(string: "https://example.com/terms")!,
color: urlColor,
font: urlFont
)
]
)

A LocalizedStringKey-based overload is also available: AttributedString.from(_:tableName:bundle:foregroundColor:font:urlConfigurations:). AttributedStringUrlConfiguration also has a LocalizedStringKey-based initializer: AttributedStringUrlConfiguration(_:tableName:bundle:urlToOpen:color:font:).

Foreground color only (no hyperlinks)

If you only need to apply a color to a whole text or Markdown source (no custom font, no hyperlink styling), use the simpler overloads:

swift
let coloredText = AttributedString.from(text: "Some plain text", foregroundColor: textColor)
let coloredKey = AttributedString.from("some.localized.key", foregroundColor: textColor)
let coloredMarkdown = AttributedString.from(markdown: someMarkdown, foregroundColor: textColor)

Each of these also has a ColorSemanticToken-based overload, e.g. AttributedString.from(text:foregroundColor: ColorSemanticToken).

Configuration options
InitializerUse case
AttributedStringUrlConfiguration(text:urlToOpen:color:font:)Match by text and URL, set custom URL. Required form for AttributedString.from(text:...)
AttributedStringUrlConfiguration(text:color:font:)Match by text only (URL taken from Markdown). Only usable with AttributedString.from(markdown:...)
AttributedStringUrlConfiguration(urlToOpen:color:font:)Match by URL only. Only usable with AttributedString.from(markdown:...)
AttributedStringUrlConfiguration(color:font:)Default fallback for any unmatched link. Only usable with AttributedString.from(markdown:...)
Matching priority (Markdown only)

For each hyperlink found in the Markdown source, the first configuration in the urlConfigurations array that matches (by URL or by text) is applied:

  1. Configurations are scanned in array order; the first one whose urlToOpen matches the link's URL, or whose text matches the link's text, wins.
  2. If no configuration matches, the default configuration (the one with no text and no urlToOpen) is applied, if any.
  3. If neither matches, a warning is logged and the base foregroundColor / font style is kept.

AttributedString.from(text:...) does not use this fallback logic: only configurations with both text and urlToOpen set are applied, matched by exact text.


10. AsyncImage — cached image loading

`OUDSAsyncImage is a cached version of SwiftUI/AsyncImage`. It loads images from URLs and caches them in memory (100MB) and on disk (500MB).

swift
import OUDSSwiftUI
// Basic usage
OUDSAsyncImage(url: URL(string: "https://example.com/photo.png"))
// With content transformation and placeholder
OUDSAsyncImage(url: url) { image in
image.resizable()
} placeholder: {
ProgressView()
}
// With phases for full control
OUDSAsyncImage(url: url) { phase in
switch phase {
case .empty: ProgressView()
case .success(let image): image.resizable()
case .failure: Image(systemName: "photo")
}
}
// Cache management
OUDSAsyncImageCache.shared.clearCache() // memory + disk
OUDSAsyncImageCache.shared.clearMemoryCache()
OUDSAsyncImageCache.shared.clearDiskCache()

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
34
Repository forks
9
7-day trend score
18

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/orange-opensource/ouds-ios/ouds-ios-framework-usage/badge)](https://verified-skill.com/skills/orange-opensource/ouds-ios/ouds-ios-framework-usage)

Something wrong with this skill or its page? Tell us.