Skip to content

Dev - #3

Open
ruess wants to merge 1953 commits into
ruess:devfrom
LoopKit:dev
Open

Dev#3
ruess wants to merge 1953 commits into
ruess:devfrom
LoopKit:dev

Conversation

@ruess

@ruess ruess commented Mar 8, 2017

Copy link
Copy Markdown
Owner

Merge latest updates into Dev branch of my repository

Camji55 and others added 29 commits June 20, 2023 09:55
* Add Dosing Strategy: automaticBolusSlidingScale

* Reverse order of two new constants

* revert to dev for dosing strategy selection

* revert to dev for dosing strategy selection

* Rename to effectiveBolusApplicationFactor, change to flag inside existing automaticBolus case

* Add applyLinearRamp slider to Dosing Strategy

* Update constants

* Modify explanation seen by user

* missed one phrase

* Update explanation seen by user, modify font

* Enable swapping of original and replacment protocols, minimize LoopKit changes

* Restore to dev branch version prior to pr1988_update merge

* Restore to dev branch version prior to update for PR 1988

* Updates per requested changes for Loop PR 1988

* Renaming, adjusting views, logging

* Wording change

* Logging error fixed

* dead code

* missed rename

* dark mode fix

* Updated algorithm experiments view and glucose based partial application view

* Put algorithm experiments behind feature flag

---------

Co-authored-by: Jonas Björkert <jonas@bjorkert.se>
Co-authored-by: Pete Schwamb <pete@schwamb.net>
…#2008)

* sign

* add irc to settings

* rc selection view

* rc selection in settings

* rc selection in data manager

* rc subtitle test

* add irc file

* enable irc

* correct report of discrepancies

* watch updates

* sign

* merge fixes

* clean SettingsView

* refactor enabled RC algo

* fix IRC description

* update RC algo upon settings change

* default IRC

* fix rebase to Loop dev

* Restore automatic signing

* Isolation of code and moved settings to Experimental Section

* Removed unnecessary xcscheme files

* moved up algorithmExperimentsSection

* copy paste error

* dark mode fix

* dark mode fix

* make consistent with dev updates

