Share HuggingFace model cache via App Group and update TMPDIR handling
keypair34 committed
Apr 28, 2026 at 20:36 UTC
39be9e7cfaec27304f38cee1842b9a77a92d8922
3 files changed
+30
-21
Examples/OndeExample/InferenceEnvironment.swift
+15
-21
@@ -1,34 +1,28 @@
1
import Foundation
2
3
-/// Configures the environment variables that the Onde Rust core requires when
4
-/// running inside an iOS/tvOS app sandbox.
3
+/// Points `HF_HOME` and `HF_HUB_CACHE` at the Onde shared App Group container
4
+/// so downloaded models are available to every Onde-powered app on the device.
5
///
6
-/// Call this **before** any `OndeChatEngine` method — ideally in your `@main`
7
-/// App struct's `init()`.
8
-///
9
-/// What each variable does:
10
-/// - `HF_HOME` – root of the HuggingFace Hub cache inside the app container
11
-/// - `HF_HUB_CACHE` – models subdirectory (avoids the default `~/.cache` path
12
-/// which is unreachable in the sandbox)
13
-/// - `TMPDIR` – the system-provided temporary directory for the process
6
+/// Call this once at launch, before creating an `OndeChatEngine`.
7
func setupInferenceEnvironment() {
8
let fm = FileManager.default
9
17
- // Base directory for all Onde / HuggingFace data.
18
- // Application Support is backed up by iCloud by default; use Caches if
19
- // you prefer a purgeable location and are OK re-downloading models.
20
- let appSupport = fm.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
21
- let hfHome = appSupport.appendingPathComponent("huggingface", isDirectory: true)
10
+ // All Onde apps use this App Group to share the HuggingFace model cache.
11
+ // If the group isn't available (e.g. entitlement missing during development),
12
+ // fall back to the app's own Application Support directory.
13
+ let base: URL = fm.containerURL(
14
+ forSecurityApplicationGroupIdentifier: "group.com.ondeinference.apps"
15
+ ) ?? fm.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
16
23
- // Create the directory tree up-front so hf-hub never has to.
24
- let hfHubCache = hfHome.appendingPathComponent("hub", isDirectory: true)
17
+ let hfHome = base.appendingPathComponent("models", isDirectory: true)
18
+ let hfHubCache = hfHome.appendingPathComponent("hub", isDirectory: true)
19
try? fm.createDirectory(at: hfHubCache, withIntermediateDirectories: true)
20
21
setenv("HF_HOME", hfHome.path, 1)
22
setenv("HF_HUB_CACHE", hfHubCache.path, 1)
23
30
- // The Rust std-lib respects TMPDIR; make sure it points inside our sandbox.
31
- if let tmp = ProcessInfo.processInfo.environment["TMPDIR"] {
32
- setenv("TMPDIR", tmp, 1) // already set by iOS — just make it explicit
33
- }
24
+ // Make sure TMPDIR points inside the sandbox for the Rust side.
25
+ let tmp = base.appendingPathComponent("tmp", isDirectory: true)
26
+ try? fm.createDirectory(at: tmp, withIntermediateDirectories: true)
27
+ setenv("TMPDIR", tmp.path, 1)
28
}
Examples/OndeExample/OndeExample.entitlements
new
+10
@@ -0,0 +1,10 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>com.apple.security.application-groups</key>
6
+ <array>
7
+ <string>group.com.ondeinference.apps</string>
8
+ </array>
9
+</dict>
10
+</plist>
Examples/OndeExample/project.yml
+5
@@ -20,6 +20,11 @@ targets:
20
excludes:
21
- project.yml
22
- "*.xcodeproj"
23
+ entitlements:
24
+ path: OndeExample.entitlements
25
+ properties:
26
+ com.apple.security.application-groups:
27
+ - group.com.ondeinference.apps
28
dependencies:
29
- package: Onde
30
product: Onde