Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
6c9b10c
refactor(ios): build interop from locked SDK xcframeworks with Object…
Kapusch Oct 26, 2026
4d52a82
fix(packaging): link a Share placeholder when Share is not selected
Kapusch Oct 26, 2026
bbf7dcd
feat(app-events): add App Events native facade
Kapusch Oct 27, 2026
c8571ab
feat(app-events): add managed FacebookAppEvents API and constants
Kapusch Oct 27, 2026
81e3039
feat(packaging): accept the AppEvents feature selection
Kapusch Oct 26, 2026
76708ad
fix(share): keep App Events settings configured by the app
Kapusch Oct 26, 2026
ce92aed
ci: validate package contents, App Events bindings and public tree
Kapusch Oct 26, 2026
5ae4aa0
docs(app-events): document App Events integration and consent gating
Kapusch Oct 26, 2026
cb98007
feat(sample): demonstrate the App Events consent flow
Kapusch Oct 26, 2026
defb904
fix(login): bind Login entry points with static __Internal imports
Kapusch Oct 26, 2026
578bf17
fix(app-events): refuse calls the SDK would drop before initialization
Kapusch Oct 27, 2026
c6417f4
feat(app-events): align InitializeSdk, user data and parameters with …
Kapusch Oct 27, 2026
ebbe864
docs(app-events): describe SDK 18.0.2 consent semantics truthfully
Kapusch Oct 27, 2026
e1fc080
fix(sample): follow the documented App Events withdrawal steps
Kapusch Oct 27, 2026
0203dda
ci: check the SDK slices and privacy manifests the targets reference
Kapusch Oct 27, 2026
27f045c
ci: build the sample and check it keeps every native entry point
Kapusch Oct 27, 2026
37e8f64
docs: state the bundled SDK version and that every selection ships FB…
Kapusch Oct 27, 2026
2da6bd1
chore(release): set package version to 1.2.0
Kapusch Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@
- [ ] Built wrapper: `bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build.sh`
- [ ] Collected SDK xcframeworks: `bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/collect-facebook-xcframeworks.sh`
- [ ] Packed NuGet: `dotnet pack src/Kapusch.FacebookApisForiOSComponents/Kapusch.FacebookApisForiOSComponents.csproj -c Release -o artifacts/nuget`
- [ ] Validated package: `python3 scripts/validate-package.py`
- [ ] Public tree scan: `python3 scripts/verify-public.py`
- [ ] Feature selection: `bash tests/validate-feature-selection.sh`
- [ ] Sample built and entry points checked: `python3 scripts/verify-app-symbols.py <sample .app>/Kapusch.Facebook.iOS.Sample`
- [ ] Updated docs if behavior/integration changed
65 changes: 18 additions & 47 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ jobs:
with:
dotnet-version: "10.0.203"

- name: Scan public tree
env:
KAPUSCH_PRIVATE_TERMS: ${{ secrets.KAPUSCH_PRIVATE_TERMS }}
run: python3 scripts/verify-public.py

- name: Validate feature selection
run: bash tests/validate-feature-selection.sh

Expand All @@ -34,12 +39,12 @@ jobs:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('global.json', '**/*.csproj') }}

- name: Cache SwiftPM scratch
- name: Cache pinned Facebook SDK archives
uses: actions/cache@v4
with:
path: |
src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build/spm
key: ${{ runner.os }}-swiftpm-${{ hashFiles('src/Kapusch.FacebookApisForiOSComponents/Native/iOS/KapuschFacebookAuthInterop/Package.resolved') }}
src/Kapusch.FacebookApisForiOSComponents/Native/iOS/.cache/downloads
key: ${{ runner.os }}-facebook-ios-sdk-${{ hashFiles('DependencyLocks/iOS/lockstate.txt') }}

- name: Build iOS wrapper
run: |
Expand All @@ -55,51 +60,17 @@ jobs:
-c Release \
-o artifacts/nuget

- name: Validate nupkg layout
- name: Validate package
run: python3 scripts/validate-package.py

- name: Build sample (simulator) and check its native entry points
run: |
python3 - <<'PY'
import glob, sys, zipfile

nupkgs = glob.glob("artifacts/nuget/*.nupkg")
if not nupkgs:
print("ERROR: no .nupkg found under artifacts/nuget/")
sys.exit(1)

nupkg = sorted(nupkgs)[-1]
print(f"Validating {nupkg}")

z = zipfile.ZipFile(nupkg)
names = set(z.namelist())

required = [
"buildTransitive/Kapusch.Facebook.iOS.targets",
"kfb.xcframework/Info.plist",
"kfbshare.xcframework/Info.plist",
"fb/FBAEMKit.xcframework/Info.plist",
"fb/FBSDKCoreKit.xcframework/Info.plist",
"fb/FBSDKCoreKit_Basics.xcframework/Info.plist",
"fb/FBSDKLoginKit.xcframework/Info.plist",
"fb/FBSDKShareKit.xcframework/Info.plist",
]

