Skip to content

Commit bf58052

Browse files
authored
[skills] Add macios-binding-creator skill v1 (#24937)
1 parent aaba96a commit bf58052

3 files changed

Lines changed: 707 additions & 0 deletions

File tree

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
---
2+
name: macios-binding-creator
3+
description: >
4+
Create C# bindings for Apple frameworks in dotnet/macios. USE FOR: binding new
5+
APIs, implementing .todo file entries, creating Xcode SDK bindings, binding
6+
AVFoundation/UIKit/AppKit or any Apple framework, "bind this framework",
7+
"implement these APIs". DO NOT USE FOR: Xcode beta version bumps (use
8+
macios-xcode-beta-update skill), CI failure investigation (use
9+
macios-ci-failure-inspector skill).
10+
---
11+
12+
# macios Binding Creator
13+
14+
Create C# bindings for Apple platform APIs in the dotnet/macios repository. This skill encodes the end-to-end workflow: from reading `.todo` files through implementation, building, and validating with xtro, cecil, and introspection tests on all platforms.
15+
16+
## When to Use This Skill
17+
18+
Use this skill when:
19+
- Asked to bind a new Apple framework or add missing API bindings
20+
- Implementing entries from `.todo` files in `tests/xtro-sharpie/api-annotations-dotnet/`
21+
- Creating bindings for a new Xcode SDK release
22+
- Adding new types, properties, methods, or enum values to existing framework bindings
23+
- Asked to "bind", "implement", or "add bindings for" any Apple framework
24+
25+
## Prerequisites
26+
27+
- Repository checked out and configured (`./configure` already run)
28+
- Xcode installed at the expected `XCODE_DEVELOPER_ROOT` path
29+
- A successful `make world` or `make all && make install` already completed
30+
31+
## Process
32+
33+
### Step 1: Understand What to Bind
34+
35+
Check the `.todo` files to see what APIs are missing:
36+
37+
```bash
38+
ls tests/xtro-sharpie/api-annotations-dotnet/*-{FrameworkName}.todo
39+
cat tests/xtro-sharpie/api-annotations-dotnet/iOS-{FrameworkName}.todo
40+
```
41+
42+
Each `.todo` file lists missing APIs per platform (iOS, tvOS, macOS, MacCatalyst). The format is:
43+
```
44+
!missing-selector! ClassName::methodName: not bound
45+
!missing-type! ClassName not bound
46+
!missing-field! ClassName FieldName not bound
47+
!missing-enum-value! EnumName::ValueName not bound
48+
```
49+
50+
> **NEVER** bind APIs that aren't in the `.todo` files unless explicitly asked. The `.todo` files are the source of truth for what's missing.
51+
52+
### Step 2: Generate Reference Bindings
53+
54+
Run the xtro generator to produce reference C# bindings from the SDK headers:
55+
56+
```bash
57+
make -C tests/xtro-sharpie gen-all
58+
```
59+
60+
This creates generated `.cs` files you can search to find the correct C# signatures, attributes, and patterns for the APIs you need to bind. Use these as reference — don't copy them verbatim.
61+
62+
### Step 3: Research the Native API
63+
64+
Before implementing, understand the native API:
65+
- Search the generated reference bindings for the correct Objective-C selectors
66+
- Read Apple header files when available (under `$XCODE_DEVELOPER_ROOT`)
67+
- Check existing bindings in `src/frameworkname.cs` for patterns used in the same framework
68+
69+
### Step 4: Implement Bindings
70+
71+
Bindings go in these locations:
72+
- **`src/frameworkname.cs`** — API definitions (interfaces with `[Export]` attributes)
73+
- **`src/FrameworkName/`** — Manual code (partial classes, enums, P/Invokes, extensions)
74+
- **`src/frameworks.sources`** — Maps frameworks to source files (update if adding new files)
75+
76+
Key binding patterns:
77+
78+
```csharp
79+
// New property on existing class
80+
[Export ("allowsCaptureOfClearKeyVideo")]
81+
bool AllowsCaptureOfClearKeyVideo { get; set; }
82+
83+
// New method on existing class
84+
[Export ("setCaptionPreviewProfileId:")]
85+
void SetCaptionPreviewProfileId ([NullAllowed] string profileId);
86+
87+
// New notification field
88+
[Field ("AVPlayerInterstitialEventMonitorScheduleRequestedNotification")]
89+
[Notification]
90+
NSString ScheduleRequestedNotification { get; }
91+
```
92+
93+
> **NEVER** forget platform availability attributes. Every new API must have `[iOS]`, `[Mac]`, `[TV]`, `[MacCatalyst]`, and/or `[No*]` attributes matching the `.todo` file platforms where the API appears.
94+
95+
> **NEVER** use `string.Empty` — use `""`. Never use `Array.Empty<T>()` — use `[]`.
96+
97+
> ⚠️ Place a space before parentheses and brackets: `Foo ()`, `Bar (1, 2)`, `myarray [0]`.
98+
99+
> ⚠️ For in depth binding patterns and conventions See [references/binding-patterns.md](references/binding-patterns.md)
100+
101+
### Step 5: Build
102+
103+
```bash
104+
make -C src build
105+
```
106+
107+
Fix any compilation errors before proceeding. Builds can take up to 60 minutes — do not timeout early.
108+
109+
### Step 6: Validate with Tests
110+
111+
Run all three test suites. **Run them sequentially, not in parallel.**
112+
113+
#### 6a. Xtro Tests
114+
115+
```bash
116+
make -C tests/xtro-sharpie run-ios
117+
make -C tests/xtro-sharpie run-tvos
118+
make -C tests/xtro-sharpie run-macos
119+
make -C tests/xtro-sharpie run-maccatalyst
120+
```
121+
122+
Verify all `.todo` entries for the bound framework are resolved. If any remain, they need binding or explicit `.ignore` entries with justification.
123+
124+
#### 6b. Cecil Tests
125+
126+
```bash
127+
make -C tests/cecil-tests run-tests
128+
```
129+
130+
#### 6c. Introspection Tests (All Platforms)
131+
132+
**IMPORTANT:** Clean shared obj directories before each platform to avoid NETSDK1005 errors:
133+
134+
```bash
135+
# iOS
136+
rm -rf tests/common/Touch.Unit/Touch.Client/dotnet/obj tests/common/MonoTouch.Dialog/obj
137+
make -C tests/introspection/dotnet clean-ios build-ios run-ios
138+
139+
# tvOS
140+
rm -rf tests/common/Touch.Unit/Touch.Client/dotnet/obj tests/common/MonoTouch.Dialog/obj
141+
make -C tests/introspection/dotnet clean-tvos build-tvos run-tvos
142+
143+
# macOS (use run-bare for direct execution with captured output)
144+
rm -rf tests/common/Touch.Unit/Touch.Client/dotnet/obj tests/common/MonoTouch.Dialog/obj
145+
make -C tests/introspection/dotnet clean-macOS build-macOS run-bare-macOS
146+
147+
# MacCatalyst (use run-bare for direct execution with captured output)
148+
rm -rf tests/common/Touch.Unit/Touch.Client/dotnet/obj tests/common/MonoTouch.Dialog/obj
149+
make -C tests/introspection/dotnet clean-MacCatalyst build-MacCatalyst run-bare-MacCatalyst
150+
```
151+
152+
> ⚠️ **macOS/MacCatalyst:** Use `make run-bare` (not `make run`) — `make run` launches the app without waiting or capturing stdout. `run-bare` runs the executable directly to capture test output.
153+
154+
> ⚠️ **iOS/tvOS:** Use `make run` (not `make run-bare`) — these require simulator infrastructure that `run-bare` doesn't provide.
155+
156+
Look for this pattern in test output to confirm results:
157+
```
158+
Tests run: X Passed: X Inconclusive: X Failed: X Ignored: X
159+
```
160+
161+
### Step 7: Handle Test Failures
162+
163+
If introspection tests fail for newly bound types:
164+
- Check if the type crashes on simulator (common for hardware-dependent APIs)
165+
- Add exclusions in the platform-specific `ApiCtorInitTest.cs` files if needed
166+
- Types that crash on init, dispose, or toString need specific exclusion entries
167+
168+
If xtro still shows unresolved entries:
169+
- Some APIs may be platform-specific (only available on device, not simulator)
170+
- Create `.ignore` entries with comments explaining why they can't be bound
171+
- Or create remaining `.todo` entries for known limitations
172+
173+
## Stop Signals
174+
175+
- Stop investigating test failures after identifying the root cause. Don't trace full call stacks.
176+
- If a type crashes on simulator, add an exclusion and move on — don't try to fix simulator issues.
177+
- Don't bind APIs beyond what's listed in the `.todo` files unless explicitly asked.
178+
- Report results per platform after all tests pass. Don't re-run passing tests.
179+
180+
## Output Format
181+
182+
When reporting results, use this structure:
183+
184+
1. **APIs bound** — table of types/members added with their platforms
185+
2. **Files changed** — list of modified files
186+
3. **Test results** — per-platform pass/fail for xtro, cecil, and introspection
187+
4. **Remaining items** — any `.todo` entries intentionally left unbound, with reasons
188+
189+
## References
190+
191+
- **Binding patterns and conventions**: See [references/binding-patterns.md](references/binding-patterns.md)
192+
- **Test commands and troubleshooting**: See [references/test-workflow.md](references/test-workflow.md)

0 commit comments

Comments
 (0)