* Glucose Based Partial Application Factor (#1988)

* Add Dosing Strategy: automaticBolusSlidingScale

* Reverse order of two new constants

* revert to dev for dosing strategy selection

* revert to dev for dosing strategy selection

* Rename to effectiveBolusApplicationFactor, change to flag inside existing automaticBolus case

* Add applyLinearRamp slider to Dosing Strategy

* Update constants

* Modify explanation seen by user

* missed one phrase

* Update explanation seen by user, modify font

* Enable swapping of original and replacment protocols, minimize LoopKit changes

* Restore to dev branch version prior to pr1988_update merge

* Restore to dev branch version prior to update for PR 1988

* Updates per requested changes for Loop PR 1988

* Renaming, adjusting views, logging

* Wording change

* Logging error fixed

* dead code

* missed rename

* dark mode fix

* Updated algorithm experiments view and glucose based partial application view

* Put algorithm experiments behind feature flag

---------

Co-authored-by: Jonas Björkert <jonas@bjorkert.se>
Co-authored-by: Pete Schwamb <pete@schwamb.net>

* Wording tweak

* Font adjustments

* Change settings.enabledRetrospectiveCorrectionAlgorithm back to var

* Reorg some files

---------

Co-authored-by: @dm61 <maksimov@colorado.edu>
Co-authored-by: Jonas Björkert <jonas@bjorkert.se>
Co-authored-by: Jonas Björkert <bjorkert@me.com>
Co-authored-by: Pete Schwamb <pete@schwamb.net>
* evaluate state of irc

* rename variables

---------

Co-authored-by: marionbarker <marionbarker@earthlink.net>
* Remote handling rearchitecture

* Move remote background handling to ServicesManager.
Use notification to detect loop completion.
Move handleRemoteNotification to ServicesManager

* Add delegate for ServicesManager

* Remove remote details from DeviceDataManager

* Remove remote terms from ServicesManagerDelegate api

* Respond only to loopFinished notifications

* Remove unused method

* Rename method

* Update names

* Update names

* Remove more remote references in DeviceDataManager

* Remove Remote 2.0 parts

* Update enact override method name

* Move validation to ServicesManager.
Move ServiceManager delegation to LoopDataManager

* Move bolus validation to ServicesManager
loopkitdev and others added 30 commits July 20, 2026 13:18
getGlucoseSample() and getInsulinOnBoard() bridged async work to sync via
DispatchGroup.wait(timeout: .distantFuture). Both run from update(), which
executes on a Swift Concurrency cooperative-pool thread. Blocking that thread
violates the pool's forward-progress guarantee: the pool is sized to the core
count, so repeated Live Activity updates park every cooperative thread on the
wait and deadlock the whole concurrency runtime (Loop stops looping).

Observed on device: all cooperative-pool threads stuck in
getGlucoseSample -> dispatch_group_wait, with the Nightscout upload queues
blocked behind them.

Make both methods async and suspend via withCheckedContinuation instead of
blocking. getBottomRow() becomes async and iterates so the IOB query stays
lazy (issued only for the .iob row). No behavior change beyond not blocking.

Co-authored-by: Pete Schwamb <pete@schwamb.net>
Send the pump a PumpHeartbeatRequest (last CGM reading date + expected reading
interval) when it must provide the BLE heartbeat, or nil when the CGM wakes the
app itself, via the setBLEHeartbeatRequest API. The last-reading time is
refreshed after every CGM reading (processCGMReadingResult already calls
updatePumpManagerBLEHeartbeatPreference), so the pump's heartbeat cadence tracks
the actual reading schedule.

Requires the LoopKit setBLEHeartbeatRequest API on dev (LoopKit dev backport).
…beat-dev

Wire pump BLE heartbeat to the CGM reading schedule (dev backport)
bump WATCHOS_DEPLOYMENT_TARGET to 9.0 to match LoopKit
* toolbar fix

* toolbar fix

* toolbar fix

* Liquid Glass Bug Fixes (Pt. 1)

* Fix settings popup after dismissal

* Fix settings popup after dismissal
* xcode 27 building

* xcode 27 building

* xcode 27 building

* xcode 27 building

* Rename for better understanding

* Rename for better understanding
…2504)

* Even out and space the status screen toolbar icons

On iOS 26 the five toolbar items share one Liquid Glass background with no
spacing between them. Any space item inserted between them splits that
shared background into separate pills, so the gaps here are transparent
padding baked into each rendered icon instead, which widens the spacing
while leaving the single pill intact.

Sizing normalizes on each icon's visible artwork rather than its canvas.
The stock assets pad themselves by very different amounts -- bolus has
essentially none, carbs has ~3.7pt top and bottom, and settings is a 25x25
gear centered on a 25x40 canvas -- so matching canvas sizes leaves the
glyphs visibly uneven and gives settings a noticeably taller pill. The ink
bounds were measured by rasterizing the assets at 600dpi and taking the
alpha bounding box; artwork is centered in every one to within 0.6pt, so
scaling alone aligns them.

Also records the pre-meal item's index at setup instead of hardcoding it
per OS version, since the two layouts place it differently.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019hVEziK3QFghqmf2Hq4YAw

* Measure icon ink at runtime and clear the 44pt tap target

Two follow-ups to the icon sizing in this branch.

Replace the ToolbarLayout.Ink table with an alpha-channel scan of each
image, so toolbarIcon() no longer takes an ink: argument and the five
measured constants go away. Same result, but it cannot go stale if an
asset is redrawn. Measuring also yields the ink's origin, so the icon is
centered on its artwork rather than on its canvas -- these assets are
centered to within 0.6pt, but the code no longer depends on that.

Raise iconVerticalMargin from 4 to 7 so each rendered canvas is 44pt
tall. The horizontal padding already put every item past 44pt wide, but
height was inkHeight + 8 = 38pt, under the HIG minimum, and a small tap
target is part of what people are reporting. Checked in portrait and
landscape on an iPhone 16 Pro.

* Normalize the toolbar icon assets and drop the sizing code

Put all seven toolbar icon assets on a common 40x40pt canvas with the
artwork 30pt tall, so nothing in code needs to know how each asset is
padded. The PDFs stay vector: each page is re-placed with a scale and
translate through CoreGraphics, not rasterized. The settings gear is the
one PNG and is upscaled 1.2x from its @3x source; its compact-height
variant is dropped so landscape loads the same asset as portrait.

