Push notifications are easy to send and difficult to deserve.
Slovo is a Russian learning app built around a deliberately small habit: one useful word, a short review, and optional reading. If I used notifications to manufacture urgency every few hours, the messaging system would undermine the product it was supposed to support.
So the retention question became:
Can Slovo identify a useful unfinished memory task, invite the learner back at a sensible time, and stop immediately when the task is complete?
I call the first OneSignal experiment Memory Rescue.
This article describes the implementation and campaign design. At the time of writing, the production result is still [NOT YET MEASURED]. I am separating architecture from outcome because an integrated SDK is not evidence that a campaign works.
Slovo stores learning progress locally. It does not need to send a person’s current Russian word or private content to build a useful messaging segment.
Instead, the app publishes a narrow set of state tags:
|
State |
Example tags |
|---|---|
|
Learning plan |
|
|
Habit |
|
|
Memory queue |
|
|
Today |
|
|
Explicit preferences |
|
|
Messaging lifecycle |
|
No word text, email address, or account content is included in these tags.
The app updates them whenever learning state is persisted:
let tags = [
"learning_level": settings.learningLevel,
"streak_days": String(streak),
"review_due_count": String(dueReviewCount),
"daily_complete": isDailyGoalComplete ? "true" : "false",
"streak_at_risk": isStreakAtRisk ? "true" : "false"
]
OneSignalManager.shared.setTags(tags)
The point is not to collect every available signal. It is to publish enough state to decide whether a message has a useful destination.
The Memory Rescue segment begins with behavior, not prose.
A learner is eligible when:
The Journey then branches on review_due_count.
If reviews are due, the message can say:
Your memory has {{review_due_count}} words ready. A two-minute recall now makes them stick.
The destination is slovo://review.
If no review is due, the message points to today’s word instead:
A small Russian moment is ready. Meet today’s word.
The destination is slovo://today.
This distinction matters. “Come back to the app” is not a useful call to action. “These words are ready for recall” is.
Slovo’s OneSignal click listener reads a launch URL or a route value from notification data and posts it into the app’s navigation layer.
Supported routes include:
slovo://todayslovo://reviewslovo://review?word=42slovo://progressThe specific-word route lets a campaign or local reminder prioritize one review item rather than dropping the learner at a generic dashboard.
Deep links are tested across warm launches, cold SwiftUI URL launches, remote OneSignal clicks, and local notification taps. A perfect message that lands on the wrong screen is still a failed experience.
The Journey should exit immediately when:
daily_complete becomes true; orstreak_saved, practice_completed, or review_answered.The app records those events as tags and can trigger a small OneSignal in-app message for moments such as sprint completion.
This prevents the classic failure where someone finishes a task and receives a reminder to do it ten minutes later.
I am also capping the Journey at no more than two pushes per day and three per week, with a seven-day re-entry delay. A second same-day message is reserved for an explicitly enabled streak rescue and only when a real streak is at risk.
Slovo’s integration includes:
The Live Activity shows completed/total reviews and the current word on the Lock Screen and Dynamic Island. It is useful during an active sprint, while push messaging is useful between sessions. They are different retention surfaces sharing the same purpose: reduce the cost of resuming the next action.
If the campaign launches and seven-day retention rises, that does not prove the message caused the rise. The most motivated learners may be the ones eligible for reminders in the first place.
The initial plan reserves a 10% holdout.
The primary metric is seven-day retained learners. Secondary metrics are:
The opt-out rate belongs beside the success metrics. A campaign that creates short-term opens by teaching users to disable notifications is not a retention win.
Memory Rescue should change if:
Possible responses include reducing frequency, removing the second message, narrowing eligibility, or letting the widget carry more of the reminder burden.
That last possibility is important. Push is not automatically the right channel. Slovo already has Home and Lock Screen widgets. The best notification strategy may be sending fewer notifications because passive surfaces are doing their job.
Before calling this campaign complete, I will capture:
The first result may be weak. That would still be useful. A documented retention experiment is more valuable than a polished diagram presented as a success.
My goal with OneSignal is not to make Slovo louder. It is to make the next memory action arrive with better timing—and to remain quiet when there is nothing useful to say.