Skip to content

Commit 0907d7f

Browse files
authored
fix #113 -- fall back to local files if offline (#133)
1 parent 30e3063 commit 0907d7f

File tree

4 files changed

+125
-8
lines changed

4 files changed

+125
-8
lines changed

Applications/StableDiffusionExample/ContentView.swift

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,25 @@ actor ModelFactory {
146146
switch loadState {
147147
case .idle:
148148
let task = Task {
149-
try await configuration.download { progress in
150-
if progress.fractionCompleted < 0.99 {
151-
reportProgress(
152-
.init(
153-
title: "Download", current: progress.fractionCompleted * 100,
154-
limit: 100))
149+
do {
150+
try await configuration.download { progress in
151+
if progress.fractionCompleted < 0.99 {
152+
reportProgress(
153+
.init(
154+
title: "Download", current: progress.fractionCompleted * 100,
155+
limit: 100))
156+
}
157+
}
158+
} catch {
159+
let nserror = error as NSError
160+
if nserror.domain == NSURLErrorDomain
161+
&& nserror.code == NSURLErrorNotConnectedToInternet
162+
{
163+
// Internet connection appears to be offline -- fall back to loading from
164+
// the local directory
165+
reportProgress(.init(title: "Offline", current: 100, limit: 100))
166+
} else {
167+
throw error
155168
}
156169
}
157170

Libraries/LLM/Load.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ func prepareModelDirectory(
3131
// an authorizationRequired means (typically) that the named repo doesn't exist on
3232
// on the server so retry with local only configuration
3333
return configuration.modelDirectory(hub: hub)
34+
} catch {
35+
let nserror = error as NSError
36+
if nserror.domain == NSURLErrorDomain && nserror.code == NSURLErrorNotConnectedToInternet {
37+
// Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline."
38+
// fall back to the local directory
39+
return configuration.modelDirectory(hub: hub)
40+
} else {
41+
throw error
42+
}
3443
}
3544
}
3645

Libraries/LLM/Tokenizer.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,25 @@ func loadTokenizerConfig(configuration: ModelConfiguration, hub: HubApi) async t
2121

2222
switch configuration.id {
2323
case .id(let id):
24-
config = LanguageModelConfigurationFromHub(
25-
modelName: configuration.tokenizerId ?? id, hubApi: hub)
24+
do {
25+
// the load can fail (async when we try to use it)
26+
let loaded = LanguageModelConfigurationFromHub(
27+
modelName: configuration.tokenizerId ?? id, hubApi: hub)
28+
_ = try await loaded.tokenizerConfig
29+
config = loaded
30+
} catch {
31+
let nserror = error as NSError
32+
if nserror.domain == NSURLErrorDomain
33+
&& nserror.code == NSURLErrorNotConnectedToInternet
34+
{
35+
// Internet connection appears to be offline -- fall back to loading from
36+
// the local directory
37+
config = LanguageModelConfigurationFromHub(
38+
modelFolder: configuration.modelDirectory(hub: hub), hubApi: hub)
39+
} else {
40+
throw error
41+
}
42+
}
2643
case .directory(let directory):
2744
config = LanguageModelConfigurationFromHub(modelFolder: directory, hubApi: hub)
2845
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1600"
4+
version = "1.7">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES"
8+
buildArchitectures = "Automatic">
9+
<BuildActionEntries>
10+
<BuildActionEntry
11+
buildForTesting = "YES"
12+
buildForRunning = "YES"
13+
buildForProfiling = "YES"
14+
buildForArchiving = "YES"
15+
buildForAnalyzing = "YES">
16+
<BuildableReference
17+
BuildableIdentifier = "primary"
18+
BlueprintIdentifier = "C36BF0002BC5CE55002D4AFE"
19+
BuildableName = "StableDiffusionExample.app"
20+
BlueprintName = "StableDiffusionExample"
21+
ReferencedContainer = "container:mlx-swift-examples.xcodeproj">
22+
</BuildableReference>
23+
</BuildActionEntry>
24+
</BuildActionEntries>
25+
</BuildAction>
26+
<TestAction
27+
buildConfiguration = "Debug"
28+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
29+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
30+
shouldUseLaunchSchemeArgsEnv = "YES"
31+
shouldAutocreateTestPlan = "YES">
32+
</TestAction>
33+
<LaunchAction
34+
buildConfiguration = "Debug"
35+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37+
launchStyle = "0"
38+
useCustomWorkingDirectory = "NO"
39+
ignoresPersistentStateOnLaunch = "NO"
40+
debugDocumentVersioning = "YES"
41+
debugServiceExtension = "internal"
42+
allowLocationSimulation = "YES">
43+
<BuildableProductRunnable
44+
runnableDebuggingMode = "0">
45+
<BuildableReference
46+
BuildableIdentifier = "primary"
47+
BlueprintIdentifier = "C36BF0002BC5CE55002D4AFE"
48+
BuildableName = "StableDiffusionExample.app"
49+
BlueprintName = "StableDiffusionExample"
50+
ReferencedContainer = "container:mlx-swift-examples.xcodeproj">
51+
</BuildableReference>
52+
</BuildableProductRunnable>
53+
</LaunchAction>
54+
<ProfileAction
55+
buildConfiguration = "Release"
56+
shouldUseLaunchSchemeArgsEnv = "YES"
57+
savedToolIdentifier = ""
58+
useCustomWorkingDirectory = "NO"
59+
debugDocumentVersioning = "YES">
60+
<BuildableProductRunnable
61+
runnableDebuggingMode = "0">
62+
<BuildableReference
63+
BuildableIdentifier = "primary"
64+
BlueprintIdentifier = "C36BF0002BC5CE55002D4AFE"
65+
BuildableName = "StableDiffusionExample.app"
66+
BlueprintName = "StableDiffusionExample"
67+
ReferencedContainer = "container:mlx-swift-examples.xcodeproj">
68+
</BuildableReference>
69+
</BuildableProductRunnable>
70+
</ProfileAction>
71+
<AnalyzeAction
72+
buildConfiguration = "Debug">
73+
</AnalyzeAction>
74+
<ArchiveAction
75+
buildConfiguration = "Release"
76+
revealArchiveInOrganizer = "YES">
77+
</ArchiveAction>
78+
</Scheme>

0 commit comments

Comments
 (0)