The two selected states are inverted badges, a plate filling the canvas
with the glyph knocked out, not line art. Their alpha bounds are the
plate, so any scheme that sizes on ink gets them wrong: sizing on the
partner's ink (the constants table) grew the pre-meal plate to 40pt on a
38pt item and clipped its corners; sizing on their own ink (the runtime
scan) shrank the glyph 20-27% when toggled on. Each badge now uses its
unselected partner's transform, so toggling swaps in place with the
plate at its natural size.

With the assets normalized, toolbarIcon() only centers the image on the
item canvas: 44pt for the minimum tap target, plus horizontal room
between items since on iOS 26 a space item would split the shared
Liquid Glass background. ToolbarLayout.Ink, inkBounds(), inkHeight and
the padding constants are gone.

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Pete Schwamb <pete@schwamb.net>
On iOS 27 the five toolbar items no longer fit narrower phones in
portrait and UIKit collapses the tail into an overflow menu. Four of
the five were UIBarButtonItem(customView:), which has no title, image
or action for the menu to show, so the menu was empty and Settings
was unreachable without rotating (#2513). The 60x44pt canvases each
icon was padded to (#2504) also made the bar wider than it needed to
be.

Make all five plain UIBarButtonItems with a title, image and action.
UIKit now provides the tap target, spacing and a working overflow
entry for each, so the padding helper, the custom UIButtons and the
index bookkeeping for swapping the pre-meal item go away; the toggle
items are updated in place.
…2523)

* Updated translations from lokalise on Thu Sep 17 08:17:21 PDT 2026

* do not change WatchApp.xcscheme, Xcode 27 will just change it back
…2524)

An app linked against the iOS 27 SDK gets wider padding around each
bar button item on iOS 27. Five items then overflow on 375pt phones
(iPhone SE 3rd gen, iPhone 12 mini), leaving three in the bar and the
rest behind the overflow menu. The same build linked against SDK 26.5
fits, which is why browser builds (Xcode 26.5) were unaffected and
local Xcode 27 builds were not.

Remove the standard padding on the five items, which brings them back
within 375pt, and give Settings high visibility priority so it is the
last item to overflow rather than the first. Both properties are new in
SDK 27, so the block is compiled only with Swift 6.4 (Xcode 27); an
SDK 26.5 build does not need it.

Verified on iPhone SE (3rd generation) and iPhone 12 mini, iOS 27.0,
built with Xcode 27: all five items fit. iOS 26.5 is unchanged.
Tapping "I'm a tester" records the date; the warning is skipped for
seven days after that. "Switch to main" does not record it, so it
shows again on the next launch.
* Don't ask to confirm a Loop reset before launch has completed

resumeLaunch() called askUserToConfirmLoopReset() unconditionally, but
resetLoopManager is only created in launchManagers(). When the app is
launched before the device has been unlocked after a reboot (a Bluetooth
state-restoration launch), checkProtectedDataAvailable() defers the
launch and the call traps on the nil manager:

  LoopAppManager.askUserToConfirmLoopReset() + 164
  LoopAppManager.resumeLaunch() + 260
  LoopAppManager.launch() + 412
  SceneDelegate.scene(_:willConnectTo:options:)

with wasUnlockedSinceBoot=0 and uptime 19s. Loop then stays dead until
the user opens it. Only ask once the launch has completed; every
re-entry into resumeLaunch() ends here, so the prompt is not lost.

* Hold an early APNs registration result until SettingsManager exists

initialize() registers for remote notifications before the launch is
gated on protected data, so the token can arrive while the launch is
still deferred and settingsManager is nil. Keep the result and deliver
it once launchManagers() has created the manager.
The one-second waits in LoopDataManagerDosingTests expired on CircleCI's
simulator, so two tests asserted against a manager that was still
working and the test host then crashed with an index out of range. A
longer timeout costs nothing when the tests pass.
Backport of #2574, #2578 and #2582
from next-dev.

