Skip to content

Visual Preview in Apple

Enhance your editorial and development experience by previewing draft content in the debug build of your Apple app.

Replace the following in ExampleApp.swift to set version based on the build configuration.

Example/ExampleApp.swift
private let client = StoryblokClient(
library: Block.self,
accessToken: "YOUR_ACCESS_TOKEN",
version: .draft,
version: {
#if DEBUG
.draft
#else
.published
#endif
}(),
region: .eu // Choose the correct region from your Space.
)

With these changes, debug builds of the app now fetch draft content from Storyblok, while release builds fetch published content.

With version set to .draft, any changes you save in Storyblok appear the next time the story() publisher is subscribed.

Add the following in ExampleApp.swift for a pull-to-refresh implementation so the story can be refreshed without restarting the app.

Example/ExampleApp.swift
var body: some Scene {
WindowGroup {
ScrollView {
if let story {
story.content
} else {
ProgressView()
.progressViewStyle(.circular)
.frame(maxWidth: .infinity, minHeight: 200)
}
}
.onReceive(publisher) { value in story = value }
.refreshable {
for await value in publisher.values {
story = value
}
}
}
}

The story() publisher is now subscribed as follows:

  • The existing onReceive modifier subscribes when the view appears to trigger the initial load automatically.
  • The new refreshable modifier adds pull-to-refresh behavior to the scroll view, re-subscribing to the publisher through its values sequence when the user pulls down.
  • Iterating the sequence with for await keeps the refresh indicator visible until the request completes, updating the story with the fresh value from the network.

With this in place, make a change to the home story, save it, then pull down in the debug build to immediately see the updated draft content.

Was this page helpful?

What went wrong?

This site uses reCAPTCHA and Google's Privacy Policy (opens in a new window).Terms of Service (opens in a new window) apply.