Custom validation messages w. Svelte

Example.svelte

<script lang="ts">
let control: HTMLInputElement
function validate() {
    if (control.validity.valueMissing) {
        control.setCustomValidity('Please provide a date of birth.')
    }
}
<script>
<input
  type="date"
  bind:this="{control}"
  required
  on:invalid="{validate}"
  on:change="{validate}"
  on:input="{validate}"
  title="A required input" />
<style>
  *:required::after {
    font-size: 125%;
    vertical-align: top;
    content: '*';
    color: red;
  }
</style>

Result

Testing SwiftUI Tables

I maintain a macOS SwiftUI app whose user interface contains a Table, one with a bound sortOrder.

The app's Xcode project contains UI tests that exercise the sorting logic, by clicking on the column headers. These tests are really fragile. Odds are good that any new release of macOS, or Xcode, or SwiftUI, will break them.

I'm not sure why they're so fragile. I suspect the way SwiftUI generates the underlying view hierarchy for a Table may still be in flux.

In any case, here is what I'm currently using to click on the column headers of a SwiftUI Table. This is for macOS 13.1, Xcode 14.2, Swift 5.7, SwiftUI 4.2.11.

    private func clickTableColumnHeaders(tableEl: XCUIElement) {
        for column in tableEl.tableColumns.allElementsBoundByIndex {
            let height = column.frame.height
            // Assume the column header lies above the column.
            let y = CGFloat(-10.0)
            let offset = CGVector(dx: 0.5, dy: y / height)
            let coords = column.coordinate(withNormalizedOffset: offset)
            // Click twice to exercise both sort orders.
            coords.click()
            coords.click()
        }
    }

Svelte's Take on ObservableObject

SwiftUI's ObservableObject and @Published make it easy to group related properties into a single class, and to react to changes of individual properties.

I recently complained to my friend, Bobi, that Svelte seemed lacking in this regard. Its tutorials always show components whose exportable state is defined by separate, top-level variable declarations.

    let count = 0;

    $: if (count >= 10) {
        alert('count is dangerously high!');
        ...

She set me straight: if you want to group related, observable properties, just use a writable store whose value is an Object (or if you prefer, a class instance). Whenever any property is changed, interested parties react automatically.

Read more…

macOS, Xcode, Ventura: When CloudKit Stops Syncing

(This is for future reference, when this sort of problem arises again.)

Last spring I started working on a pair (macOS, iOS) of personal utility applications. They relied on CloudKit storage. For months they worked well together. Then, as soon as I updated to macOS 13 Ventura, they stopped syncing.

Read more…

Git Default Branches: from master to main

Short Form

$ cd old_repository
$ git branch -m master main
$ git push -u origin main

$ ssh my_hosting_provider
my_hosting_provider$ cd code_repos/my_bare_repo.git
my_hosting_provider$ git symbolic-ref HEAD refs/heads/main

my_hosting_provider$ exit
$ git push origin --delete master

Read more…