- Replace the per-cycle "Loop success", "Loop error" and "CGM Fetch"
  events with one "Daily summary" per local day: loop success count and
  mean/max duration, loop error counts by issue id, the count of stored
  CGM readings, the day's UTC offset, and the settings state (closed
  loop, dosing strategy, integral retrospective correction, glucose based
  partial application). Running totals are kept in UserDefaults and the
  summary is sent on the first loop or CGM reading of the next day.
- Send that settings state as user properties at launch and whenever it
  changes, with "Closed loop enabled change", "Dosing strategy change"
  and "Algorithm experiment change" events. Also send Pump Type and CGM
  Type at launch, and set them to "None" when the device is removed.
- Send Pump Model and CGM Model user properties from the managers'
  HKDevice.model at setup and launch, and when a status update reports a
  different model.
- Stop sending health data: drop bolus units and carb grams, and send
  only the kind of override, and its duration, not preset names, targets
  or sensitivity.
- Send "Override Ended" when a preset is deactivated and "Settings
  Screen" when Settings opens.
- Carb and bolus events from the phone are now in session; from the
  watch and remote commands they stay out of session.
- Replace "Alert Issued" with "Alert Displayed": immediate alerts when
  issued, delayed and repeating alerts after a loop once they have come
  due without being retracted, and loop-not-running notifications when
  Loop infers their delivery.

dev's glucose samples don't record backfill, so the summary counts CGM
readings but has no backfill counts. The summary and state are updated
on the main queue, since dev reports loops and readings from other
queues.
* Require iOS 17.6

The project-level 15.1 setting overrode Loop.xcconfig, so the app still
targeted iOS 15.1. Remove it and raise Loop.xcconfig to 17.6, which
matches next-dev and the plugins that already require it.

* Submit issue reports to the LoopKit developers

Backport of #2585 from next-dev. Settings > Support > Report
Issue now opens one screen where the person either submits a report to
ingest.loopkit.org/v1/issues or exports Loop's diagnostic report locally,
which opens the existing issue report screen.

A submitted report has a description, optional title and screenshots.
It is anonymous unless the person fills in a name, email, Zulip or GitHub
contact, and the analytics device ID is never sent. Build and device
details (version, build, branch, revisions, device model, OS, pump and
CGM model) are listed on the screen and sent with every report. Loop's
diagnostic report is attached as text by default; the toggle says it
contains health data. Photos other than PNG are converted to JPEG.

dev has no build customizations list, so that context key is left out.
The diagnostic report and the pump and CGM models come from the
settings delegate, since dev's settings view model has no device
manager.

* Include build customizations in issue reports

Backport of #2577 from next-dev. capture-build-details.sh
records each *.loopcustomization file that the LoopWorkspace
customization script adds, the diagnostic report lists them, and an
issue report sends them as "customizations" with the other build details.
testRescheduleMutedLoopNotLoopingAlerts failed now and then on the first
run after a simulator had been idle. Changing the muter reschedules the
loop-not-running notifications from ExtensionDataManager.lastLoopCompleted,
which the host app refreshes only after launch; a value more than 20
minutes old schedules nothing, leaving the unmuted notifications from
loopDidComplete in place. Earlier runs also leave a 4-hour mute in
UserDefaults, which hides the problem until it expires.

The test now sets the last loop date it reschedules from, and reads the
pending notifications until the muted versions replace the others, for
up to 5 seconds, instead of reading them once.
* Leave the Report a Problem options to support plugins

Support had Report Issue, Submit Bug Report (added by LoopSupport) and
Export Critical Event Logs next to each other. The ways to report a
problem now belong to support plugins; DIY Loop's live in LoopSupport
behind a single Report a Problem row.

Loop's report form, submitter and local export screen move to
LoopSupport, and Loop provides its critical event log export through
SupportUIDelegate.criticalEventLogExportView().

* update string catalog

---------

Co-authored-by: marionbarker <marionbarker@earthlink.net>
Replaces the original Loop 1/2-era screenshots with simulator captures of
the current dev app: status screen, carb entry, meal bolus, custom presets,
Lock Screen Live Activity, the CGM picker, and the Apple Watch app. Shows a
rendered app icon at a fixed size, describes the main features and
supported devices, links LoopWorkspace, and drops the dead Travis badge.
Refresh the README with dev screenshots and features
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.