Repository navigation
Choose the sync identifier for each new carb entry - #2587
Merged
Merged
Conversation
CarbStore.addCarbEntry now takes the entry's identity from the caller (LoopKit/LoopKit#654), so each caller decides when a save is a retry of the same entry. - Bolus entry screen: one identifier per screen, so saving again after a failed bolus does not add the carbs twice. - Watch carb and bolus flow: one identifier per carb entry under consideration, sent in SetBolusUserInfo ("cs"). A retry after a lost reply reuses it; the phone stores the carbs once. Messages from watch apps without the field get a fresh identifier, as before. - Simple bolus calculator and remote carb commands: a fresh identifier per save, as before. Remote commands carry their own identity, but the services delegate does not pass it through yet.
A watch app that predates the identifier would get a fresh one per message, so a retry after a lost reply would add the carbs twice. Reject the whole message instead, before anything is stored or delivered; the watch shows its existing bolus failure, as for an expired recommendation.
Follows LoopKit/LoopKit#654, where NewCarbEntry now carries its sync identifier and edits use CarbEntryUpdate. The bolus screens take a CarbEntryChange, either a new entry or an edit of a stored one, in place of the nullable new-entry and original-entry pair, and saving switches on it. The carb entry screen chooses one identifier per screen, so saving again after a failed bolus stores the carbs once. The watch puts the identifier in the entry it sends, replacing the separate cs key. SetBolusUserInfo and GetBolusRecommendationUserInfo now refuse a message whose carb entry doesn't decode. Without that, an older watch app's carbs would decode as no carbs and its bolus would go ahead without them; now nothing is stored or delivered, and the watch shows its bolus failure.
ps2
marked this pull request as ready for review
October 19, 2026 12:49
ps2
added a commit
to LoopKit/LoopWorkspace
that referenced
this pull request
Oct 19, 2026
Loop: issue reports to the LoopKit developers (LoopKit/Loop#2585), even alarm loudness (LoopKit/Loop#2589), stop AlarmKit alarms after a relaunch (LoopKit/Loop#2590), alarms play through silent mode (LoopKit/Loop#2591), carb entry sync identifier (LoopKit/Loop#2587). LoopKit: watch glucose duplicate crash (LoopKit/LoopKit#655), chart back-gesture (LoopKit/LoopKit#656, LoopKit/LoopKit#658), iOS 17.6 and watchOS 10.6 (LoopKit/LoopKit#659), previous pump's reservoir values (LoopKit/LoopKit#657), carb entry sync identifier (LoopKit/LoopKit#654). LibreLoop: not-an-Abbott-product notice (LoopKit/LibreLoop#25), iOS 17.6 (LoopKit/LibreLoop#26), backfilled readings in Recent Readings (LoopKit/LibreLoop#27). LibreTransmitter: forward the newest trend reading (LoopKit/LibreTransmitter#58). EversenseKit and MixpanelService: iOS 17.6 (LoopKit/EversenseKit#7, LoopKit/MixpanelService#9).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requires LoopKit/LoopKit#654, where a
NewCarbEntrycarries its own sync identifier, so that a retried save is stored once, and edits useCarbEntryUpdate.Each place that creates a new entry now chooses its identity:
Edits
The bolus screens took a nullable new entry plus a nullable original entry. They now take a
CarbEntryChange, which is either.add(NewCarbEntry)or.edit(StoredCarbEntry, CarbEntryUpdate), and saving callsaddCarbEntryorreplaceCarbEntryto match.recommendManualBolusandgeneratePredictiontake the same value.Older watch apps
SetBolusUserInfoandGetBolusRecommendationUserInfonow refuse a message whose carb entry doesn't decode. Without that, an older watch app's entry would decode as no carbs, and its bolus would go ahead without them.Not covered
Remote commands carry their own identity, but
ServicesManager.deliverRemoteCarbsdoesn't receive it yet; passing it through needs a LoopKit delegate change and is left for a follow-up.Testing
LoopTests: 333 pass on the iOS simulator against CarbStore: carry the sync identifier on new carb entries LoopKit#654. New tests cover saving a new entry from the bolus screen, a watch message without carbs, and a watch carb entry without an identifier being refused. The edit-path tests now check thatreplaceCarbEntryis called.