Cache & Sync
Manage frame caching, offline support, and sync strategies in Nativeblocks.
Nativeblocks caches frames locally after the first fetch. On subsequent loads the cached version is shown immediately while the SDK silently checks for updates in the background.
API
// Fetch the latest frame from the server and update local cache
NativeblocksManager.getInstance().syncFrame("/home")
// Remove a specific frame from cache
NativeblocksManager.getInstance().clearFrame("/home")
// Remove all cached frames
NativeblocksManager.getInstance().clearAllFrames()
Scenarios
App Launch Prefetch
Fetch critical frames during startup so users see fresh content on first navigation with no loading delay.
Use getScaffold to retrieve all registered frame routes from the server, then sync each one. This way your prefetch list stays in sync with whatever frames are deployed without hardcoding routes in the app.
class HomeViewModel : ViewModel() {
fun prefetch() {
viewModelScope.launch {
// Fetch all registered routes from the server and sync each one
NativeblocksManager.getInstance().getScaffold()
.onSuccess { scaffold ->
scaffold.frames.forEach { frame ->
NativeblocksManager.getInstance().syncFrame(frame.route)
}
}
.onFailure { Log.e("Nativeblocks", "prefetch failed", it) }
}
}
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: HomeViewModel by viewModels()
setContent {
MyAppTheme {
val navController = rememberNavController()
LaunchedEffect(Unit) {
viewModel.prefetch()
}
Scaffold { padding ->
NavHost(
navController = navController,
startDestination = "home",
modifier = Modifier.padding(padding)
) {
composable("home") {
NativeblocksFrame(
route = "/home",
routeArguments = hashMapOf(),
loading = { NativeblocksLoading() },
error = { msg -> NativeblocksError(message = msg) }
)
}
}
}
}
}
}
}
Pull-to-Refresh
Let users manually refresh a frame by pulling down on the screen.
import com.google.accompanist.swiperefresh.SwipeRefresh
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
@Composable
fun HomeScreen() {
var isRefreshing by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
SwipeRefresh(
state = rememberSwipeRefreshState(isRefreshing),
onRefresh = {
scope.launch {
isRefreshing = true
NativeblocksManager.getInstance().syncFrame("/home")
isRefreshing = false
}
}
) {
NativeblocksFrame(
route = "/home",
routeArguments = hashMapOf(),
loading = { NativeblocksLoading() },
error = { msg -> NativeblocksError(message = msg) }
)
}
}
After a Server Deploy
When you push a new frame version, use a push notification to trigger an immediate sync on all active clients.
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class NativeblocksMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(message: RemoteMessage) {
val route = message.data["route"] ?: return
GlobalScope.launch {
NativeblocksManager.getInstance().syncFrame(route)
}
}
}
User Logout
Clear all cached frames on logout to remove any user-scoped or personalised content.
fun logout() {
viewModelScope.launch {
authRepository.logout()
NativeblocksManager.getInstance().clearAllFrames()
navController.navigate("login") {
popUpTo(0) { inclusive = true }
}
}
}
Stale or Broken Frame
If a frame fails to render, clear its cache from the error callback and let it re-fetch on the next visit.
@Composable
fun CheckoutScreen() {
val scope = rememberCoroutineScope()
NativeblocksFrame(
route = "/checkout",
routeArguments = hashMapOf(),
loading = { NativeblocksLoading() },
error = { msg ->
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = msg)
Spacer(modifier = Modifier.height(12.dp))
Button(onClick = {
scope.launch {
NativeblocksManager.getInstance().clearFrame("/checkout")
}
}) {
Text("Retry")
}
}
}
)
}
A/B Test Reset
When user attributes change (plan upgrade, login), update global parameters and sync to receive the correct variant immediately.
fun onPlanUpgraded(newPlan: String) {
viewModelScope.launch {
NativeblocksManager.getInstance().setGlobalParameters(
"plan" to newPlan
)
NativeblocksManager.getInstance().syncFrame("/home")
}
}
How offline works
When a device has no connectivity, NativeblocksFrame renders the last cached version automatically. No code changes needed. The frame stays cached until explicitly cleared or until it expires based on your release TTL settings.
If no cached version exists and the device is offline, the error callback is triggered.