How to tell when replication complete on app launch?

I’m having trouble pinning down when replication is complete on app launch. In other words, when replication the first time is done.

I have a loading splash screen where I need everything replicated before letting the user in. Calculating the percentage is easy enough and in the docs, but there are many different exceptions in the replication which makes this not straight forward.

This is how my code looks like for kCBLReplicationChangeNotification:

if pull.status == .Active || push.status == .Active {
    let total = Float(push.changesCount + pull.changesCount)
    
    if total > 0 {
        let completed = Float(push.completedChangesCount + pull.completedChangesCount)
        let percent = completed / total
        
        progressView.progress = percent
        
        if !replicationComplete && percent >= 0.99 {
            replicationComplete = true
            startSession()
        }
    }
}

A few things I’m hoping someone can help shed light on:

  1. Replication percentage always ends up as something like 0.999783, but never 1. Is this expected?

  2. What if there’s nothing to replicate for the user, the total will be zero and the user’s splash screen will never finish or reach 100%?

  3. What if there’s no internet, does it timeout back to idle state?

I’m sort of confused and wish there was a replication.complete flag, because [active, idle, offline, stopped] isn’t what it seems, such as offline isn’t the same as no internet, and idle kind of means complete but not really. Also if the total isn’t determined yet, -1 would be more clear I think since zero just gives total another meaning in some cases.

Any help or advise would be greatly appreciated to accomplish a splash screen that fully completes replication before letting the user into the app.

The replication is complete when its status changes to idle (continuous) or stopped (one-shot). If that’s not working for you, please give us some details.

  1. The progress count numbers only have meaning while the replication’s state is active. When it finishes, the state will change, rather than the numbers moving to exactly 100%.
  2. If there’s nothing to replicate the status will quickly go to idle/stopped.
  3. That’s what the offline state means.

Thanks for the clarity. What was confusing me is there’s a status for push, pull, and replication objects and they can all be different.

Figuring when is an actual complete seems to be this for me: (pull.status == .Idle || pull.status == .Stopped) && (push.status == .Idle || push.status == .Stopped)

Btw to figure out truly offline, since offline triggers once on start up even when internet is available, I ended up doing something like this:

    if repl.status == .Offline {
        NSTimer.after(5) {
            // Allow user to get in if still offline
            guard repl.status == .Offline else { return }
            ...start up...
        }
        return
    }

What was confusing me is there’s a status for push, pull, and replication objects and they can all be different

Replication is uni-directional; it can be either push or pull. Usually you run both a push and a pull replicator, but they’re independent of each other.

If you are trying to find out when you’ve received all the data on the app’s first launch, the only replicator you care about is the pull. (The push one will immediately stop or go idle because it sees there’s nothing in the local database.)

offline triggers once on start up even when internet is available

Yeah, that can be a bit confusing. The process that figures out if the server is reachable is asynchronous, so the replicator starts out assuming it’s offline. It should probably start with the opposite assumption, but changes in the replicator’s state machine have to be made very, very carefully, and we haven’t gotten around to redesigning that yet.

I think attachments adds another dimension to the replication state process. I posted more details in case it helps anyone: https://github.com/couchbase/couchbase-lite-ios/issues/1508