missing = [p for p in required if p not in names]
if missing:
print("ERROR: missing required paths in nupkg:")
for p in missing:
print(f" - {p}")
sys.exit(1)

# Guardrail: ensure the wrapper is not flattened at the package root.
if "Info.plist" in names:
print("ERROR: wrapper appears flattened (found 'Info.plist' at package root).")
sys.exit(1)

if any(name.startswith("fb/FBSDKGamingServicesKit.xcframework/") for name in names):
print("ERROR: GamingServicesKit must not be packaged.")
sys.exit(1)

print("OK: nupkg layout looks correct.")
PY
dotnet build samples/Kapusch.Facebook.iOS.Sample/Kapusch.Facebook.iOS.Sample.csproj \
-c Debug \
-p:RuntimeIdentifier=iossimulator-arm64 \
-p:EnableCodeSigning=false
python3 scripts/verify-app-symbols.py \
samples/Kapusch.Facebook.iOS.Sample/bin/Debug/net10.0-ios/iossimulator-arm64/Kapusch.Facebook.iOS.Sample.app/Kapusch.Facebook.iOS.Sample

- uses: actions/upload-artifact@v4
with:
Expand Down
57 changes: 10 additions & 47 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ jobs:
with:
dotnet-version: "10.0.203"

- name: Scan public tree
env:
KAPUSCH_PRIVATE_TERMS: ${{ secrets.KAPUSCH_PRIVATE_TERMS }}
run: python3 scripts/verify-public.py

- name: Validate feature selection
run: bash tests/validate-feature-selection.sh

Expand All @@ -88,12 +93,12 @@ jobs:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('global.json', '**/*.csproj') }}

- name: Cache SwiftPM scratch
- name: Cache pinned Facebook SDK archives
uses: actions/cache@v4
with:
path: |
src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build/spm
key: ${{ runner.os }}-swiftpm-${{ hashFiles('src/Kapusch.FacebookApisForiOSComponents/Native/iOS/KapuschFacebookAuthInterop/Package.resolved') }}
src/Kapusch.FacebookApisForiOSComponents/Native/iOS/.cache/downloads
key: ${{ runner.os }}-facebook-ios-sdk-${{ hashFiles('DependencyLocks/iOS/lockstate.txt') }}

- name: Build iOS wrapper
run: |
Expand All @@ -110,50 +115,8 @@ jobs:
-o artifacts/nuget \
/p:PackageVersion="${{ steps.version.outputs.version }}"

- name: Validate nupkg layout
run: |
python3 - <<'PY'
import glob, sys, zipfile

nupkgs = glob.glob("artifacts/nuget/*.nupkg")
if not nupkgs:
print("ERROR: no .nupkg found under artifacts/nuget/")
sys.exit(1)

nupkg = sorted(nupkgs)[-1]
print(f"Validating {nupkg}")

z = zipfile.ZipFile(nupkg)
names = set(z.namelist())

required = [
"buildTransitive/Kapusch.Facebook.iOS.targets",
"kfb.xcframework/Info.plist",
"kfbshare.xcframework/Info.plist",
"fb/FBAEMKit.xcframework/Info.plist",
"fb/FBSDKCoreKit.xcframework/Info.plist",
"fb/FBSDKCoreKit_Basics.xcframework/Info.plist",
"fb/FBSDKLoginKit.xcframework/Info.plist",
"fb/FBSDKShareKit.xcframework/Info.plist",
]

missing = [p for p in required if p not in names]
if missing:
print("ERROR: missing required paths in nupkg:")
for p in missing:
print(f" - {p}")
sys.exit(1)

if "Info.plist" in names:
print("ERROR: wrapper appears flattened (found 'Info.plist' at package root).")
sys.exit(1)

if any(name.startswith("fb/FBSDKGamingServicesKit.xcframework/") for name in names):
print("ERROR: GamingServicesKit must not be packaged.")
sys.exit(1)

print("OK: nupkg layout looks correct.")
PY
- name: Validate package
run: python3 scripts/validate-package.py

- name: Push to NuGet.org
if: steps.version.outputs.publish_target == 'nuget'
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ artifacts/
# macOS
.DS_Store

# SwiftPM / Xcode
# Xcode
.build/
*.xcworkspace/
DerivedData/
Expand All @@ -24,6 +24,7 @@ DerivedData/

# Native build output (repo-only)
src/**/Native/iOS/build/
src/**/Native/iOS/.cache/

# Sample local config
samples/**/Info.plist
Expand Down
13 changes: 11 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,23 @@
- Public OSS repo: keep docs/sample generic and not app-specific.
- The NuGet ships the required `xcframework`s and references them via `NativeReference`.
- Consuming apps must not download native deps at build time.
- The repo may use SwiftPM during CI/build to fetch the upstream Facebook iOS SDK, but consuming apps must not download native deps at build time.
- The repo build downloads the upstream Facebook iOS SDK release xcframeworks pinned (URL + SHA-256) in `DependencyLocks/iOS/lockstate.txt`; consuming apps must not download native deps at build time.
- The native facades are Objective-C and use only the SDK's Objective-C headers, so they do not depend on the Swift compiler release Meta used for the binaries.

## Repo layout
- `src/Kapusch.FacebookApisForiOSComponents/` — NuGet project (managed API + buildTransitive MSBuild)
- `src/Kapusch.FacebookApisForiOSComponents/Native/iOS/` — Swift wrapper source + scripts (repo-only)
- `src/Kapusch.FacebookApisForiOSComponents/Native/iOS/` — Objective-C wrapper source + scripts (repo-only)
- `DependencyLocks/iOS/lockstate.txt` — pinned Facebook iOS SDK artifacts
- `Docs/` — integration docs
- `samples/` — optional sample template (no secrets committed)

## Validation
- `bash tests/validate-feature-selection.sh` — feature selection and wrapper source invariants.
- `python3 scripts/validate-package.py` — packed layout, native exports, App Events bindings and constants.
- `python3 scripts/verify-public.py` — no real Facebook credentials or emails in tracked files, and no private term read from `KAPUSCH_PRIVATE_TERMS` or the untracked `.git/info/private-terms`.
- `python3 scripts/verify-app-symbols.py <app executable>` — a built app (CI builds the sample) keeps every `kfb_*` entry point.
- When package contents or native entry points change, update `scripts/validate-package.py` in the same commit.

## Safety
- Do not add new dependency ingestion paths without documenting them in `README.md`.
- Do not commit real app ids/secrets.
Expand Down
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ Thanks for contributing!
If you are working without the NuGet (ProjectReference), see `Docs/SourceMode.md`.


Build the Swift wrapper:
Build the Objective-C wrappers (this also restores and collects the pinned Facebook SDK xcframeworks):

- `bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build.sh`

Collect the Facebook SDK xcframeworks (from the SwiftPM scratch produced by the build):
Re-collect the Facebook SDK xcframeworks only (restores them from `DependencyLocks/iOS/lockstate.txt` when needed):

- `bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/collect-facebook-xcframeworks.sh`

Expand All @@ -27,14 +27,14 @@ Pack the NuGet:
## Formatting

- C#: follow `.editorconfig` (tabs, LF).
- Swift: keep changes minimal and consistent with existing style.
- Objective-C: keep changes minimal and consistent with existing style (tabs, ARC, Objective-C SDK surface only).

## Pull requests

- Keep PRs focused and well-scoped.
- Branch from `master` and target `master`; this repository does not use long-lived `release/*` branches.
- Do not commit secrets.
- If you update the Facebook SDK version, update `Package.swift` and `Package.resolved` together.
- If you update the Facebook SDK version, update every line of `DependencyLocks/iOS/lockstate.txt` together. The SHA-256 values must equal the `remoteChecksum` values of the upstream `Package.swift` at the same tag.

See `Docs/Release.md` before changing versions, tags, or publishing workflows.

Expand Down
10 changes: 10 additions & 0 deletions DependencyLocks/iOS/lockstate.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Pinned Facebook iOS SDK release artifacts (dynamic xcframeworks).
# Format: <url> <sha256> <filename>
# The SHA-256 values equal the `remoteChecksum` values of the upstream
# Package.swift at the same tag.

https://github.com/facebook/facebook-ios-sdk/releases/download/v18.0.2/FBSDKCoreKit_Basics-Dynamic_XCFramework.zip c57eb4255c86b60ac0a19cd4c42694220f41985e104ced9cb1c998b650de1bf3 FBSDKCoreKit_Basics-Dynamic_XCFramework.zip
https://github.com/facebook/facebook-ios-sdk/releases/download/v18.0.2/FBAEMKit-Dynamic_XCFramework.zip 2a2409a08917b6cfab27a66333ecb73c27b8852d45b2985e4281f68554c0dd5f FBAEMKit-Dynamic_XCFramework.zip
https://github.com/facebook/facebook-ios-sdk/releases/download/v18.0.2/FBSDKCoreKit-Dynamic_XCFramework.zip a647fa24789d5c579ca8c7088c9394d5b410194d8c7e269f8d3f7cf3c33279fd FBSDKCoreKit-Dynamic_XCFramework.zip
https://github.com/facebook/facebook-ios-sdk/releases/download/v18.0.2/FBSDKLoginKit-Dynamic_XCFramework.zip 0f984f04366fcc141e901de6c635fef40c7c496c015c0d1121e03c5913431d52 FBSDKLoginKit-Dynamic_XCFramework.zip
https://github.com/facebook/facebook-ios-sdk/releases/download/v18.0.2/FBSDKShareKit-Dynamic_XCFramework.zip dad67fc33428f9c793252a71607c08c6ce9748b6804d0b4241c63ab444c8fef8 FBSDKShareKit-Dynamic_XCFramework.zip
Loading
Loading