Compare commits

..
572 Commits
Author SHA1 Message Date
semantic-release-bot dc40fa43bc chore(release): 100.2.1 [skip ci]
## [100.2.1](https://github.com/KofTwentyTwo/CommandTabFree/compare/v100.2.0...v100.2.1) (2026-06-16)
2026-06-16 21:21:18 +00:00
james.maes 2ae7ded357 docs: record auto-update live, cask v100.2.0, release-gate decouple
Reflect v100.2.0 (auto-update via the GitHub Pages feed), the Homebrew cask bump, and the will-release gating that lets non-release pushes build and test without cutting a release.
2026-06-16 16:16:42 -05:00
james.maes dd15f22031 ci: gate release apparatus on semantic-release will-release decision
determine_next_version.sh writes an empty VERSION.txt when no commit since the last tag is release-worthy; gate cert-import/sign-build/notarize/appcast/release (and version injection) on that, so non-release pushes build+test without cutting a release or needing [skip ci].
2026-06-16 16:11:32 -05:00
semantic-release-bot 4ecfc4606f chore(release): 100.2.0 [skip ci]
# [100.2.0](https://github.com/KofTwentyTwo/CommandTabFree/compare/v100.1.0...v100.2.0) (2026-06-16)

### Features

* **updates:** enable Sparkle auto-update via GitHub Pages appcast ([45457cb](https://github.com/KofTwentyTwo/CommandTabFree/commit/45457cb))
2026-06-16 21:05:45 +00:00
james.maes 45457cb313 feat(updates): enable Sparkle auto-update via GitHub Pages appcast
Point DOMAIN at the repo's GitHub Pages site (serves the gh-pages appcast.xml), enable SUEnableAutomaticChecks, and remove the in-tree appcast skeleton (feed is published out-of-tree). Ships an auto-updating build.
2026-06-16 16:02:04 -05:00
james.maes 62e0226f01 ci: stop release tail clobbering .fork-sync-state cursor [skip ci]
Reset .fork-sync-state to v11.3.0 (last-synced upstream tag) and remove the release-tail step that overwrote it with the fork release tag, which would stall upstream-sync. Update SESSION-STATE/TODO/CICD-STATUS/README for the live signed+notarized v100.1.0 release.
2026-06-16 15:32:55 -05:00
github-actions[bot] 92254c021f chore(sync-state): advance to v100.1.0 [skip ci] 2026-06-16 19:48:28 +00:00
semantic-release-bot 0aca4d9400 chore(release): 100.1.0 [skip ci]
# [100.1.0](https://github.com/KofTwentyTwo/CommandTabFree/compare/v100.0.3...v100.1.0) (2026-06-16)

### Bug Fixes

* **ci:** build ad-hoc until Apple cert provisioned ([6070f0c](https://github.com/KofTwentyTwo/CommandTabFree/commit/6070f0c))
* **l10n:** regenerate base Localizable.strings from source ([d1e1b29](https://github.com/KofTwentyTwo/CommandTabFree/commit/d1e1b29))

### Features

* **release:** sign + notarize with fork Developer ID ([2f9fac1](https://github.com/KofTwentyTwo/CommandTabFree/commit/2f9fac1))
2026-06-16 19:48:19 +00:00
james.maes 2f9fac17b7 feat(release): sign + notarize with fork Developer ID
Set the fork Developer ID in config/local.xcconfig (Manual style + team), re-sign the vendored Sparkle helpers under it, and import the cert with an optional APPLE_P12_PASSWORD. Built, signed, and notarized (Accepted) locally before cutting.
2026-06-16 14:42:45 -05:00
james.maes 4a007e88c9 docs: add owner-gated TODO; tidy SESSION-STATE
Capture the owner-gated remaining work (publishing pipeline blockers) in docs/TODO.md; make SESSION-STATE HEAD reference hash-stable.
2026-06-16 12:55:22 -05:00
james.maes 885c52567d docs: record CI green + ad-hoc build fix + sync labels
Push CI is fully green (run 27634828800). NEXT SESSION blocker resolved; remaining work is owner-gated only.
2026-06-16 12:16:12 -05:00
james.maes 6070f0cbb9 fix(ci): build ad-hoc until Apple cert provisioned
Release build inherited upstream's Developer ID and failed on CI (exit 65, no cert). Build ad-hoc when the release gate is not signing-ready; build_app.sh now forwards xcodebuild overrides. Auto-switches to signed when the owner adds the cert.
2026-06-16 12:08:05 -05:00
james.maes d1e1b29623 fix(l10n): regenerate base Localizable.strings from source
Base strings drifted from source after the About redesign and brand sweep; regenerating via genstrings unblocks the generated-files CI gate. Dead paywall strings stay upstream-branded to keep merge surface minimal.
2026-06-15 15:22:49 -05:00
james.maes 2588101096 docs: correct CI/CD status + add NEXT SESSION handoff 2026-06-15 15:07:12 -05:00
james.maes 6313c295f3 docs: record CI/CD wiring + Guard B fix (green on unblocked) 2026-06-15 14:55:24 -05:00
james.maes d3e7529d91 ci: fix Guard B to match shipped de-paywall patch (guard-false-else + depaywall marker) 2026-06-15 14:52:09 -05:00
james.maes 287c4a07c4 ci: gate release tail on owner secrets (push CI green until then); sign_update --ed-key-file; commitlint sync-merge ignores; drop upstream-only scripts 2026-06-15 14:45:14 -05:00
james.maes eb95ad2d52 docs(readme): note .dmg/.zip direct-download install option 2026-06-15 14:31:18 -05:00
james.maes b9e871f176 chore: repo renamed alt-tab-free → CommandTabFree (update URLs); drop JetBrains sponsor from README 2026-06-15 14:13:53 -05:00
james.maes 39f10cfba3 docs: mark ⌘⇥ app icon as final (owner-approved), drop real-artwork TODO 2026-06-15 14:05:16 -05:00
james.maes 5b590bd6e5 docs: README install section + mark §3.1 brand/l10n/icon items done 2026-06-15 14:00:35 -05:00
james.maes 0b6d389842 docs: bump SESSION-STATE to v100.0.3 (full l10n rebrand) 2026-06-15 13:44:18 -05:00
james.maes adcd7c5f93 l10n: rebrand AltTab→CommandTabFree across all language tables (attribution kept) 2026-06-15 13:13:16 -05:00
james.maes b2cad34a6a docs: bump SESSION-STATE to v100.0.2 (menu icon, About redesign, l10n tidy) 2026-06-15 13:08:42 -05:00
james.maes 76ef4e49a5 l10n: rebrand AltTab→CommandTabFree in base+en strings (attribution kept) 2026-06-15 12:52:50 -05:00
james.maes acef128bbd feat(about): KofTwentyTwo identity + AltTab attribution links; drop Support button 2026-06-15 12:43:11 -05:00
james.maes 7f2a483ad2 brand: menu bar icons → command-tab (⌘⇥) glyph, matching app icon 2026-06-15 12:16:32 -05:00
james.maes 0b021beda7 chore: gitignore vendor/*/build (Xcode per-package output) 2026-06-15 11:58:47 -05:00
james.maes 4c169ef3d7 docs: record v100.0.1 release, brew tap, Sparkle key wiring + build gotcha 2026-06-15 11:57:32 -05:00
james.maes c7d2d9681e feat(sparkle): wire fork EdDSA public key; disable auto-checks 2026-06-15 11:42:28 -05:00
james.maes edf499d19e docs: session-state handoff (depaywall-free) 2026-06-15 09:53:20 -05:00
james.maes 98a023aa03 brand: placeholder app icon (command-tab glyph) + fix scheme product name to CommandTabFree.app 2026-06-15 08:57:37 -05:00
james.maesandClaude Opus 4.8 f5f9034d41 brand: rename user-facing AltTab → CommandTabFree, update About dialog (upstream attribution preserved)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 08:55:39 -05:00
james.maes e2429096d7 build: default CURRENT_PROJECT_VERSION=0.0.0 for local builds (App.version crash) 2026-06-15 08:51:15 -05:00
james.maes 4d82a684f3 chore: set fork identity — CommandTabFree / com.koftwentytwo.commandtabfree (frozen) 2026-06-10 17:03:12 -05:00
james.maes 6795ff43fb docs: mark Test scheme GREEN — 16 legacy paywall tests resolved (1a914c88) 2026-06-10 13:57:20 -05:00
james.maes 1a914c88f5 test: skip legacy paywall-behaviour tests (depaywall) — Test scheme green, anti-relock guards still active 2026-06-10 13:55:21 -05:00
james.maes 5c57cc738b docs: execution status + owner publish checklist (Test scheme RED on 16 legacy paywall tests — flagged BLOCKING) 2026-06-10 13:43:53 -05:00
james.maes 3dde8a91b6 chore: identity overlay + sync/guard/release CI scaffolding (placeholders flagged for owner) 2026-06-10 13:38:09 -05:00
james.maesandClaude Opus 4.8 4506c53958 test: anti-relock guards (pro never locked, incl. post-trial-expiry)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 13:32:00 -05:00
james.maes f3d7685984 depaywall: neutralize license gate, cookie, telemetry, and activate handler (src/pro left intact) 2026-06-10 13:29:52 -05:00
james.maes e243fb4bff docs: audit + republish/maintained-fork plans 2026-06-10 13:27:36 -05:00
semantic-release-bot 9fadf36bf8 chore(release): 11.3.0 [skip ci]
# [11.3.0](https://github.com/lwouis/alt-tab-macos/compare/v11.2.0...v11.3.0) (2026-06-04)

### Features

* better support adobe apps (closes [#5707](https://github.com/lwouis/alt-tab-macos/issues/5707)) ([f3fe535](https://github.com/lwouis/alt-tab-macos/commit/f3fe535))
2026-06-04 20:33:23 +00:00
lwouis f3fe535acb feat: better support adobe apps (closes #5707) 2026-06-04 21:56:59 +02:00
semantic-release-bot 8124cf5496 chore(release): 11.2.0 [skip ci]
# [11.2.0](https://github.com/lwouis/alt-tab-macos/compare/v11.1.0...v11.2.0) (2026-06-04)

### Bug Fixes

* always persist menubar icon removal from dragging ([#5654](https://github.com/lwouis/alt-tab-macos/issues/5654)) ([a354fde](https://github.com/lwouis/alt-tab-macos/commit/a354fde))
* better handle some shortcut conflicts (related to 3059dc23) ([cddc89d](https://github.com/lwouis/alt-tab-macos/commit/cddc89d))
* command+tab would sometimes not bind correctly (closes [#5653](https://github.com/lwouis/alt-tab-macos/issues/5653)) ([c75aac5](https://github.com/lwouis/alt-tab-macos/commit/c75aac5))
* focus issues with show-main-window setting (closes [#5684](https://github.com/lwouis/alt-tab-macos/issues/5684)) ([0899f61](https://github.com/lwouis/alt-tab-macos/commit/0899f61))
* improve processing of accessibility events (closes [#5665](https://github.com/lwouis/alt-tab-macos/issues/5665)) ([e0b1778](https://github.com/lwouis/alt-tab-macos/commit/e0b1778))
* only show screen recording callout when it's needed (closes [#5623](https://github.com/lwouis/alt-tab-macos/issues/5623)) ([9a9994b](https://github.com/lwouis/alt-tab-macos/commit/9a9994b))
* preserve switcher selection across reorders (closes [#5665](https://github.com/lwouis/alt-tab-macos/issues/5665)) ([5bd746d](https://github.com/lwouis/alt-tab-macos/commit/5bd746d))
* settings window search and controls editor edge-cases ([c143ec2](https://github.com/lwouis/alt-tab-macos/commit/c143ec2))
* text shortcuts like cmd+a work in search mode (closes [#5675](https://github.com/lwouis/alt-tab-macos/issues/5675)) ([d483c5a](https://github.com/lwouis/alt-tab-macos/commit/d483c5a))
* very minor memory leak ([7d60d55](https://github.com/lwouis/alt-tab-macos/commit/7d60d55))

### Features

* do not repeat title if window title is app name (closes [#5672](https://github.com/lwouis/alt-tab-macos/issues/5672)) ([30eb5f2](https://github.com/lwouis/alt-tab-macos/commit/30eb5f2))

### Performance Improvements

* carry (pid, wid) in AX subscription refcon to skip identity calls ([a39816e](https://github.com/lwouis/alt-tab-macos/commit/a39816e))
* improve performance of the settings window ([3059dc2](https://github.com/lwouis/alt-tab-macos/commit/3059dc2))
2026-06-04 11:59:20 +00:00
lwouis cddc89dd21 fix: better handle some shortcut conflicts (related to 3059dc23) 2026-06-04 13:55:22 +02:00
lwouis 83b5ddc091 refactor: move debug-menu into qa-menu, and update it 2026-06-03 21:18:31 +02:00
lwouis 7d60d55395 fix: very minor memory leak 2026-06-03 21:17:45 +02:00
lwouis e0b1778db7 fix: improve processing of accessibility events (closes #5665) 2026-06-01 08:34:12 +02:00
lwouis 9a9994bf28 fix: only show screen recording callout when it's needed (closes #5623) 2026-06-01 08:34:12 +02:00
lwouis a39816e303 perf: carry (pid, wid) in AX subscription refcon to skip identity calls
AXObserverAddNotification's refcon was always nil. Bake the owning identity into it at subscribe time so the AX callback gets (pid, wid) for free, instead of an element.pid()/cgWindowId() round-trip per event. Window-level subscriptions carry a real wid; app-level subscriptions carry wid 0, so focus/main/created still resolve their per-event subject window from the element. Notably this gives a reliable wid for kAXUIElementDestroyed, which previously had to query an already-dead element.
2026-05-30 21:51:13 +02:00
lwouis c143ec2f0c fix: settings window search and controls editor edge-cases 2026-05-30 19:38:20 +02:00
lwouis 83f8ae18fa refactor: remove very minor leak or flagged-as-leak 2026-05-28 21:04:48 +02:00
lwouis f006b26931 refactor: improve specs/tests coverage 2026-05-28 19:28:49 +02:00
lwouis e4a306dc8c refactor: prevent appkit rare crashes due to in-flight tooltips 2026-05-28 14:11:14 +02:00
lwouis c75aac585a fix: command+tab would sometimes not bind correctly (closes #5653) 2026-05-28 14:00:57 +02:00
lwouis 60cca89bb8 refactor: add specs and coverage; move tests close to files 2026-05-28 14:00:57 +02:00
lwouis 0899f61654 fix: focus issues with show-main-window setting (closes #5684) 2026-05-28 13:56:51 +02:00
lwouis 3059dc2356 perf: improve performance of the settings window 2026-05-28 13:56:50 +02:00
lwouis 5bd746d342 fix: preserve switcher selection across reorders (closes #5665)
Async AX events (focused-window changed, app activated) can fire during
the switcher's show path and reorder Windows.list under the panel. The
old updateSelectedWindow short-circuited to the initial-pick path
whenever the lowest-lastFocusOrder window changed mid-show, throwing
away the user's selectedTarget and re-picking the default. Visible slot
swap plus highlight jump; if the user released keys early they landed
on the wrong window.

Extract a pure-function kernel (SelectionResolver) covering the full
selection state machine and replace updateSelectedWindow with a thin
snapshot/decide/apply wrapper. The actual fix is dropping the
focusedWindowChangedWhileShowing arm of shouldSelectFromScratch: the
list still reorders (Photoshop finishing launch is fresh state the
user wants reflected), but the existing target-by-id lookup re-resolves
the user's pick at its new index instead of being skipped.

28 new SelectionResolverTests lock down every selection path: initial
pick rules, target preservation across reorders (#5665 regressions),
target removal, search-mode flags, edge cases.

Also adds minimal Appearance and SettingsSearchIndex stubs to Mocks.swift
so the unit-test target builds. ProBadgeView and LightLabel referenced
those types without the underlying source being in the test target.
2026-05-28 13:56:50 +02:00
lwouis 9a47672920 refactor: log results of carbon shortcut apis (#5653) 2026-05-28 13:56:49 +02:00
lwouis a354fdecc8 fix: always persist menubar icon removal from dragging (#5654) 2026-05-28 13:56:49 +02:00
lwouis d483c5aa88 fix: text shortcuts like cmd+a work in search mode (closes #5675) 2026-05-28 13:56:48 +02:00
lwouis 30eb5f2116 feat: do not repeat title if window title is app name (closes #5672) 2026-05-28 13:56:48 +02:00
semantic-release-bot 14acc0ce7d chore(release): 11.1.0 [skip ci]
# [11.1.0](https://github.com/lwouis/alt-tab-macos/compare/v11.0.1...v11.1.0) (2026-05-25)

### Bug Fixes

* better handle electron apps hidden windows (closes [#5449](https://github.com/lwouis/alt-tab-macos/issues/5449)) ([0434679](https://github.com/lwouis/alt-tab-macos/commit/0434679))
* improve tab detection (closes [#5618](https://github.com/lwouis/alt-tab-macos/issues/5618)) ([a8098c3](https://github.com/lwouis/alt-tab-macos/commit/a8098c3))
* rare crash when assigning shortcuts with arrow keys ([4977808](https://github.com/lwouis/alt-tab-macos/commit/4977808))
* rare crash when capturing window thumbnails ([f4a54c8](https://github.com/lwouis/alt-tab-macos/commit/f4a54c8))
* very rare crash on quit ([007edc6](https://github.com/lwouis/alt-tab-macos/commit/007edc6))

### Features

* support setups with non latin keyboard layouts (closes [#5607](https://github.com/lwouis/alt-tab-macos/issues/5607)) ([f0e195d](https://github.com/lwouis/alt-tab-macos/commit/f0e195d))
2026-05-25 11:42:42 +00:00
lwouis 04346790b8 fix: better handle electron apps hidden windows (closes #5449) 2026-05-25 11:37:54 +02:00
lwouis f49250aa45 refactor: silence swiftui logs when debugging 2026-05-25 10:53:39 +02:00
lwouis a8098c39db fix: improve tab detection (closes #5618) 2026-05-25 10:36:56 +02:00
lwouis f0e195d0de feat: support setups with non latin keyboard layouts (closes #5607) 2026-05-25 09:41:46 +02:00
lwouis 49778089ea fix: rare crash when assigning shortcuts with arrow keys 2026-05-25 09:35:27 +02:00
lwouis f4a54c8f1b fix: rare crash when capturing window thumbnails 2026-05-24 22:00:29 +02:00
lwouis 007edc624e fix: very rare crash on quit 2026-05-24 21:14:39 +02:00
lwouis b6af54425e refactor: remove references to poeditor files we removed 2026-05-24 17:41:34 +02:00
semantic-release-bot 146e2aec46 chore(release): 11.0.1 [skip ci]
## [11.0.1](https://github.com/lwouis/alt-tab-macos/compare/v11.0.0...v11.0.1) (2026-05-22)

### Bug Fixes

* cmd key could be stuck after switching (closes [#5650](https://github.com/lwouis/alt-tab-macos/issues/5650)) ([3a48a13](https://github.com/lwouis/alt-tab-macos/commit/3a48a13))
2026-05-22 17:12:59 +00:00
lwouis 3a48a13cb5 fix: cmd key could be stuck after switching (closes #5650) 2026-05-22 18:53:59 +02:00
lwouis 910288d149 ci: update github actions versions 2026-05-21 10:44:20 +02:00
semantic-release-bot 1f2b5a513e chore(release): 11.0.0 [skip ci]
# [11.0.0](https://github.com/lwouis/alt-tab-macos/compare/v10.12.0...v11.0.0) (2026-05-21)

### Features

* introducing alt-tab pro! ([9147a4a](https://github.com/lwouis/alt-tab-macos/commit/9147a4a)), closes [#5450](https://github.com/lwouis/alt-tab-macos/issues/5450) [#5539](https://github.com/lwouis/alt-tab-macos/issues/5539) [#5627](https://github.com/lwouis/alt-tab-macos/issues/5627) [#5509](https://github.com/lwouis/alt-tab-macos/issues/5509) [#5492](https://github.com/lwouis/alt-tab-macos/issues/5492) [#5585](https://github.com/lwouis/alt-tab-macos/issues/5585) [#5488](https://github.com/lwouis/alt-tab-macos/issues/5488) [#5583](https://github.com/lwouis/alt-tab-macos/issues/5583) [#5482](https://github.com/lwouis/alt-tab-macos/issues/5482) [#5313](https://github.com/lwouis/alt-tab-macos/issues/5313)

### BREAKING CHANGES

* announcement: https://github.com/lwouis/alt-tab-macos/discussions/5533

* improved performance, especially switcher responsiveness
* reduced battery usage even more
2026-05-21 08:28:52 +00:00
lwouis 9147a4a864 feat: introducing alt-tab pro!
BREAKING CHANGE: announcement: https://github.com/lwouis/alt-tab-macos/discussions/5533

* improved performance, especially switcher responsiveness
* reduced battery usage even more
* reduced ram usage (closes #5450, closes #5539, closes #5627)
* reduced app size even more
* polished many aspects of the ui; align more with liquid glass
* better handle "ghost" windows (closes #5509)
* fix issue with wrong window order (closes #5492)
* escape closes the switcher on tahoe (closes #5585)
* improve search matches (closes #5488)
* localizations trimmed and reviewed entirely (closes #5583)
* highlight matching app icons when searching, in addition to text
* better settings import/export
* reworked "send feedback" experience
* reworked exceptions ui (closes #5482)
* per-shortcut settings (closes #5313)
* rework about window
2026-05-21 10:21:25 +02:00
semantic-release-bot 317a485bcb chore(release): 10.12.0 [skip ci]
# [10.12.0](https://github.com/lwouis/alt-tab-macos/compare/v10.11.0...v10.12.0) (2026-04-13)

### Features

* remove the need to add email in feedback form ([da9a46b](https://github.com/lwouis/alt-tab-macos/commit/da9a46b))
* show usage stats in the about-window ([9c5b963](https://github.com/lwouis/alt-tab-macos/commit/9c5b963))
2026-04-13 09:03:24 +00:00
lwouis 20caf75096 ci: move appcast from github raw to website 2026-04-13 10:57:52 +02:00
lwouis 873aabec72 docs: add terms and privacy policies on website 2026-04-13 10:53:25 +02:00
lwouis da9a46bf49 feat: remove the need to add email in feedback form 2026-04-13 10:53:25 +02:00
lwouis 9c5b9630e8 feat: show usage stats in the about-window 2026-04-13 10:31:08 +02:00
semantic-release-bot 49a41bd66d chore(release): 10.11.0 [skip ci]
# [10.11.0](https://github.com/lwouis/alt-tab-macos/compare/v10.10.1...v10.11.0) (2026-04-08)

### Features

* add local usage stats for curious users ([8e07d26](https://github.com/lwouis/alt-tab-macos/commit/8e07d26))
2026-04-08 20:11:45 +00:00
lwouis 8e07d261b9 feat: add local usage stats for curious users 2026-04-08 22:02:28 +02:00
semantic-release-bot d222dbbb10 chore(release): 10.10.1 [skip ci]
## [10.10.1](https://github.com/lwouis/alt-tab-macos/compare/v10.10.0...v10.10.1) (2026-04-05)

### Bug Fixes

* about-alttab window would crash when opened (closes [#5491](https://github.com/lwouis/alt-tab-macos/issues/5491)) ([d5152fb](https://github.com/lwouis/alt-tab-macos/commit/d5152fb))
* rare crash sometimes when opening the app twice quickly ([47e6cbd](https://github.com/lwouis/alt-tab-macos/commit/47e6cbd))
* rare crash when scrolling some settings window views ([317d2ff](https://github.com/lwouis/alt-tab-macos/commit/317d2ff))
2026-04-05 15:40:34 +00:00
lwouis 47e6cbd987 fix: rare crash sometimes when opening the app twice quickly 2026-04-05 17:33:12 +02:00
lwouis 317d2ff78a fix: rare crash when scrolling some settings window views 2026-04-05 17:22:40 +02:00
lwouis d5152fba44 fix: about-alttab window would crash when opened (closes #5491) 2026-04-05 08:49:28 +02:00
lwouis 90cdd3544a ci: fix changelog broken by sitemap 2026-04-04 21:42:38 +02:00
lwouis 13340d82f6 ci: remove _redirects on cloudflare 2026-04-04 21:38:11 +02:00
semantic-release-bot 69f67ffeeb chore(release): 10.10.0 [skip ci]
# [10.10.0](https://github.com/lwouis/alt-tab-macos/compare/v10.9.0...v10.10.0) (2026-04-04)

### Bug Fixes

* better handle bugged apps with hidden windows (closes [#5296](https://github.com/lwouis/alt-tab-macos/issues/5296)) ([ff1e923](https://github.com/lwouis/alt-tab-macos/commit/ff1e923))
* improve reliability after sleep/wake ([1ab419d](https://github.com/lwouis/alt-tab-macos/commit/1ab419d))
* show more apps when adding an exception (closes [#5463](https://github.com/lwouis/alt-tab-macos/issues/5463)) ([41d608e](https://github.com/lwouis/alt-tab-macos/commit/41d608e))

### Features

* better recognizes tabbed windows ([170bd67](https://github.com/lwouis/alt-tab-macos/commit/170bd67))
* improve localizations ([fe6e52d](https://github.com/lwouis/alt-tab-macos/commit/fe6e52d))
* improved detection of windows and apps ([7a2a548](https://github.com/lwouis/alt-tab-macos/commit/7a2a548))
* update localizations ([ecafbe7](https://github.com/lwouis/alt-tab-macos/commit/ecafbe7))

### Performance Improvements

* improve badges retrieval ([edbbf20](https://github.com/lwouis/alt-tab-macos/commit/edbbf20))
2026-04-04 19:30:53 +00:00
lwouis fe6e52d691 feat: improve localizations 2026-04-04 21:26:45 +02:00
lwouis 6c35e10a66 ci: generate sitemap 2026-04-04 16:22:47 +02:00
lwouis 18b523e458 ci: migrate from netlify to cloudflare 2026-04-04 15:36:46 +02:00
lwouis 41d608efda fix: show more apps when adding an exception (closes #5463) 2026-03-29 18:22:52 +02:00
lwouis f1c59a2748 refactor: small improvements to concurrency 2026-03-28 17:21:10 +01:00
lwouis 0e897b0678 refactor: program main-menu instead of .xib
avoids SDK logs
not sure if easier to maintain though
2026-03-28 12:07:17 +01:00
lwouis 7a2a5482ae feat: improved detection of windows and apps
* find more windows and apps (e.g. apps that take 30s to launch)
* keep windows and apps more up-to-date
* more efficient, uses fewer resources
2026-03-28 11:57:48 +01:00
lwouis 170bd673e0 feat: better recognizes tabbed windows 2026-03-28 11:57:48 +01:00
lwouis ff1e92303a fix: better handle bugged apps with hidden windows (closes #5296) 2026-03-28 11:57:48 +01:00
lwouis edbbf2082c perf: improve badges retrieval 2026-03-28 11:57:48 +01:00
lwouis 1ab419dd09 fix: improve reliability after sleep/wake 2026-03-28 11:57:48 +01:00
lwouis 6bd5f26e1c refactor: improve logs for application discrimination 2026-03-24 11:35:05 +01:00
lwouis ecafbe7212 feat: update localizations 2026-03-22 18:51:57 +01:00
semantic-release-bot 173950af08 chore(release): 10.9.0 [skip ci]
# [10.9.0](https://github.com/lwouis/alt-tab-macos/compare/v10.8.0...v10.9.0) (2026-03-22)

### Bug Fixes

* panel may re-center when searching ([a1f8b18](https://github.com/lwouis/alt-tab-macos/commit/a1f8b18))

### Features

* new setting to not capture windows in background (closes [#5337](https://github.com/lwouis/alt-tab-macos/issues/5337)) ([5ed6c1d](https://github.com/lwouis/alt-tab-macos/commit/5ed6c1d)), closes [#5371](https://github.com/lwouis/alt-tab-macos/issues/5371)
* show better ui when there are no window (closes [#283](https://github.com/lwouis/alt-tab-macos/issues/283)) ([9f3e20a](https://github.com/lwouis/alt-tab-macos/commit/9f3e20a))
* update fr/en localizations ([630527e](https://github.com/lwouis/alt-tab-macos/commit/630527e))
2026-03-22 16:29:10 +00:00
lwouis 5ed6c1d9ce feat: new setting to not capture windows in background (closes #5337)
Also closes #5371
2026-03-22 17:19:19 +01:00
lwouis 630527e0b7 feat: update fr/en localizations 2026-03-22 17:19:19 +01:00
lwouis a1f8b18888 fix: panel may re-center when searching 2026-03-22 17:19:18 +01:00
lwouis 9f3e20a826 feat: show better ui when there are no window (closes #283) 2026-03-22 17:19:18 +01:00
lwouis dbc77fe214 ci: release notes should interpret markdown (closes #597) 2026-03-22 17:19:17 +01:00
semantic-release-bot be2de1ab83 chore(release): 10.8.0 [skip ci]
# [10.8.0](https://github.com/lwouis/alt-tab-macos/compare/v10.7.0...v10.8.0) (2026-03-20)

### Bug Fixes

* allow quitting multiple apps in a row (follow-up on [#5421](https://github.com/lwouis/alt-tab-macos/issues/5421)) ([56c1927](https://github.com/lwouis/alt-tab-macos/commit/56c1927))
* apps with no open window might not show up (closes [#5424](https://github.com/lwouis/alt-tab-macos/issues/5424)) ([8962ad1](https://github.com/lwouis/alt-tab-macos/commit/8962ad1))
* avoid repeating shortcut that was released (closes [#5429](https://github.com/lwouis/alt-tab-macos/issues/5429)) ([3b1c7c7](https://github.com/lwouis/alt-tab-macos/commit/3b1c7c7))
* switcher might show empty on rare occasions (closes [#5432](https://github.com/lwouis/alt-tab-macos/issues/5432)) ([6105bb3](https://github.com/lwouis/alt-tab-macos/commit/6105bb3))
* window order in the switcher might be incorrect ([#5346](https://github.com/lwouis/alt-tab-macos/issues/5346)) ([545d81d](https://github.com/lwouis/alt-tab-macos/commit/545d81d))

### Features

* allow next-window shortcut without modifiers (closes [#5433](https://github.com/lwouis/alt-tab-macos/issues/5433)) ([15ede93](https://github.com/lwouis/alt-tab-macos/commit/15ede93))
* stabilize ui during search (closes [#5431](https://github.com/lwouis/alt-tab-macos/issues/5431)) ([7dd11cf](https://github.com/lwouis/alt-tab-macos/commit/7dd11cf))
2026-03-20 20:57:34 +00:00
lwouis 56c1927584 fix: allow quitting multiple apps in a row (follow-up on #5421) 2026-03-20 21:52:24 +01:00
lwouis 7dd11cff01 feat: stabilize ui during search (closes #5431) 2026-03-20 21:52:24 +01:00
lwouis 15ede93868 feat: allow next-window shortcut without modifiers (closes #5433) 2026-03-20 21:52:23 +01:00
lwouis 4502e8bd15 refactor: improve logging of window discriminator logic 2026-03-20 21:52:23 +01:00
lwouis 6105bb30ad fix: switcher might show empty on rare occasions (closes #5432) 2026-03-20 21:52:22 +01:00
lwouis 545d81d872 fix: window order in the switcher might be incorrect (#5346) 2026-03-20 21:52:22 +01:00
lwouis 3b1c7c76a9 fix: avoid repeating shortcut that was released (closes #5429) 2026-03-19 21:11:06 +01:00
lwouis 8962ad1a54 fix: apps with no open window might not show up (closes #5424) 2026-03-16 19:44:17 +01:00
semantic-release-bot 39b818de11 chore(release): 10.7.0 [skip ci]
# [10.7.0](https://github.com/lwouis/alt-tab-macos/compare/v10.6.0...v10.7.0) (2026-03-15)

### Bug Fixes

* allow quitting multiple apps in a row (closes [#5421](https://github.com/lwouis/alt-tab-macos/issues/5421)) ([de9aaa1](https://github.com/lwouis/alt-tab-macos/commit/de9aaa1))
* avoid memory usage growth over time (closes [#5138](https://github.com/lwouis/alt-tab-macos/issues/5138)) ([739649a](https://github.com/lwouis/alt-tab-macos/commit/739649a))
* edit shortcuts in settings window search bar on first launch ([2adf741](https://github.com/lwouis/alt-tab-macos/commit/2adf741))
* prevent sheets from messing up thumbnails order ([#5346](https://github.com/lwouis/alt-tab-macos/issues/5346)) ([b008d63](https://github.com/lwouis/alt-tab-macos/commit/b008d63))
* thumbnails might be shown too small ([57c95a6](https://github.com/lwouis/alt-tab-macos/commit/57c95a6))

### Features

* reduce memory usage by storing fewer app icons ([b21168a](https://github.com/lwouis/alt-tab-macos/commit/b21168a))
2026-03-15 14:29:13 +00:00
lwouis b008d63928 fix: prevent sheets from messing up thumbnails order (#5346) 2026-03-15 15:19:38 +01:00
lwouis de9aaa1fc1 fix: allow quitting multiple apps in a row (closes #5421) 2026-03-15 15:15:07 +01:00
lwouis 739649a749 fix: avoid memory usage growth over time (closes #5138) 2026-03-14 18:44:57 +01:00
lwouis 2adf741355 fix: edit shortcuts in settings window search bar on first launch 2026-03-13 10:46:37 +01:00
lwouis ec763814a9 refactor: reduce ram usage by early returning when not visible 2026-03-13 10:27:00 +01:00
lwouis b21168a033 feat: reduce memory usage by storing fewer app icons 2026-03-13 10:22:04 +01:00
lwouis cf8a41528d refactor: throttling was not actually working 2026-03-12 17:15:24 +01:00
lwouis 57c95a6e35 fix: thumbnails might be shown too small 2026-03-12 11:24:47 +01:00
semantic-release-bot 17615d00a9 chore(release): 10.6.0 [skip ci]
# [10.6.0](https://github.com/lwouis/alt-tab-macos/compare/v10.5.0...v10.6.0) (2026-03-10)

### Bug Fixes

* allow edit shortcuts in the search bar (closes [#5308](https://github.com/lwouis/alt-tab-macos/issues/5308)) ([35ddbe7](https://github.com/lwouis/alt-tab-macos/commit/35ddbe7))
* better handle context menu in search bar ([9aea8f6](https://github.com/lwouis/alt-tab-macos/commit/9aea8f6))
* key repeat in search mode ([fd4e373](https://github.com/lwouis/alt-tab-macos/commit/fd4e373))
* preview may not update its position (closes [#5396](https://github.com/lwouis/alt-tab-macos/issues/5396)) ([dbadb2b](https://github.com/lwouis/alt-tab-macos/commit/dbadb2b))
* right-click and middle-click outside panel ([9969a07](https://github.com/lwouis/alt-tab-macos/commit/9969a07))
* show preview window on first shortcut press (closes [#5385](https://github.com/lwouis/alt-tab-macos/issues/5385)) ([106f7c9](https://github.com/lwouis/alt-tab-macos/commit/106f7c9))
* trackpad scrolling shouldn't also scroll on background apps ([cacb789](https://github.com/lwouis/alt-tab-macos/commit/cacb789))

### Features

* scrolling the settings update the sidebar (closes [#5400](https://github.com/lwouis/alt-tab-macos/issues/5400)) ([3b831d4](https://github.com/lwouis/alt-tab-macos/commit/3b831d4))
2026-03-10 20:49:15 +00:00
lwouis 35ddbe72ed fix: allow edit shortcuts in the search bar (closes #5308) 2026-03-10 21:33:46 +01:00
lwouis fd4e3734e8 fix: key repeat in search mode 2026-03-10 21:33:46 +01:00
lwouis cacb7891e7 fix: trackpad scrolling shouldn't also scroll on background apps 2026-03-10 21:33:44 +01:00
lwouis 9969a07b22 fix: right-click and middle-click outside panel 2026-03-10 21:33:25 +01:00
lwouis 9aea8f62c9 fix: better handle context menu in search bar 2026-03-10 21:33:00 +01:00
lwouis 106f7c90f9 fix: show preview window on first shortcut press (closes #5385) 2026-03-09 23:14:38 +01:00
lwouis 3b831d4e59 feat: scrolling the settings update the sidebar (closes #5400) 2026-03-09 23:09:46 +01:00
lwouis dbadb2b4e5 fix: preview may not update its position (closes #5396) 2026-03-09 16:34:17 +01:00
semantic-release-bot 7d0eb278bf chore(release): 10.5.0 [skip ci]
# [10.5.0](https://github.com/lwouis/alt-tab-macos/compare/v10.4.0...v10.5.0) (2026-03-08)

### Bug Fixes

* input with ime better interacts with search (closes [#5377](https://github.com/lwouis/alt-tab-macos/issues/5377)) ([15caa33](https://github.com/lwouis/alt-tab-macos/commit/15caa33))

### Features

* improved search results ([0f8d6f1](https://github.com/lwouis/alt-tab-macos/commit/0f8d6f1))
* refinements on mouse hover and dragging ([#5350](https://github.com/lwouis/alt-tab-macos/issues/5350)) ([643cc80](https://github.com/lwouis/alt-tab-macos/commit/643cc80))
2026-03-08 17:56:44 +00:00
lwouis 0f8d6f140a feat: improved search results 2026-03-08 18:49:58 +01:00
lwouis 15caa33a60 fix: input with ime better interacts with search (closes #5377) 2026-03-08 18:49:57 +01:00
lwouis d905617248 refactor: add log for menubar visibility change 2026-03-05 15:25:01 +01:00
lwouis 643cc80ae0 feat: refinements on mouse hover and dragging (#5350) 2026-03-05 15:25:00 +01:00
semantic-release-bot a867171a45 chore(release): 10.4.0 [skip ci]
# [10.4.0](https://github.com/lwouis/alt-tab-macos/compare/v10.3.0...v10.4.0) (2026-03-04)

### Bug Fixes

* clicking tiles required to release precisely (closes [#5373](https://github.com/lwouis/alt-tab-macos/issues/5373)) ([2c6c9fb](https://github.com/lwouis/alt-tab-macos/commit/2c6c9fb))
* issues when using multiple keyboard languages (closes [#2125](https://github.com/lwouis/alt-tab-macos/issues/2125)) ([ea7284b](https://github.com/lwouis/alt-tab-macos/commit/ea7284b))
* switcher may show windows in the wrong order (closes [#5346](https://github.com/lwouis/alt-tab-macos/issues/5346)) ([a632e42](https://github.com/lwouis/alt-tab-macos/commit/a632e42))

### Features

* add kazakh and improve all localizations ([0ad389a](https://github.com/lwouis/alt-tab-macos/commit/0ad389a))
* improve drag-and-drop over alttab (closes [#5350](https://github.com/lwouis/alt-tab-macos/issues/5350)) ([a809ffa](https://github.com/lwouis/alt-tab-macos/commit/a809ffa))
2026-03-04 18:43:30 +00:00
lwouis 2c6c9fb2cc fix: clicking tiles required to release precisely (closes #5373) 2026-03-04 19:37:39 +01:00
lwouis 0ad389aa6f feat: add kazakh and improve all localizations 2026-03-04 19:01:28 +01:00
lwouis a632e42fbc fix: switcher may show windows in the wrong order (closes #5346) 2026-03-04 11:45:58 +01:00
lwouis a809ffad61 feat: improve drag-and-drop over alttab (closes #5350) 2026-03-01 19:26:28 +01:00
lwouis ea7284b387 fix: issues when using multiple keyboard languages (closes #2125) 2026-03-01 16:45:30 +01:00
lwouis 37ba9662f1 docs: simplify website introduction page 2026-02-24 21:26:27 +01:00
lwouis 1f340a3590 ci: netlify deploy broke after they updated their ubuntu vm
make jekyll build use ruby 3 and more recent bundler, so it works on more recent VMs
2026-02-24 21:21:56 +01:00
semantic-release-bot f7368f0dfe chore(release): 10.3.0 [skip ci]
# [10.3.0](https://github.com/lwouis/alt-tab-macos/compare/v10.2.0...v10.3.0) (2026-02-24)

### Bug Fixes

* avoid clipping long settings window buttons (closes [#5320](https://github.com/lwouis/alt-tab-macos/issues/5320)) ([402b6f6](https://github.com/lwouis/alt-tab-macos/commit/402b6f6))
* closing a window would remove the thumbnail (closes [#5324](https://github.com/lwouis/alt-tab-macos/issues/5324)) ([451bbbe](https://github.com/lwouis/alt-tab-macos/commit/451bbbe))
* fade-out speed could show wrong value in rare cases ([f5e81fe](https://github.com/lwouis/alt-tab-macos/commit/f5e81fe))
* improve settings window on macos 10.13 ([5ce48c1](https://github.com/lwouis/alt-tab-macos/commit/5ce48c1))
* mouse hover would sometimes disappear ([8c7263e](https://github.com/lwouis/alt-tab-macos/commit/8c7263e))

### Features

* add ur/mr localizations + update all localizations ([dc538dc](https://github.com/lwouis/alt-tab-macos/commit/dc538dc))
* consolidate settings (closes [#1732](https://github.com/lwouis/alt-tab-macos/issues/1732)) ([219098d](https://github.com/lwouis/alt-tab-macos/commit/219098d))
* reduce app disk size ([3c95c6c](https://github.com/lwouis/alt-tab-macos/commit/3c95c6c))
2026-02-24 19:55:27 +00:00
lwouis dc538dc994 feat: add ur/mr localizations + update all localizations 2026-02-24 20:48:29 +01:00
lwouis 9f563bcec2 docs: release notes had bright titles in dark mode 2026-02-24 20:48:29 +01:00
lwouis 1ff8c9c19a docs: migrate faq to github discussions
also closes #5339
2026-02-24 20:48:28 +01:00
lwouis 810b7116cd chore: refresh controls ui on dark/light mode change 2026-02-24 20:48:28 +01:00
lwouis 3fb66d412a chore: derisk event handling (#5336)
* .listenOnly means we don't block event processing
* using CGEvent directly means we don't need main-thread to convert to NSEvent
2026-02-24 20:48:27 +01:00
lwouis 741b074134 chore: multiple shortcuts could be selected if scrolling 2026-02-24 20:48:27 +01:00
lwouis c3ef4bc87c chore: logs in the debug tools were hard to read in dark mode 2026-02-24 20:48:26 +01:00
lwouis f5e81fe8cd fix: fade-out speed could show wrong value in rare cases 2026-02-24 20:48:26 +01:00
lwouis 3c95c6c276 feat: reduce app disk size 2026-02-24 20:48:26 +01:00
lwouis f54aca3fd9 refactor: reuse nested-scrolling logic across controls and blacklist 2026-02-24 20:48:25 +01:00
lwouis 7220643c82 refactor: make migration code simpler 2026-02-24 20:48:25 +01:00
lwouis ede879f3d6 refactor: make language preferences drier 2026-02-24 20:48:24 +01:00
lwouis 8c7263e8f1 fix: mouse hover would sometimes disappear 2026-02-24 20:48:24 +01:00
lwouis 402b6f6ff1 fix: avoid clipping long settings window buttons (closes #5320) 2026-02-24 20:48:23 +01:00
lwouis 451bbbe035 fix: closing a window would remove the thumbnail (closes #5324) 2026-02-24 20:48:23 +01:00
lwouis db34a7eb8f refactor: use static vars/funcs as much as possible 2026-02-24 20:48:22 +01:00
lwouis 5ce48c18e6 fix: improve settings window on macos 10.13 2026-02-24 18:42:22 +01:00
lwouis 219098d6a3 feat: consolidate settings (closes #1732) 2026-02-24 18:42:21 +01:00
semantic-release-bot 5f87336f3f chore(release): 10.2.0 [skip ci]
# [10.2.0](https://github.com/lwouis/alt-tab-macos/compare/v10.1.0...v10.2.0) (2026-02-19)

### Bug Fixes

* improve settings ui on macos 10.13 ([#5255](https://github.com/lwouis/alt-tab-macos/issues/5255)) ([75347ad](https://github.com/lwouis/alt-tab-macos/commit/75347ad))
* rare crash when a window was opened ([28c4b12](https://github.com/lwouis/alt-tab-macos/commit/28c4b12))
* small issues when mouse hover is set to select (closes [#5292](https://github.com/lwouis/alt-tab-macos/issues/5292)) ([b9e0344](https://github.com/lwouis/alt-tab-macos/commit/b9e0344))
* sometimes the active app was not up-to-date (closes [#5291](https://github.com/lwouis/alt-tab-macos/issues/5291)) ([ea51d57](https://github.com/lwouis/alt-tab-macos/commit/ea51d57))

### Features

* add burmese + update all localizations ([f5e1014](https://github.com/lwouis/alt-tab-macos/commit/f5e1014))
* add new setting for auto size (closes [#3669](https://github.com/lwouis/alt-tab-macos/issues/3669)) ([c51376f](https://github.com/lwouis/alt-tab-macos/commit/c51376f))
* add setting to blacklist window by title (closes [#5299](https://github.com/lwouis/alt-tab-macos/issues/5299)) ([35eae11](https://github.com/lwouis/alt-tab-macos/commit/35eae11))
* can add running apps into blacklist (closes [#5268](https://github.com/lwouis/alt-tab-macos/issues/5268)) ([d5d6996](https://github.com/lwouis/alt-tab-macos/commit/d5d6996))
* remember position/size of secondary windows (closes [#5305](https://github.com/lwouis/alt-tab-macos/issues/5305)) ([4b85fb8](https://github.com/lwouis/alt-tab-macos/commit/4b85fb8))
2026-02-19 22:42:05 +00:00
lwouis f5e1014bce feat: add burmese + update all localizations 2026-02-19 23:34:57 +01:00
lwouis 75347adc8d fix: improve settings ui on macos 10.13 (#5255) 2026-02-19 23:34:56 +01:00
lwouis 35eae11389 feat: add setting to blacklist window by title (closes #5299) 2026-02-19 23:34:55 +01:00
lwouis 28c4b121ca fix: rare crash when a window was opened 2026-02-19 23:20:15 +01:00
lwouis d5d699659c feat: can add running apps into blacklist (closes #5268) 2026-02-19 23:20:14 +01:00
lwouis 4b85fb8cf7 feat: remember position/size of secondary windows (closes #5305) 2026-02-19 23:20:14 +01:00
lwouis c51376fd26 feat: add new setting for auto size (closes #3669) 2026-02-19 23:20:13 +01:00
lwouis b9e0344da4 fix: small issues when mouse hover is set to select (closes #5292) 2026-02-19 23:20:12 +01:00
lwouis ea51d57d3d fix: sometimes the active app was not up-to-date (closes #5291) 2026-02-19 23:20:12 +01:00
semantic-release-bot a7b7a79ece chore(release): 10.1.0 [skip ci]
# [10.1.0](https://github.com/lwouis/alt-tab-macos/compare/v10.0.0...v10.1.0) (2026-02-17)

### Bug Fixes

* better flow when last 2 windows are minimized (closes [#2159](https://github.com/lwouis/alt-tab-macos/issues/2159)) ([da6be20](https://github.com/lwouis/alt-tab-macos/commit/da6be20))
* issue with link drag-and-drop over the switcher (closes [#5292](https://github.com/lwouis/alt-tab-macos/issues/5292)) ([4e6361f](https://github.com/lwouis/alt-tab-macos/commit/4e6361f))
* trackpad gesture active when disabled (closes [#5301](https://github.com/lwouis/alt-tab-macos/issues/5301)) ([d074faa](https://github.com/lwouis/alt-tab-macos/commit/d074faa))

### Features

* allow settings export/import (closes [#4514](https://github.com/lwouis/alt-tab-macos/issues/4514)) ([69a9dfa](https://github.com/lwouis/alt-tab-macos/commit/69a9dfa))
2026-02-17 18:30:07 +00:00
lwouis 09789e297d refactor: remove unnecessary string 2026-02-17 18:24:48 +01:00
lwouis 69a9dfa41b feat: allow settings export/import (closes #4514) 2026-02-17 18:01:26 +01:00
lwouis 4e6361ff7b fix: issue with link drag-and-drop over the switcher (closes #5292) 2026-02-17 17:42:20 +01:00
lwouis 91d4a7781e refactor: update settings sidebar to liquid glass visuals 2026-02-17 17:42:18 +01:00
lwouis da6be203f0 fix: better flow when last 2 windows are minimized (closes #2159) 2026-02-17 11:45:55 +01:00
lwouis d074faafd1 fix: trackpad gesture active when disabled (closes #5301) 2026-02-17 10:38:08 +01:00
semantic-release-bot 39d7af8483 chore(release): 10.0.0 [skip ci]
# [10.0.0](https://github.com/lwouis/alt-tab-macos/compare/v9.0.0...v10.0.0) (2026-02-16)

### Bug Fixes

* app could crash in rare scenarios ([3de0276](https://github.com/lwouis/alt-tab-macos/commit/3de0276))
* launched app may not be seen as active (closes [#5291](https://github.com/lwouis/alt-tab-macos/issues/5291)) ([3e47ebe](https://github.com/lwouis/alt-tab-macos/commit/3e47ebe))
* quick switches could sometimes do nothing (closes [#5289](https://github.com/lwouis/alt-tab-macos/issues/5289)) ([82795d8](https://github.com/lwouis/alt-tab-macos/commit/82795d8))

### Features

* add debug tools ([07e4024](https://github.com/lwouis/alt-tab-macos/commit/07e4024))
* add fuzzy search mode (closes [#590](https://github.com/lwouis/alt-tab-macos/issues/590)) ([4e986f3](https://github.com/lwouis/alt-tab-macos/commit/4e986f3))
* allow up to 9 shortcuts ([#3882](https://github.com/lwouis/alt-tab-macos/issues/3882)) ([8cab3e1](https://github.com/lwouis/alt-tab-macos/commit/8cab3e1))
* new settings experience (closes [#5287](https://github.com/lwouis/alt-tab-macos/issues/5287)) ([3890beb](https://github.com/lwouis/alt-tab-macos/commit/3890beb))
* support app-icon badges with large numbers ([ceed334](https://github.com/lwouis/alt-tab-macos/commit/ceed334))
* support showing only non-visible spaces (closes [#1274](https://github.com/lwouis/alt-tab-macos/issues/1274)) ([51db0cb](https://github.com/lwouis/alt-tab-macos/commit/51db0cb))
* update bn localization ([3f1617c](https://github.com/lwouis/alt-tab-macos/commit/3f1617c))

### BREAKING CHANGES

* a whole new alt-tab experience by pressing "s". You can also set search as the default style in the settings
2026-02-16 23:04:53 +00:00
lwouis 2ee406c909 refactor: fix tests 2026-02-16 23:56:14 +01:00
lwouis 66db895dd3 refactor: missed some renames 2026-02-16 23:56:13 +01:00
lwouis 07e4024a9c feat: add debug tools 2026-02-16 23:56:13 +01:00
lwouis 8cab3e1f8b feat: allow up to 9 shortcuts (#3882) 2026-02-16 22:53:01 +01:00
lwouis 3f1617cba0 feat: update bn localization 2026-02-16 22:53:01 +01:00
lwouis 82795d845c fix: quick switches could sometimes do nothing (closes #5289) 2026-02-16 22:53:01 +01:00
lwouis 99201191f4 refactor: prevent ambiguous ids between apps and windows 2026-02-16 22:53:00 +01:00
lwouis 3de027644c fix: app could crash in rare scenarios
concurrency issues on preferences
2026-02-16 22:53:00 +01:00
lwouis 3e47ebec8e fix: launched app may not be seen as active (closes #5291) 2026-02-16 22:52:59 +01:00
lwouis 3890beb9d3 feat: new settings experience (closes #5287) 2026-02-16 22:52:58 +01:00
lwouis 93e2b35dc7 refactor: permissions window is lazily initialized 2026-02-16 22:52:57 +01:00
lwouis da21cb8e21 refactor: feedback window is lazily initialized 2026-02-16 22:52:57 +01:00
lwouis 14a0b716b6 refactor: preferences window is lazily initialized 2026-02-16 22:52:56 +01:00
Jakku Sakura 4e986f37a0 feat: add fuzzy search mode (closes #590)
BREAKING CHANGE: a whole new alt-tab experience by pressing "s". You can also set search as the default style in the settings
2026-02-16 22:52:56 +01:00
lwouis e3092b4299 chore: remove complex ai rules 2026-02-16 13:33:19 +01:00
lwouis ceed334b06 feat: support app-icon badges with large numbers 2026-02-16 13:33:18 +01:00
lwouis 51db0cb8e4 feat: support showing only non-visible spaces (closes #1274) 2026-02-16 13:33:18 +01:00
semantic-release-bot 3961f2a888 chore(release): 9.0.0 [skip ci]
# [9.0.0](https://github.com/lwouis/alt-tab-macos/compare/v8.3.4...v9.0.0) (2026-02-11)

### Bug Fixes

* missing thumbnails in rare cases ([3142590](https://github.com/lwouis/alt-tab-macos/commit/3142590))
* preserve scroll position in switcher if windows change ([fa9e4d0](https://github.com/lwouis/alt-tab-macos/commit/fa9e4d0))
* prevent macos 10.13 crash (closes [#5255](https://github.com/lwouis/alt-tab-macos/issues/5255)) ([d525d35](https://github.com/lwouis/alt-tab-macos/commit/d525d35))

### Features

* improve performance when many windows are open (closes [#5177](https://github.com/lwouis/alt-tab-macos/issues/5177)) ([5d0a92f](https://github.com/lwouis/alt-tab-macos/commit/5d0a92f))
* new thumbnails shadows in macos 26 style ([26d46e3](https://github.com/lwouis/alt-tab-macos/commit/26d46e3))
* update cs/el/fr/ru localizations ([2681218](https://github.com/lwouis/alt-tab-macos/commit/2681218))

### Performance Improvements

* better caanimation batching ([016052c](https://github.com/lwouis/alt-tab-macos/commit/016052c))
* cache expensive layout values ([904bd17](https://github.com/lwouis/alt-tab-macos/commit/904bd17))
* cache expensive layout values 2 ([13ed78b](https://github.com/lwouis/alt-tab-macos/commit/13ed78b))
* cache font from appearance ([305870b](https://github.com/lwouis/alt-tab-macos/commit/305870b))
* cache screen uuids and frontmost app ([a5135c5](https://github.com/lwouis/alt-tab-macos/commit/a5135c5))
* capture samplebuffer directly ([2bce0d2](https://github.com/lwouis/alt-tab-macos/commit/2bce0d2))
* create overlay view to optimize view count ([ec5802a](https://github.com/lwouis/alt-tab-macos/commit/ec5802a))
* do all mouse interactions globally instead of local tracking ([d89bc29](https://github.com/lwouis/alt-tab-macos/commit/d89bc29))
* have views under and over the thumbnailview ([b9637e5](https://github.com/lwouis/alt-tab-macos/commit/b9637e5))
* improve hiding the ui ([4f5e325](https://github.com/lwouis/alt-tab-macos/commit/4f5e325))
* merge mouseevents into cursorevents ([9edf312](https://github.com/lwouis/alt-tab-macos/commit/9edf312))
* move app icon capture to background queue ([5a35aa9](https://github.com/lwouis/alt-tab-macos/commit/5a35aa9))
* optim hangs from DebugMenu ([4b830e6](https://github.com/lwouis/alt-tab-macos/commit/4b830e6))
* prevent appkit work ([fefc491](https://github.com/lwouis/alt-tab-macos/commit/fefc491))
* prevent costly window recursive views update ([41e0e7c](https://github.com/lwouis/alt-tab-macos/commit/41e0e7c))
* prevent possible frequent permissions check ([216563b](https://github.com/lwouis/alt-tab-macos/commit/216563b))
* remove normalize-subview to avoid appkit work ([ce2dfc1](https://github.com/lwouis/alt-tab-macos/commit/ce2dfc1))
* simplify and combine views for better perf ([3a8c0f3](https://github.com/lwouis/alt-tab-macos/commit/3a8c0f3))
* small optimizations from profiling ([db314c9](https://github.com/lwouis/alt-tab-macos/commit/db314c9))
* throttle all window/app ax calls ([337e2fb](https://github.com/lwouis/alt-tab-macos/commit/337e2fb))
* update windows manually after 250s ([52530b2](https://github.com/lwouis/alt-tab-macos/commit/52530b2))
* use calayer instead of nsview for lightimageview ([7dec9da](https://github.com/lwouis/alt-tab-macos/commit/7dec9da))

### BREAKING CHANGES

* major performance improvements
2026-02-11 20:50:23 +00:00
lwouis 91d44e72df ci: workaround github actions bug by checking out more commits 2026-02-11 21:42:44 +01:00
lwouis 314259032d fix: missing thumbnails in rare cases 2026-02-11 21:35:41 +01:00
lwouis fa9e4d0ee1 fix: preserve scroll position in switcher if windows change 2026-02-11 21:35:41 +01:00
lwouis 6de7fee90c refactor: add bottom padding when scrolling in appicons appearance 2026-02-11 21:35:40 +01:00
lwouis f7226f681a refactor: fix windowless indicator position 2026-02-11 21:35:39 +01:00
lwouis 26d46e3768 feat: new thumbnails shadows in macos 26 style 2026-02-11 21:35:39 +01:00
lwouis 216563b635 perf: prevent possible frequent permissions check 2026-02-11 21:35:38 +01:00
lwouis 3f2f391c93 refactor: extract statusiconsview 2026-02-11 21:35:38 +01:00
lwouis 9edf31244a perf: merge mouseevents into cursorevents 2026-02-11 21:35:37 +01:00
lwouis d89bc29425 perf: do all mouse interactions globally instead of local tracking 2026-02-11 21:35:36 +01:00
lwouis d525d350fc fix: prevent macos 10.13 crash (closes #5255) 2026-02-11 21:35:36 +01:00
lwouis d1ba6bd333 chore: update periphery + remove dead code 2026-02-11 21:35:35 +01:00
lwouis 6695e9be9c refactor: rename to tiles 2026-02-11 21:35:35 +01:00
lwouis 396ef6f0b0 refactor: fix mouse hover right after switching space 2026-02-11 21:35:34 +01:00
lwouis b9637e5802 perf: have views under and over the thumbnailview 2026-02-11 21:35:34 +01:00
lwouis fe52511885 refactor: space indicator always rightmost 2026-02-11 21:35:33 +01:00
lwouis 337e2fbfec perf: throttle all window/app ax calls 2026-02-11 21:35:32 +01:00
lwouis 4f5e32593b perf: improve hiding the ui 2026-02-11 21:35:32 +01:00
lwouis db314c9948 perf: small optimizations from profiling 2026-02-11 21:35:31 +01:00
lwouis 7dec9da401 perf: use calayer instead of nsview for lightimageview 2026-02-11 21:35:31 +01:00
lwouis 3a8c0f3bee perf: simplify and combine views for better perf 2026-02-11 21:35:30 +01:00
lwouis ec5802a487 perf: create overlay view to optimize view count 2026-02-11 21:35:29 +01:00
lwouis fefc491ce5 perf: prevent appkit work 2026-02-11 21:35:29 +01:00
lwouis 41e0e7c688 perf: prevent costly window recursive views update 2026-02-11 21:35:28 +01:00
lwouis ce2dfc1f19 perf: remove normalize-subview to avoid appkit work 2026-02-11 21:35:28 +01:00
lwouis 13ed78bc23 perf: cache expensive layout values 2 2026-02-11 21:35:27 +01:00
lwouis 904bd17c53 perf: cache expensive layout values 2026-02-11 21:35:27 +01:00
lwouis 1f3a653faa refactor: add benchmarker 2026-02-11 21:35:26 +01:00
lwouis cd1d6574f7 chore: remove dead code 2026-02-11 21:35:26 +01:00
lwouis a5135c5560 perf: cache screen uuids and frontmost app 2026-02-11 21:35:25 +01:00
lwouis 2bce0d2d40 perf: capture samplebuffer directly 2026-02-11 21:35:24 +01:00
lwouis 016052ca14 perf: better caanimation batching 2026-02-11 21:35:24 +01:00
lwouis 305870b3ee perf: cache font from appearance 2026-02-11 21:35:23 +01:00
lwouis 52530b2d5c perf: update windows manually after 250s 2026-02-11 21:35:23 +01:00
lwouis 5a35aa95bc perf: move app icon capture to background queue 2026-02-11 21:35:22 +01:00
lwouis 53da0344bf refactor: avoid checking transparency on some images 2026-02-11 21:35:22 +01:00
lwouis f30d3760a1 refactor: codex perf improvements 2026-02-11 21:35:21 +01:00
lwouis fbcc3f5f02 refactor: improve manual window discovery 2026-02-11 21:35:21 +01:00
Christian Battaglia 5d0a92f3f7 feat: improve performance when many windows are open (closes #5177)
BREAKING CHANGE: major performance improvements
2026-02-11 21:35:18 +01:00
lwouis 4b830e6ba7 perf: optim hangs from DebugMenu 2026-02-08 10:30:48 +01:00
lwouis 698e5e8e0c chore: update periphery config 2026-02-08 10:30:47 +01:00
lwouis a4f5a23846 docs: add ai agents rules 2026-02-08 10:30:44 +01:00
lwouis 268121850d feat: update cs/el/fr/ru localizations 2026-02-08 10:23:16 +01:00
semantic-release-bot aeaf782feb chore(release): 8.3.4 [skip ci]
## [8.3.4](https://github.com/lwouis/alt-tab-macos/compare/v8.3.3...v8.3.4) (2026-01-31)

### Bug Fixes

* app could sometimes crash in the background ([ab704dc](https://github.com/lwouis/alt-tab-macos/commit/ab704dc)), closes [#5260](https://github.com/lwouis/alt-tab-macos/issues/5260)
* quitting apps by pressing q multiple times (closes [#5247](https://github.com/lwouis/alt-tab-macos/issues/5247)) ([21aeafd](https://github.com/lwouis/alt-tab-macos/commit/21aeafd))
2026-01-31 18:18:25 +00:00
lwouis 21aeafd8dd fix: quitting apps by pressing q multiple times (closes #5247) 2026-01-31 18:42:45 +01:00
lwouis ab704dc4be fix: app could sometimes crash in the background
closes #5260

appcenter showed that access to debugId() from main and non-main threa could crash the app. Making debugId a string that's set once at init simplifies everything and allows concurrent access from threads
2026-01-31 18:42:42 +01:00
lwouis 42c0a03ddc docs: improve website title 2026-01-25 22:34:53 +01:00
semantic-release-bot 550529f1fa chore(release): 8.3.3 [skip ci]
## [8.3.3](https://github.com/lwouis/alt-tab-macos/compare/v8.3.2...v8.3.3) (2026-01-25)

### Bug Fixes

* app icons could sometimes be invisible (closes [#5226](https://github.com/lwouis/alt-tab-macos/issues/5226)) ([23fbc01](https://github.com/lwouis/alt-tab-macos/commit/23fbc01))
* improve trackpad gesture detection (closes [#5203](https://github.com/lwouis/alt-tab-macos/issues/5203)) ([9b5e43e](https://github.com/lwouis/alt-tab-macos/commit/9b5e43e))
* switcher could sometimes show with no window pre-selected ([3e95f77](https://github.com/lwouis/alt-tab-macos/commit/3e95f77))
* title could be off-center in app-icons appearance (closes [#5235](https://github.com/lwouis/alt-tab-macos/issues/5235)) ([7fdfe4a](https://github.com/lwouis/alt-tab-macos/commit/7fdfe4a))
2026-01-25 21:24:33 +00:00
lwouis 23fbc01a0e fix: app icons could sometimes be invisible (closes #5226) 2026-01-25 22:19:02 +01:00
lwouis 56546571b6 docs: add frequently asked questions on website 2026-01-24 20:12:45 +01:00
lwouis e5c634e672 refactor: simplify v-center logic
no need for the complex bias thing. We round in the end. And up or down each have downsides, so let's pick the default without doing extra logic
2026-01-24 14:07:38 +01:00
lwouis 7fdfe4a9ee fix: title could be off-center in app-icons appearance (closes #5235) 2026-01-24 13:39:25 +01:00
lwouis 3e95f77cc0 fix: switcher could sometimes show with no window pre-selected 2026-01-24 13:39:24 +01:00
lwouis 9b5e43eec5 fix: improve trackpad gesture detection (closes #5203) 2026-01-23 18:27:42 +01:00
lwouis ac3c3740c2 chore: improve log 2026-01-23 18:18:27 +01:00
semantic-release-bot 35a67ddf16 chore(release): 8.3.2 [skip ci]
## [8.3.2](https://github.com/lwouis/alt-tab-macos/compare/v8.3.1...v8.3.2) (2026-01-22)

### Bug Fixes

* blacklisting fullscreen windows was not working (closes [#5228](https://github.com/lwouis/alt-tab-macos/issues/5228)) ([53815e0](https://github.com/lwouis/alt-tab-macos/commit/53815e0))
2026-01-22 23:34:13 +00:00
lwouis 53815e0f28 fix: blacklisting fullscreen windows was not working (closes #5228) 2026-01-23 00:24:53 +01:00
semantic-release-bot 7b7a73bd46 chore(release): 8.3.1 [skip ci]
## [8.3.1](https://github.com/lwouis/alt-tab-macos/compare/v8.3.0...v8.3.1) (2026-01-22)

### Bug Fixes

* chrome apps windows would not show in the switcher (closes [#5227](https://github.com/lwouis/alt-tab-macos/issues/5227)) ([bf3fa67](https://github.com/lwouis/alt-tab-macos/commit/bf3fa67))
2026-01-22 21:47:45 +00:00
lwouis bf3fa6734e fix: chrome apps windows would not show in the switcher (closes #5227) 2026-01-22 22:28:46 +01:00
semantic-release-bot be06aef6d7 chore(release): 8.3.0 [skip ci]
# [8.3.0](https://github.com/lwouis/alt-tab-macos/compare/v8.2.0...v8.3.0) (2026-01-20)

### Bug Fixes

* position of windowless indicator in thumbnails appearance ([d1fd1fd](https://github.com/lwouis/alt-tab-macos/commit/d1fd1fd))
* small memory leak when opening the switcher (closes [#4255](https://github.com/lwouis/alt-tab-macos/issues/4255)) ([0a6485e](https://github.com/lwouis/alt-tab-macos/commit/0a6485e))
* windows would sometimes not update their order (closes [#5207](https://github.com/lwouis/alt-tab-macos/issues/5207)) ([a3f2a54](https://github.com/lwouis/alt-tab-macos/commit/a3f2a54))

### Features

* increase apparition delay granularity (closes [#5210](https://github.com/lwouis/alt-tab-macos/issues/5210)) ([5b0df6b](https://github.com/lwouis/alt-tab-macos/commit/5b0df6b))
2026-01-20 17:59:06 +00:00
lwouis 3e27abd1e8 chore: improve log levels 2026-01-19 19:35:15 +01:00
lwouis 0a6485e024 fix: small memory leak when opening the switcher (closes #4255) 2026-01-19 19:35:14 +01:00
lwouis 5b0df6bd4c feat: increase apparition delay granularity (closes #5210) 2026-01-19 19:35:14 +01:00
lwouis a3f2a54f20 fix: windows would sometimes not update their order (closes #5207) 2026-01-19 19:35:13 +01:00
lwouis d1fd1fd9d0 fix: position of windowless indicator in thumbnails appearance 2026-01-17 00:06:10 +01:00
lwouis cd5fb46963 chore: silence build warnings from pods 2026-01-15 19:21:32 +01:00
semantic-release-bot 09ebff06ee chore(release): 8.2.0 [skip ci]
# [8.2.0](https://github.com/lwouis/alt-tab-macos/compare/v8.1.0...v8.2.0) (2026-01-15)

### Bug Fixes

* thumbnails could sometimes be stretched (closes [#5204](https://github.com/lwouis/alt-tab-macos/issues/5204)) ([ac24d6d](https://github.com/lwouis/alt-tab-macos/commit/ac24d6d))

### Features

* stop checking screen-recording permission after launch ([#5202](https://github.com/lwouis/alt-tab-macos/issues/5202)) ([f481d22](https://github.com/lwouis/alt-tab-macos/commit/f481d22))
2026-01-15 18:02:05 +00:00
lwouis ac24d6d148 fix: thumbnails could sometimes be stretched (closes #5204) 2026-01-15 18:01:08 +01:00
lwouis f481d22b75 feat: stop checking screen-recording permission after launch (#5202)
closes #5202

the permission check was expensive for the os, leading to higher energy usage, thus more battery drain
2026-01-15 15:47:33 +01:00
lwouis 149e3a5026 docs: improve changelog design 2026-01-15 14:42:42 +01:00
lwouis ef83525e9a docs: improve website on mobile 2026-01-15 14:42:41 +01:00
semantic-release-bot 56a042716e chore(release): 8.1.0 [skip ci]
# [8.1.0](https://github.com/lwouis/alt-tab-macos/compare/v8.0.0...v8.1.0) (2026-01-14)

### Bug Fixes

* allow f-keys as shortcuts-when-active (closes [#5166](https://github.com/lwouis/alt-tab-macos/issues/5166)) ([a0c9fee](https://github.com/lwouis/alt-tab-macos/commit/a0c9fee))
* avoid unintentional trackpad trigger (closes [#4278](https://github.com/lwouis/alt-tab-macos/issues/4278)) ([0539a3a](https://github.com/lwouis/alt-tab-macos/commit/0539a3a))
* better handle palm/fingers resting on the trackpad (closes [#5191](https://github.com/lwouis/alt-tab-macos/issues/5191)) ([9ed8a19](https://github.com/lwouis/alt-tab-macos/commit/9ed8a19))
* mitigate macos 15 bugs with screencapture-kit (closes [#5190](https://github.com/lwouis/alt-tab-macos/issues/5190)) ([b2f5c6c](https://github.com/lwouis/alt-tab-macos/commit/b2f5c6c))
* mouse hover detection for hidden/windowless apps ([7c64864](https://github.com/lwouis/alt-tab-macos/commit/7c64864))
* thumbnails could sometimes be the wrong size ([9d0b947](https://github.com/lwouis/alt-tab-macos/commit/9d0b947))

### Features

* add belarusian localization ([0fe722b](https://github.com/lwouis/alt-tab-macos/commit/0fe722b))
* improve accidental cursor movement ([74b5a11](https://github.com/lwouis/alt-tab-macos/commit/74b5a11)), closes [/github.com/lwouis/alt-tab-macos/issues/4278#issuecomment-3733280737](https://github.com//github.com/lwouis/alt-tab-macos/issues/4278/issues/issuecomment-3733280737)
* improve pl localization ([3b53ce7](https://github.com/lwouis/alt-tab-macos/commit/3b53ce7))
* show outline of windows hidden for privacy reasons (closes [#5172](https://github.com/lwouis/alt-tab-macos/issues/5172)) ([1090acf](https://github.com/lwouis/alt-tab-macos/commit/1090acf))
2026-01-14 23:19:39 +00:00
lwouis 0fe722bfba feat: add belarusian localization 2026-01-15 00:08:36 +01:00
lwouis 3b53ce77bb feat: improve pl localization 2026-01-15 00:08:36 +01:00
lwouis b2f5c6c4d5 fix: mitigate macos 15 bugs with screencapture-kit (closes #5190) 2026-01-15 00:08:35 +01:00
emptiestplace 7c64864c2f fix: mouse hover detection for hidden/windowless apps 2026-01-15 00:08:35 +01:00
lwouis 9d0b947a48 fix: thumbnails could sometimes be the wrong size
* fixes issues when the user has monitors with different DPI
* fixes issues where screenshots after a window is resized could be wrong (because of cached SCWindow having stale frame.size)
2026-01-15 00:08:34 +01:00
lwouis 9ed8a199b0 fix: better handle palm/fingers resting on the trackpad (closes #5191) 2026-01-15 00:08:34 +01:00
lwouis a0c9feefca fix: allow f-keys as shortcuts-when-active (closes #5166) 2026-01-15 00:08:33 +01:00
lwouis 1a2822d130 docs: website redesign 2026-01-14 00:09:51 +01:00
lwouis 44007195b7 docs: improve website and readme 2026-01-12 17:15:25 +01:00
lwouis 74b5a119d3 feat: improve accidental cursor movement
see https://github.com/lwouis/alt-tab-macos/issues/4278#issuecomment-3733280737
2026-01-11 14:55:26 +01:00
lwouis 0539a3ad49 fix: avoid unintentional trackpad trigger (closes #4278) 2026-01-11 14:55:26 +01:00
lwouis a06afd4bd2 refactor: remove unneeded views; simplify views 2026-01-11 14:55:25 +01:00
lwouis 1090acf3a5 feat: show outline of windows hidden for privacy reasons (closes #5172) 2026-01-07 19:16:14 +01:00
semantic-release-bot b8ba0f0888 chore(release): 8.0.0 [skip ci]
# [8.0.0](https://github.com/lwouis/alt-tab-macos/compare/v7.39.0...v8.0.0) (2026-01-06)

### Bug Fixes

* avoid macos bug where many permission dialogs pop (closes [#5106](https://github.com/lwouis/alt-tab-macos/issues/5106)) ([5c4199e](https://github.com/lwouis/alt-tab-macos/commit/5c4199e))

### Features

* improve memory image of showing app icons (closes [#5144](https://github.com/lwouis/alt-tab-macos/issues/5144)) ([bf58335](https://github.com/lwouis/alt-tab-macos/commit/bf58335))
* improve ta localization ([989b344](https://github.com/lwouis/alt-tab-macos/commit/989b344))
* improve thumbnails with screen-capture kit ([7821d7c](https://github.com/lwouis/alt-tab-macos/commit/7821d7c)), closes [#4255](https://github.com/lwouis/alt-tab-macos/issues/4255) [#3652](https://github.com/lwouis/alt-tab-macos/issues/3652)

### Performance Improvements

* debounce screen/space events to minimize work ([e2b4779](https://github.com/lwouis/alt-tab-macos/commit/e2b4779))

### BREAKING CHANGES

* Better thumbnails with ScreenCaptureKit for users on macOS >= 14
2026-01-06 18:36:28 +00:00
lwouis 989b344b1d feat: improve ta localization 2026-01-06 19:27:16 +01:00
lwouis bf58335bbe feat: improve memory image of showing app icons (closes #5144) 2026-01-05 23:12:36 +01:00
lwouis 5c4199ec74 fix: avoid macos bug where many permission dialogs pop (closes #5106) 2026-01-04 22:53:54 +01:00
lwouis 7821d7c979 feat: improve thumbnails with screen-capture kit
BREAKING CHANGE: Better thumbnails with ScreenCaptureKit for users on macOS >= 14

* No more WindowServer memory leaks (closes #4255)
* No more purple UI from macOS bothering users
* Fullscreen thumbnails contain top part (closes #3652)
* Thumbnails contain dialogs (e.g. Save/Print panel)
* Show thumbnails for off-screen windows
* Memory usage drastically reduced (e.g. don't save full-resolution if Preview feature is not used)
* Limitations of ScreenCaptureKit compared to private API: can't capture minimized/hidden/tabbed windows
2026-01-04 22:49:41 +01:00
lwouis e2b47790a9 perf: debounce screen/space events to minimize work 2026-01-04 14:18:17 +01:00
lwouis ff66a0664d chore: reduce link font size 2026-01-04 12:08:44 +01:00
semantic-release-bot 6d42bef7ec chore(release): 7.39.0 [skip ci]
# [7.39.0](https://github.com/lwouis/alt-tab-macos/compare/v7.38.1...v7.39.0) (2026-01-03)

### Bug Fixes

* avoid showing closed windows (closes [#3589](https://github.com/lwouis/alt-tab-macos/issues/3589)) ([894a69d](https://github.com/lwouis/alt-tab-macos/commit/894a69d)), closes [#4924](https://github.com/lwouis/alt-tab-macos/issues/4924)
* permission checks might freeze or restart the app (closes [#5112](https://github.com/lwouis/alt-tab-macos/issues/5112)) ([7906d63](https://github.com/lwouis/alt-tab-macos/commit/7906d63))
* permission window could steal focus (see [#3577](https://github.com/lwouis/alt-tab-macos/issues/3577)) ([2f875b3](https://github.com/lwouis/alt-tab-macos/commit/2f875b3))
* permissions window could look wrong in some languages like chinese ([914f91f](https://github.com/lwouis/alt-tab-macos/commit/914f91f)), closes [/github.com/lwouis/alt-tab-macos/issues/5112#issuecomment-3692769341](https://github.com//github.com/lwouis/alt-tab-macos/issues/5112/issues/issuecomment-3692769341)
* preview could sometimes be incorrectly positioned ([edc2f00](https://github.com/lwouis/alt-tab-macos/commit/edc2f00))
* show some hovering windows (e.g. zoom.app) (closes [#5140](https://github.com/lwouis/alt-tab-macos/issues/5140)) ([fcc6651](https://github.com/lwouis/alt-tab-macos/commit/fcc6651))
* thumbnails could sometimes have the wrong size ([55f3f59](https://github.com/lwouis/alt-tab-macos/commit/55f3f59))

### Features

* avoid occasional delays in showing the switcher (closes [#5109](https://github.com/lwouis/alt-tab-macos/issues/5109)) ([3c04a4c](https://github.com/lwouis/alt-tab-macos/commit/3c04a4c))
* improve nb/tr localizations ([5e842d5](https://github.com/lwouis/alt-tab-macos/commit/5e842d5))
* remove shadow around app icon appearance ([dda612c](https://github.com/lwouis/alt-tab-macos/commit/dda612c))

### Performance Improvements

* do login item and plist updates later to accelerate launch ([2f72c5d](https://github.com/lwouis/alt-tab-macos/commit/2f72c5d))
* don't compute diffs of running-apps; directly get new/old ([7ded01c](https://github.com/lwouis/alt-tab-macos/commit/7ded01c))
* improve mouse hover algo and core-animation side ([6103785](https://github.com/lwouis/alt-tab-macos/commit/6103785))
2026-01-03 18:23:00 +00:00
lwouis cca3423a59 ci: github action somehow misses 2 commits; adding more leeway 2026-01-03 19:18:44 +01:00
lwouis 5e842d5850 feat: improve nb/tr localizations 2026-01-03 19:18:43 +01:00
lwouis 0c724f3c7b refactor: various small improvements 2026-01-03 19:18:43 +01:00
lwouis 55f3f59208 fix: thumbnails could sometimes have the wrong size 2026-01-03 19:18:43 +01:00
lwouis edc2f00603 fix: preview could sometimes be incorrectly positioned 2026-01-03 19:18:42 +01:00
lwouis bcb130e7eb refactor: clarify names and organize tidier 2026-01-03 19:18:42 +01:00
lwouis d8de1e80b8 refactor: logs overall: lazy + reviewed them 1 by 1 for better dx 2026-01-03 19:18:41 +01:00
lwouis 610378525a perf: improve mouse hover algo and core-animation side 2026-01-03 18:09:19 +01:00
lwouis 2f72c5d6ae perf: do login item and plist updates later to accelerate launch 2026-01-03 18:09:19 +01:00
lwouis a62949f0dc refactor: add logs 2026-01-03 18:09:18 +01:00
lwouis 7ded01c277 perf: don't compute diffs of running-apps; directly get new/old 2026-01-03 18:09:18 +01:00
lwouis a45361321d chore: document why we check mouse events on main-thread 2026-01-03 18:09:17 +01:00
lwouis b7204f9694 refactor: repeatingKeyThread -> repeatingKeyQueue 2026-01-03 18:09:17 +01:00
lwouis b8a3b779e1 chore: document why we use kvo for processes diffing 2026-01-03 18:09:16 +01:00
lwouis 7906d630be fix: permission checks might freeze or restart the app (closes #5112) 2026-01-03 18:09:16 +01:00
lwouis 3c04a4ce15 feat: avoid occasional delays in showing the switcher (closes #5109) 2026-01-03 17:36:23 +01:00
lwouis 2f875b3bcb fix: permission window could steal focus (see #3577) 2025-12-28 18:47:02 +01:00
lwouis 914f91f9f7 fix: permissions window could look wrong in some languages like chinese
see https://github.com/lwouis/alt-tab-macos/issues/5112#issuecomment-3692769341
2025-12-28 18:47:01 +01:00
lwouis fcc6651b6a fix: show some hovering windows (e.g. zoom.app) (closes #5140) 2025-12-28 18:47:01 +01:00
lwouis dda612c15e feat: remove shadow around app icon appearance 2025-12-28 18:47:00 +01:00
lwouis 894a69d41f fix: avoid showing closed windows (closes #3589)
closes #4924
2025-12-20 01:14:30 +01:00
lwouis e2523f1d99 docs: remove dead link on website (closes #5134) 2025-12-20 01:14:29 +01:00
lwouis 6fa35ae35c chore: document tab detection experiments 2025-12-16 10:31:37 +01:00
semantic-release-bot d0a2d31b5a chore(release): 7.38.1 [skip ci]
## [7.38.1](https://github.com/lwouis/alt-tab-macos/compare/v7.38.0...v7.38.1) (2025-12-13)

### Bug Fixes

* could sometimes freeze on the permission window ([43838e1](https://github.com/lwouis/alt-tab-macos/commit/43838e1)), closes [#5112](https://github.com/lwouis/alt-tab-macos/issues/5112)
* prevent crash when sending a debug profile ([741e790](https://github.com/lwouis/alt-tab-macos/commit/741e790))
2025-12-13 19:15:21 +00:00
lwouis 43838e1ccc fix: could sometimes freeze on the permission window
#5112
2025-12-13 20:10:52 +01:00
lwouis 741e7902db fix: prevent crash when sending a debug profile 2025-12-07 23:45:42 +01:00
semantic-release-bot 6426d318fb chore(release): 7.38.0 [skip ci]
# [7.38.0](https://github.com/lwouis/alt-tab-macos/compare/v7.37.0...v7.38.0) (2025-12-07)

### Bug Fixes

* could sometimes freeze upon launch (closes [#5079](https://github.com/lwouis/alt-tab-macos/issues/5079)) ([ee27df7](https://github.com/lwouis/alt-tab-macos/commit/ee27df7))
* sending feedback with a debug-profile could sometimes crash ([e0ae29d](https://github.com/lwouis/alt-tab-macos/commit/e0ae29d))

### Features

* improve ca/es/ga/pt/pt-br/uk localizations ([8a98b4e](https://github.com/lwouis/alt-tab-macos/commit/8a98b4e))
* prevent mouse-hover when using trackpad swipes (closes [#5071](https://github.com/lwouis/alt-tab-macos/issues/5071)) ([b8ecd58](https://github.com/lwouis/alt-tab-macos/commit/b8ecd58))
2025-12-07 11:40:27 +00:00
lwouis 8a98b4ee40 feat: improve ca/es/ga/pt/pt-br/uk localizations 2025-12-07 12:35:22 +01:00
lwouis dcaac482de refactor: separate concerns and simplify 2025-12-06 15:17:31 +01:00
lwouis ee27df7680 fix: could sometimes freeze upon launch (closes #5079) 2025-12-06 12:59:29 +01:00
lwouis e0ae29d64a fix: sending feedback with a debug-profile could sometimes crash 2025-12-06 12:31:33 +01:00
lwouis db78e66451 refactor: consolidate classes, avoid free functions and variables 2025-12-06 12:31:32 +01:00
lwouis b8ecd58005 feat: prevent mouse-hover when using trackpad swipes (closes #5071) 2025-12-06 12:31:32 +01:00
lwouis 2725834c4a refactor: move free functions/variables into their class 2025-12-06 12:31:31 +01:00
semantic-release-bot 42cb2d5d88 chore(release): 7.37.0 [skip ci]
# [7.37.0](https://github.com/lwouis/alt-tab-macos/compare/v7.36.0...v7.37.0) (2025-11-28)

### Bug Fixes

* better crop app icons on macos < 26 (closes [#5080](https://github.com/lwouis/alt-tab-macos/issues/5080)) ([237bb1e](https://github.com/lwouis/alt-tab-macos/commit/237bb1e))

### Features

* improve portuguese localization ([3994429](https://github.com/lwouis/alt-tab-macos/commit/3994429))
* warn tahoe users of shortcut conflict with macos game-overlay ([911aad4](https://github.com/lwouis/alt-tab-macos/commit/911aad4)), closes [#5018](https://github.com/lwouis/alt-tab-macos/issues/5018)
2025-11-28 23:07:33 +00:00
lwouis 3994429b88 feat: improve portuguese localization 2025-11-29 00:03:28 +01:00
lwouis 237bb1e0d9 fix: better crop app icons on macos < 26 (closes #5080) 2025-11-29 00:03:27 +01:00
lwouis 911aad42cc feat: warn tahoe users of shortcut conflict with macos game-overlay
closes #5018
2025-11-29 00:03:27 +01:00
lwouis 36ded28ce4 chore: add input-source to debug profile 2025-11-27 19:31:19 +01:00
semantic-release-bot 9761bb91e9 chore(release): 7.36.0 [skip ci]
# [7.36.0](https://github.com/lwouis/alt-tab-macos/compare/v7.35.0...v7.36.0) (2025-11-25)

### Bug Fixes

* switcher could become broken after changing appearance ([d377b3d](https://github.com/lwouis/alt-tab-macos/commit/d377b3d)), closes [#5061](https://github.com/lwouis/alt-tab-macos/issues/5061)

### Features

* improve portuguese localization ([435a310](https://github.com/lwouis/alt-tab-macos/commit/435a310))
2025-11-25 08:56:30 +00:00
lwouis 435a310590 feat: improve portuguese localization 2025-11-25 09:51:59 +01:00
lwouis d377b3dbca fix: switcher could become broken after changing appearance
closes #5061
2025-11-25 09:51:57 +01:00
semantic-release-bot 850fe285b4 chore(release): 7.35.0 [skip ci]
# [7.35.0](https://github.com/lwouis/alt-tab-macos/compare/v7.34.0...v7.35.0) (2025-11-24)

### Bug Fixes

* app would sometimes crash on macos monterey (closes [#5051](https://github.com/lwouis/alt-tab-macos/issues/5051)) ([29e1cff](https://github.com/lwouis/alt-tab-macos/commit/29e1cff))
* better gesture recognition (closes [#5039](https://github.com/lwouis/alt-tab-macos/issues/5039)) ([1689954](https://github.com/lwouis/alt-tab-macos/commit/1689954))
* closing fullscreen window would glitch it (closes [#5029](https://github.com/lwouis/alt-tab-macos/issues/5029)) ([ee436cc](https://github.com/lwouis/alt-tab-macos/commit/ee436cc))

### Features

* add trackpad haptic feedback for better navigation (closes [#4763](https://github.com/lwouis/alt-tab-macos/issues/4763)) ([fb5dfc4](https://github.com/lwouis/alt-tab-macos/commit/fb5dfc4))
* better icon for feedback form (closes [#5013](https://github.com/lwouis/alt-tab-macos/issues/5013)) ([2c3373a](https://github.com/lwouis/alt-tab-macos/commit/2c3373a))
* improve portuguese localization ([c294ad0](https://github.com/lwouis/alt-tab-macos/commit/c294ad0))
2025-11-24 22:30:41 +00:00
lwouis 2adeb8dbcb chore: remove sparkle updater object from mainmenu
it could crash the app, if loading the xib was done inside main.async{}
it was not needed in the first place, despite what Sparkle does said
2025-11-24 18:07:51 +01:00
lwouis fb5dfc4399 feat: add trackpad haptic feedback for better navigation (closes #4763) 2025-11-24 15:42:58 +01:00
lwouis 29e1cff8f1 fix: app would sometimes crash on macos monterey (closes #5051) 2025-11-24 11:19:44 +01:00
lwouis 2c3373ae16 feat: better icon for feedback form (closes #5013) 2025-11-24 11:19:44 +01:00
lwouis c294ad0d4d feat: improve portuguese localization 2025-11-24 11:19:43 +01:00
lwouis ee436cc7cc fix: closing fullscreen window would glitch it (closes #5029) 2025-11-24 11:19:43 +01:00
lwouis 168995493f fix: better gesture recognition (closes #5039) 2025-11-24 11:19:42 +01:00
semantic-release-bot e477f8b3da chore(release): 7.34.0 [skip ci]
# [7.34.0](https://github.com/lwouis/alt-tab-macos/compare/v7.33.0...v7.34.0) (2025-11-20)

### Bug Fixes

* reduce memory footprint after running for a while (closes [#4255](https://github.com/lwouis/alt-tab-macos/issues/4255)) ([938b735](https://github.com/lwouis/alt-tab-macos/commit/938b735))

### Features

* improve localizations ([516329a](https://github.com/lwouis/alt-tab-macos/commit/516329a))
* improve responsiveness in showing switcher (closes [#4959](https://github.com/lwouis/alt-tab-macos/issues/4959)) ([a80721b](https://github.com/lwouis/alt-tab-macos/commit/a80721b))
2025-11-20 23:27:41 +00:00
lwouis 516329a408 feat: improve localizations 2025-11-21 00:21:07 +01:00
lwouis 938b7353ff fix: reduce memory footprint after running for a while (closes #4255) 2025-11-20 23:42:27 +01:00
lwouis a80721b2d3 feat: improve responsiveness in showing switcher (closes #4959) 2025-11-20 23:42:26 +01:00
lwouis 4e065b9a80 docs: add delight to website support page 2025-11-20 23:42:25 +01:00
lwouis aa8d7d02d1 chore: fix changelog title being removed from now on 2025-11-17 21:18:58 +01:00
semantic-release-bot 05b36fc58f chore(release): 7.33.0 [skip ci]
# [7.33.0](https://github.com/lwouis/alt-tab-macos/compare/v7.32.0...v7.33.0) (2025-11-16)

### Bug Fixes

* app icon was too small in titles-appearance large-size ([ffd0c75](https://github.com/lwouis/alt-tab-macos/commit/ffd0c75))
* take into account accent-color immediatly (closes [#4984](https://github.com/lwouis/alt-tab-macos/issues/4984)) ([011fdba](https://github.com/lwouis/alt-tab-macos/commit/011fdba))

### Features

* improve dealing with reserved/conflicting shortcuts ([fdf3134](https://github.com/lwouis/alt-tab-macos/commit/fdf3134)), closes [#3190](https://github.com/lwouis/alt-tab-macos/issues/3190) [#3288](https://github.com/lwouis/alt-tab-macos/issues/3288) [#1835](https://github.com/lwouis/alt-tab-macos/issues/1835) [#3826](https://github.com/lwouis/alt-tab-macos/issues/3826)
* improve nl/pl/uk localizations ([96caad4](https://github.com/lwouis/alt-tab-macos/commit/96caad4))
* improve trackpad multi-fingers swiping (closes [#4765](https://github.com/lwouis/alt-tab-macos/issues/4765)) ([d6196ec](https://github.com/lwouis/alt-tab-macos/commit/d6196ec))
* improve ux for titles-appearance (closes [#4975](https://github.com/lwouis/alt-tab-macos/issues/4975)) ([c352591](https://github.com/lwouis/alt-tab-macos/commit/c352591))
* macos tahoe improvements: menubar menu, feedback form, wording ([309cae3](https://github.com/lwouis/alt-tab-macos/commit/309cae3)), closes [#4986](https://github.com/lwouis/alt-tab-macos/issues/4986)
2025-11-16 17:57:31 +00:00
fhdufhdu d6196ecad8 feat: improve trackpad multi-fingers swiping (closes #4765) 2025-11-16 18:51:09 +01:00
lwouis 21a91421a6 docs: improve website menu 2025-11-16 18:51:08 +01:00
lwouis 272f51ad5b docs: remove auto-translation of release notes
closes #3933
2025-11-16 18:51:08 +01:00
lwouis c352591d72 feat: improve ux for titles-appearance (closes #4975) 2025-11-16 18:51:07 +01:00
lwouis 96caad46a5 feat: improve nl/pl/uk localizations 2025-11-16 18:51:07 +01:00
lwouis 309cae316b feat: macos tahoe improvements: menubar menu, feedback form, wording
closes #4986
2025-11-16 18:51:06 +01:00
lwouis ffd0c75e8b fix: app icon was too small in titles-appearance large-size 2025-11-15 19:14:38 +01:00
lwouis fdf313472c feat: improve dealing with reserved/conflicting shortcuts
(closes #3190, closes #3288, closes #1835, closes #3826)
2025-11-15 18:47:59 +01:00
lwouis 011fdba7d3 fix: take into account accent-color immediatly (closes #4984) 2025-11-12 19:07:37 +01:00
semantic-release-bot e5e8521ae3 chore(release): 7.32.0 [skip ci]
# [7.32.0](https://github.com/lwouis/alt-tab-macos/compare/v7.31.0...v7.32.0) (2025-11-10)

### Bug Fixes

* alt-tab could crash if asked to close one of its own window ([f46372b](https://github.com/lwouis/alt-tab-macos/commit/f46372b))
* could sometimes crash when navigating up or down (closes [#4110](https://github.com/lwouis/alt-tab-macos/issues/4110)) ([d2220c6](https://github.com/lwouis/alt-tab-macos/commit/d2220c6))

### Features

* improve pl/zh-hk localizations ([786e752](https://github.com/lwouis/alt-tab-macos/commit/786e752))
* improve responsiveness of showing the switcher ([689adc0](https://github.com/lwouis/alt-tab-macos/commit/689adc0))
* new look for tahoe and liquid glass (closes [#4658](https://github.com/lwouis/alt-tab-macos/issues/4658)) ([fab9d7c](https://github.com/lwouis/alt-tab-macos/commit/fab9d7c))
* titles appearance now resizes for better readability ([26d40e1](https://github.com/lwouis/alt-tab-macos/commit/26d40e1)), closes [#3882](https://github.com/lwouis/alt-tab-macos/issues/3882)
* update visuals for macos tahoe and liquid glass ([33c6615](https://github.com/lwouis/alt-tab-macos/commit/33c6615))

### Performance Improvements

* improve rendering performance by doing less work ([ec55ae8](https://github.com/lwouis/alt-tab-macos/commit/ec55ae8))
2025-11-10 19:56:49 +00:00
lwouis 786e752417 feat: improve pl/zh-hk localizations 2025-11-10 20:48:58 +01:00
lwouis d2220c68bd fix: could sometimes crash when navigating up or down (closes #4110) 2025-11-10 20:48:58 +01:00
lwouis 26d40e1149 feat: titles appearance now resizes for better readability
parts of #3882

also fixed a display of titles in every appearance, especially on first display of the switcher ui
2025-11-10 20:48:57 +01:00
lwouis 15a55e6e07 chore: minor cleanup 2025-11-09 09:40:08 +01:00
lwouis 32ab8d6573 chore: calculate nstextfield frame width better 2025-11-09 09:40:07 +01:00
lwouis ec55ae8b00 perf: improve rendering performance by doing less work 2025-11-09 09:40:07 +01:00
lwouis 689adc0a30 feat: improve responsiveness of showing the switcher 2025-11-09 09:40:06 +01:00
lwouis fab9d7c0ab feat: new look for tahoe and liquid glass (closes #4658) 2025-11-09 09:40:06 +01:00
lwouis 4aec2aa6da chore: improve debug build speed 2025-11-09 09:40:05 +01:00
lwouis f46372b97c fix: alt-tab could crash if asked to close one of its own window 2025-11-02 16:05:26 +01:00
lwouis 33c661505e feat: update visuals for macos tahoe and liquid glass 2025-11-02 12:37:03 +01:00
lwouis 91e16f7863 chore: improve readme 2025-11-02 00:31:57 +01:00
lwouis 55e8c331a6 chore: add debug widget to monitor queues 2025-10-30 11:19:24 +01:00
lwouis ae092cd1a7 chore: better logs 2025-10-30 11:17:44 +01:00
semantic-release-bot 122dc2ec0f chore(release): 7.31.0 [skip ci]
# [7.31.0](https://github.com/lwouis/alt-tab-macos/compare/v7.30.0...v7.31.0) (2025-10-26)

### Bug Fixes

* cmd+q would quit alt-tab instead of the selected app (closes [#4867](https://github.com/lwouis/alt-tab-macos/issues/4867)) ([247f635](https://github.com/lwouis/alt-tab-macos/commit/247f635)), closes [#4891](https://github.com/lwouis/alt-tab-macos/issues/4891)
* title was truncated in app-icons appearance (closes [#4860](https://github.com/lwouis/alt-tab-macos/issues/4860)) ([a1cfd1d](https://github.com/lwouis/alt-tab-macos/commit/a1cfd1d))

### Features

* improve ar/de/fr/kn/ru/zh-tw localizations ([173bc97](https://github.com/lwouis/alt-tab-macos/commit/173bc97))
* improve windows detection ([cab591e](https://github.com/lwouis/alt-tab-macos/commit/cab591e))
* new cli command to focus a window using focus order (closes [#4610](https://github.com/lwouis/alt-tab-macos/issues/4610)) ([84166ab](https://github.com/lwouis/alt-tab-macos/commit/84166ab))
* save resources trying to detect certain windows ([33e5acf](https://github.com/lwouis/alt-tab-macos/commit/33e5acf))
2025-10-26 16:45:18 +00:00
lwouis c25b918a51 chore: update xcbeautify to v3.0.0 2025-10-26 17:40:28 +01:00
lwouis 173bc97d0f feat: improve ar/de/fr/kn/ru/zh-tw localizations 2025-10-26 17:40:28 +01:00
lwouis 84166ab954 feat: new cli command to focus a window using focus order (closes #4610) 2025-10-26 17:40:27 +01:00
lwouis a1cfd1de25 fix: title was truncated in app-icons appearance (closes #4860)
fix was to update ci to use macos 15 and xcode 26, since the issue goes away when compiling with xcode 26, without any code change
2025-10-26 17:40:26 +01:00
lwouis 58fcae7af8 chore: improve podfile setup 2025-10-26 16:18:02 +01:00
lwouis 29f0a08391 chore: ignore cursor files 2025-10-26 16:18:01 +01:00
lwouis 2d683e7e46 docs: mention kind support from jetbrains 2025-10-26 16:17:54 +01:00
lwouis 247f6353b0 fix: cmd+q would quit alt-tab instead of the selected app (closes #4867)
closes #4891
2025-10-26 16:15:12 +01:00
lwouis 08e28fd0a5 refactor: improve launch logs 2025-10-26 16:15:11 +01:00
lwouis cab591eb48 feat: improve windows detection 2025-10-26 16:15:02 +01:00
lwouis 33e5acf0ea feat: save resources trying to detect certain windows 2025-09-24 20:21:20 +02:00
semantic-release-bot 15554ef767 chore(release): 7.30.0 [skip ci]
# [7.30.0](https://github.com/lwouis/alt-tab-macos/compare/v7.29.0...v7.30.0) (2025-09-23)

### Bug Fixes

* bring back pre-v7.28 performance (closes [#4805](https://github.com/lwouis/alt-tab-macos/issues/4805)) ([fb6110d](https://github.com/lwouis/alt-tab-macos/commit/fb6110d))

### Features

* improve nb/nl/zh-tw localizations ([a9cb03c](https://github.com/lwouis/alt-tab-macos/commit/a9cb03c))
2025-09-23 22:05:16 +00:00
lwouis a9cb03c26f feat: improve nb/nl/zh-tw localizations 2025-09-24 00:00:25 +02:00
lwouis fb6110d0eb fix: bring back pre-v7.28 performance (closes #4805) 2025-09-23 23:53:31 +02:00
semantic-release-bot c3ace1faff chore(release): 7.29.0 [skip ci]
# [7.29.0](https://github.com/lwouis/alt-tab-macos/compare/v7.28.0...v7.29.0) (2025-09-20)

### Bug Fixes

* windows order was not updating correctly (closes [#4754](https://github.com/lwouis/alt-tab-macos/issues/4754)) ([1316eb2](https://github.com/lwouis/alt-tab-macos/commit/1316eb2))

### Features

* improve fr/ja languages ([c5286c3](https://github.com/lwouis/alt-tab-macos/commit/c5286c3))
2025-09-20 13:15:32 +00:00
lwouis c5286c3a6e feat: improve fr/ja languages 2025-09-19 22:19:52 +02:00
lwouis 1316eb2769 fix: windows order was not updating correctly (closes #4754)
(regression introduced in v7.28.0)
2025-09-19 21:37:24 +02:00
semantic-release-bot 27909f1824 chore(release): 7.28.0 [skip ci]
# [7.28.0](https://github.com/lwouis/alt-tab-macos/compare/v7.27.0...v7.28.0) (2025-09-15)

### Bug Fixes

* focusing windows could fail after focusing a frozen app ([#4520](https://github.com/lwouis/alt-tab-macos/issues/4520)) ([591ce52](https://github.com/lwouis/alt-tab-macos/commit/591ce52))
* improve detection of windows (closes [#4405](https://github.com/lwouis/alt-tab-macos/issues/4405)) ([3c79840](https://github.com/lwouis/alt-tab-macos/commit/3c79840))
* keyboard selection now works with dragging + mouse hover ([be077f1](https://github.com/lwouis/alt-tab-macos/commit/be077f1)), closes [#4711](https://github.com/lwouis/alt-tab-macos/issues/4711)
* remove high-volume unactionable logs (closes [#4697](https://github.com/lwouis/alt-tab-macos/issues/4697)) ([e93e42f](https://github.com/lwouis/alt-tab-macos/commit/e93e42f))

### Features

* add gujarati localization ([4ebd990](https://github.com/lwouis/alt-tab-macos/commit/4ebd990))
* add hong-kong cantonese + improve other languages ([78c8525](https://github.com/lwouis/alt-tab-macos/commit/78c8525))
* add preference to show only non-active apps (closes [#4691](https://github.com/lwouis/alt-tab-macos/issues/4691)) ([4567550](https://github.com/lwouis/alt-tab-macos/commit/4567550))
* improve norwegian localization ([726e13e](https://github.com/lwouis/alt-tab-macos/commit/726e13e))
* more fine-grained cursor-follows-focus preference (closes [#4734](https://github.com/lwouis/alt-tab-macos/issues/4734)) ([985a681](https://github.com/lwouis/alt-tab-macos/commit/985a681))
2025-09-15 20:18:27 +00:00
lwouis 78c852514f feat: add hong-kong cantonese + improve other languages 2025-09-15 22:10:41 +02:00
lwouis 985a681d72 feat: more fine-grained cursor-follows-focus preference (closes #4734) 2025-09-15 22:10:41 +02:00
lwouis 3c79840a29 fix: improve detection of windows (closes #4405) 2025-08-29 22:04:39 +02:00
lwouis 95ee614d9f refactor: improve logging and subscribeToNotification 2025-08-29 18:52:01 +02:00
lwouis 591ce5274f fix: focusing windows could fail after focusing a frozen app (#4520)
also generally reworked and improved background work handling
2025-08-29 10:00:43 +02:00
lwouis 3f18951368 refactor: improve running-applications handler 2025-08-29 10:00:43 +02:00
lwouis be077f1a67 fix: keyboard selection now works with dragging + mouse hover
(closes #4711)
2025-08-27 19:50:33 +02:00
lwouis 1a4b53917d chore: fix localization scripts 2025-08-27 19:50:33 +02:00
lwouis 726e13edcd feat: improve norwegian localization 2025-08-27 19:50:32 +02:00
lwouis 4ebd990e30 feat: add gujarati localization 2025-08-27 19:50:32 +02:00
lwouis 4567550978 feat: add preference to show only non-active apps (closes #4691) 2025-08-27 19:50:32 +02:00
lwouis f489bd7d36 ci: bring back appcenter symbols upload until june 2026 2025-08-27 19:50:32 +02:00
lwouis e93e42f952 fix: remove high-volume unactionable logs (closes #4697) 2025-08-22 21:09:05 +02:00
semantic-release-bot 250c9c4bce chore(release): 7.27.0 [skip ci]
# [7.27.0](https://github.com/lwouis/alt-tab-macos/compare/v7.26.0...v7.27.0) (2025-08-12)

### Bug Fixes

* restore default command+tab if shortcut is unbound (closes [#4642](https://github.com/lwouis/alt-tab-macos/issues/4642)) ([f66c92a](https://github.com/lwouis/alt-tab-macos/commit/f66c92a))

### Features

* improve cs/th localizations ([aa46a62](https://github.com/lwouis/alt-tab-macos/commit/aa46a62))
* windowless apps can now be shown in focus-order (closes [#4653](https://github.com/lwouis/alt-tab-macos/issues/4653)) ([5db53b5](https://github.com/lwouis/alt-tab-macos/commit/5db53b5))
2025-08-12 20:02:54 +00:00
lwouis aa46a62457 feat: improve cs/th localizations 2025-08-12 16:33:17 +02:00
lwouis f66c92aefb fix: restore default command+tab if shortcut is unbound (closes #4642) 2025-08-12 16:26:32 +02:00
Inês Almeida a696611615 docs: fix broken link to private api documentation 2025-08-12 14:24:30 +02:00
lwouis 5db53b5a9e feat: windowless apps can now be shown in focus-order (closes #4653) 2025-08-11 11:41:05 +02:00
semantic-release-bot e9e732756e chore(release): 7.26.0 [skip ci]
# [7.26.0](https://github.com/lwouis/alt-tab-macos/compare/v7.25.0...v7.26.0) (2025-07-31)

### Bug Fixes

* ignore autodesk fusion internal panels (closes [#4578](https://github.com/lwouis/alt-tab-macos/issues/4578)) ([f67d182](https://github.com/lwouis/alt-tab-macos/commit/f67d182))

### Features

* improve da/fi/ga localizations ([f376529](https://github.com/lwouis/alt-tab-macos/commit/f376529))
* improve preference to show-apps-with-open-window (closes [#4485](https://github.com/lwouis/alt-tab-macos/issues/4485)) ([67f5098](https://github.com/lwouis/alt-tab-macos/commit/67f5098))
2025-07-31 17:55:19 +00:00
lwouis ca96b85352 ci: more portable unicode sorting for contributors 2025-07-31 19:48:59 +02:00
lwouis 67f5098c95 feat: improve preference to show-apps-with-open-window (closes #4485) 2025-07-31 12:01:32 +02:00
lwouis f37652942d feat: improve da/fi/ga localizations 2025-07-29 10:43:28 +02:00
Gregory f67d182a92 fix: ignore autodesk fusion internal panels (closes #4578) 2025-07-01 10:34:54 +02:00
semantic-release-bot b325cc75c0 chore(release): 7.25.0 [skip ci]
# [7.25.0](https://github.com/lwouis/alt-tab-macos/compare/v7.24.0...v7.25.0) (2025-06-14)

### Bug Fixes

* icons on thumbnails could sometimes be incorrect ([b4bc0b0](https://github.com/lwouis/alt-tab-macos/commit/b4bc0b0))

### Features

* new cli commands: --show, --detailed-list (closes [#4489](https://github.com/lwouis/alt-tab-macos/issues/4489)) ([b0ce899](https://github.com/lwouis/alt-tab-macos/commit/b0ce899))
2025-06-14 12:29:24 +00:00
lwouis 6cc76903b0 docs: update contributors list 2025-06-14 14:18:55 +02:00
lwouis b4bc0b006a fix: icons on thumbnails could sometimes be incorrect
example use-case: show a Finder window, and middle-click it. The next thumbnail under the mouse will not show its purple quit icon
2025-06-14 14:18:55 +02:00
lwouis b0ce899a71 feat: new cli commands: --show, --detailed-list (closes #4489) 2025-06-14 14:18:55 +02:00
semantic-release-bot bd162a9e08 chore(release): 7.24.0 [skip ci]
# [7.24.0](https://github.com/lwouis/alt-tab-macos/compare/v7.23.0...v7.24.0) (2025-05-05)

### Features

* clicking to focus windows/apps is now easier (closes [#4407](https://github.com/lwouis/alt-tab-macos/issues/4407)) ([397457c](https://github.com/lwouis/alt-tab-macos/commit/397457c))
* improve ca/pt/ro localizations ([8b7d69c](https://github.com/lwouis/alt-tab-macos/commit/8b7d69c))

### Performance Improvements

* avoid updating preview if not necessary ([518f8b4](https://github.com/lwouis/alt-tab-macos/commit/518f8b4))
2025-05-05 10:07:24 +00:00
lwouis 8b7d69c0ff feat: improve ca/pt/ro localizations 2025-05-05 12:02:25 +02:00
lwouis 518f8b402e perf: avoid updating preview if not necessary 2025-05-05 11:59:14 +02:00
lwouis 397457cacb feat: clicking to focus windows/apps is now easier (closes #4407) 2025-04-04 19:32:04 +02:00
semantic-release-bot eee0db133c chore(release): 7.23.0 [skip ci]
# [7.23.0](https://github.com/lwouis/alt-tab-macos/compare/v7.22.0...v7.23.0) (2025-04-01)

### Bug Fixes

* avoid crashing on uncommon keys in shortcuts (closes [#4379](https://github.com/lwouis/alt-tab-macos/issues/4379)) ([9d852ee](https://github.com/lwouis/alt-tab-macos/commit/9d852ee))
* window name would sometimes be empty (closes [#4350](https://github.com/lwouis/alt-tab-macos/issues/4350)) ([911c3c1](https://github.com/lwouis/alt-tab-macos/commit/911c3c1))

### Features

* improve hindi localization ([dec0519](https://github.com/lwouis/alt-tab-macos/commit/dec0519))
2025-04-01 21:38:28 +00:00
lwouis dec05198c7 feat: improve hindi localization 2025-04-01 23:31:45 +02:00
lwouis 911c3c17c5 fix: window name would sometimes be empty (closes #4350) 2025-04-01 10:43:24 +02:00
lwouis 9d852eee9c fix: avoid crashing on uncommon keys in shortcuts (closes #4379) 2025-03-31 12:09:04 +02:00
semantic-release-bot 17e1f1e4c7 chore(release): 7.22.0 [skip ci]
# [7.22.0](https://github.com/lwouis/alt-tab-macos/compare/v7.21.1...v7.22.0) (2025-03-30)

### Bug Fixes

* language switcher picked up as window ([f4f7d9a](https://github.com/lwouis/alt-tab-macos/commit/f4f7d9a))
* prevent rare crash ([4e35f9f](https://github.com/lwouis/alt-tab-macos/commit/4e35f9f))

### Features

* update ca/de/fr/ko/ru/tw localizations ([9b3f936](https://github.com/lwouis/alt-tab-macos/commit/9b3f936))
2025-03-30 00:58:26 +00:00
lwouis c0ac29fdd8 ci: remove appcenter upload 2025-03-30 01:51:26 +01:00
lwouis 9b3f93688e feat: update ca/de/fr/ko/ru/tw localizations 2025-03-30 01:34:58 +01:00
Yaros f4f7d9addc fix: language switcher picked up as window 2025-03-30 01:29:18 +01:00
lwouis 4e35f9f290 fix: prevent rare crash 2025-02-23 21:06:22 +01:00
semantic-release-bot 820b6ea3aa chore(release): 7.21.1 [skip ci]
## [7.21.1](https://github.com/lwouis/alt-tab-macos/compare/v7.21.0...v7.21.1) (2025-02-22)

### Bug Fixes

* update how feedback messages are sent ([647f900](https://github.com/lwouis/alt-tab-macos/commit/647f900))
2025-02-22 09:54:48 +00:00
lwouis 647f900b85 fix: update how feedback messages are sent 2025-02-22 10:50:11 +01:00
semantic-release-bot 6c0f97ffe9 chore(release): 7.21.0 [skip ci]
# [7.21.0](https://github.com/lwouis/alt-tab-macos/compare/v7.20.1...v7.21.0) (2025-02-21)

### Bug Fixes

* app would sometimes crash (closes [#4244](https://github.com/lwouis/alt-tab-macos/issues/4244)) ([d543393](https://github.com/lwouis/alt-tab-macos/commit/d543393))

### Features

* add lithuanian localization ([bc95b90](https://github.com/lwouis/alt-tab-macos/commit/bc95b90))
* improve chinese localization ([330ac54](https://github.com/lwouis/alt-tab-macos/commit/330ac54))
2025-02-21 21:33:37 +00:00
lwouis bc95b905af feat: add lithuanian localization 2025-02-21 22:27:58 +01:00
lwouis 330ac54c6f feat: improve chinese localization 2025-02-21 22:15:57 +01:00
lwouis 54249d03dd refactor: use new fine-grained token + better logs 2025-02-21 22:01:22 +01:00
lwouis d543393e3f fix: app would sometimes crash (closes #4244) 2025-02-21 21:20:29 +01:00
lwouis ee010de36c refactor: remove unused method 2025-02-20 22:44:26 +01:00
semantic-release-bot 3c7aaafa63 chore(release): 7.20.1 [skip ci]
## [7.20.1](https://github.com/lwouis/alt-tab-macos/compare/v7.20.0...v7.20.1) (2025-02-20)

### Bug Fixes

* may crash when changing space or screen ([b62cec0](https://github.com/lwouis/alt-tab-macos/commit/b62cec0))
2025-02-20 07:11:54 +00:00
lwouis b62cec0cdc fix: may crash when changing space or screen 2025-02-20 08:04:13 +01:00
semantic-release-bot a474660498 chore(release): 7.20.0 [skip ci]
# [7.20.0](https://github.com/lwouis/alt-tab-macos/compare/v7.19.1...v7.20.0) (2025-02-19)

### Bug Fixes

* better detect windows from other spaces (closes [#1324](https://github.com/lwouis/alt-tab-macos/issues/1324)) ([2cd8b96](https://github.com/lwouis/alt-tab-macos/commit/2cd8b96))
* colored circles would go away on ui refresh (closes [#4151](https://github.com/lwouis/alt-tab-macos/issues/4151)) ([dcea005](https://github.com/lwouis/alt-tab-macos/commit/dcea005))
* stage manager no longer skews the thumbnails (closes [#1731](https://github.com/lwouis/alt-tab-macos/issues/1731)) ([93defcd](https://github.com/lwouis/alt-tab-macos/commit/93defcd))
* window might be noted to be on the wrong space ([5413372](https://github.com/lwouis/alt-tab-macos/commit/5413372))

### Features

* add javanese localization ([8564ed2](https://github.com/lwouis/alt-tab-macos/commit/8564ed2))
* improve performance and lower resources consumption ([9d78700](https://github.com/lwouis/alt-tab-macos/commit/9d78700))
* improve thumbnails quality and performance (closes [#4183](https://github.com/lwouis/alt-tab-macos/issues/4183)) ([9d6fc68](https://github.com/lwouis/alt-tab-macos/commit/9d6fc68))
* improve window focusing action ([8dd63c7](https://github.com/lwouis/alt-tab-macos/commit/8dd63c7))
* update fr, kn, pt-br, uk localizations ([fd0411b](https://github.com/lwouis/alt-tab-macos/commit/fd0411b))
2025-02-19 17:48:16 +00:00
lwouis 6e2a5ff081 docs: sunset discord server 2025-02-19 18:40:52 +01:00
lwouis 8dd63c722f feat: improve window focusing action 2025-02-15 20:02:41 +01:00
lwouis e98dff325d refactor: use more accurate type for private apis 2025-02-14 21:46:09 +01:00
lwouis 8d93508062 chore: remove unused param from previous experiment 2025-02-13 11:49:30 +01:00
lwouis fd0411b508 feat: update fr, kn, pt-br, uk localizations 2025-02-13 11:49:30 +01:00
lwouis 8564ed255a feat: add javanese localization 2025-02-13 11:49:29 +01:00
lwouis 9d78700ab7 feat: improve performance and lower resources consumption
avoid unnecessary AX calls and batch calls when possible
2025-02-13 11:49:29 +01:00
lwouis c72fedbb30 refactor: update window fullscreen, size, position, on space change 2025-02-12 18:01:20 +01:00
lwouis e637c61cc9 refactor: debounce high-frequency window events 2025-02-12 18:01:20 +01:00
lwouis dae19ca067 refactor: clarify type and windowless state 2025-02-12 18:01:20 +01:00
lwouis 9d6fc68642 feat: improve thumbnails quality and performance (closes #4183) 2025-02-12 18:01:19 +01:00
lwouis 2cd8b96d38 fix: better detect windows from other spaces (closes #1324)
We found a workaround after more than 3 years of searching!
2025-02-12 18:01:19 +01:00
lwouis 541337259d fix: window might be noted to be on the wrong space 2025-02-03 21:55:47 +01:00
lwouis 93defcd3a7 fix: stage manager no longer skews the thumbnails (closes #1731) 2025-02-03 11:25:47 +01:00
lwouis 69edbbdf42 refactor: improve writing launch-agent and its logs 2025-01-24 10:42:57 +01:00
lwouis dcea005d8d fix: colored circles would go away on ui refresh (closes #4151) 2025-01-22 12:05:52 +01:00
lwouis cfd59d31a1 chore: use a longer datetime format in logs 2025-01-22 12:05:52 +01:00
semantic-release-bot f42ffa61d1 chore(release): 7.19.1 [skip ci]
## [7.19.1](https://github.com/lwouis/alt-tab-macos/compare/v7.19.0...v7.19.1) (2025-01-14)

### Bug Fixes

* a few labels were not displaying (closes [#4127](https://github.com/lwouis/alt-tab-macos/issues/4127)) ([0a22547](https://github.com/lwouis/alt-tab-macos/commit/0a22547))
2025-01-14 21:43:44 +00:00
lwouis 0a2254702f fix: a few labels were not displaying (closes #4127) 2025-01-14 22:37:09 +01:00
semantic-release-bot d02327af2d chore(release): 7.19.0 [skip ci]
# [7.19.0](https://github.com/lwouis/alt-tab-macos/compare/v7.18.1...v7.19.0) (2025-01-14)

### Features

* add preference to toggle animation of preview (closes [#4118](https://github.com/lwouis/alt-tab-macos/issues/4118)) ([c10ca2a](https://github.com/lwouis/alt-tab-macos/commit/c10ca2a))
* middle-click will now close windows and quit applications ([2f8c014](https://github.com/lwouis/alt-tab-macos/commit/2f8c014))
2025-01-14 17:37:05 +00:00
lwouis c10ca2a77e feat: add preference to toggle animation of preview (closes #4118) 2025-01-14 12:24:55 +01:00
lwouis 2f8c01418d feat: middle-click will now close windows and quit applications 2025-01-14 12:24:55 +01:00
semantic-release-bot 3a0c84a8f5 chore(release): 7.18.1 [skip ci]
## [7.18.1](https://github.com/lwouis/alt-tab-macos/compare/v7.18.0...v7.18.1) (2025-01-12)

### Bug Fixes

* don't check screen-recording permission if unnecessary ([f3b116e](https://github.com/lwouis/alt-tab-macos/commit/f3b116e)), closes [#4113](https://github.com/lwouis/alt-tab-macos/issues/4113)
* show shadows around thumbnails (closes [#4068](https://github.com/lwouis/alt-tab-macos/issues/4068)) ([597b443](https://github.com/lwouis/alt-tab-macos/commit/597b443))
2025-01-12 21:33:06 +00:00
lwouis 597b443796 fix: show shadows around thumbnails (closes #4068) 2025-01-12 22:25:45 +01:00
lwouis 0ea925289b docs: clarify what the screen-recording permission is used for 2025-01-12 22:25:45 +01:00
lwouis f3b116e47c fix: don't check screen-recording permission if unnecessary
closes #4113
2025-01-12 22:25:45 +01:00
lwouis 4c3ec7d067 refactor: use swift shorthand for optional check 2025-01-12 22:25:45 +01:00
lwouis 941d8afb9a chore: document why we use CGSHWCaptureWindowList 2025-01-12 22:25:45 +01:00
lwouis 8e41662088 chore: test out SCScreenshotManager.captureImage 2025-01-12 22:25:44 +01:00
semantic-release-bot 71bb2d889b chore(release): 7.18.0 [skip ci]
# [7.18.0](https://github.com/lwouis/alt-tab-macos/compare/v7.17.0...v7.18.0) (2025-01-07)

### Bug Fixes

* various issues with the app freezing or being slowly ([121515c](https://github.com/lwouis/alt-tab-macos/commit/121515c))
* window order on first display was wrong ([db5644e](https://github.com/lwouis/alt-tab-macos/commit/db5644e))
* window preview was not showing in titles style ([684cc66](https://github.com/lwouis/alt-tab-macos/commit/684cc66))

### Features

* improve polish localization ([c712473](https://github.com/lwouis/alt-tab-macos/commit/c712473))
2025-01-07 00:20:50 +00:00
lwouis c712473c7a feat: improve polish localization 2025-01-07 01:16:05 +01:00
lwouis 121515cbc7 fix: various issues with the app freezing or being slowly 2025-01-07 01:12:06 +01:00
lwouis 8b52dc8acb chore: add testbed file if i ever need to investigate again 2025-01-07 01:09:37 +01:00
lwouis db5644e058 fix: window order on first display was wrong 2025-01-06 23:29:15 +01:00
lwouis 684cc666d3 fix: window preview was not showing in titles style 2025-01-06 14:25:40 +01:00
lwouis dfff608ad1 docs: document cli usage on the website 2025-01-05 22:55:11 +01:00
semantic-release-bot f1c5ae73c2 chore(release): 7.17.0 [skip ci]
# [7.17.0](https://github.com/lwouis/alt-tab-macos/compare/v7.16.0...v7.17.0) (2025-01-05)

### Bug Fixes

* app icons could sometimes be at the wrong size ([d5d1311](https://github.com/lwouis/alt-tab-macos/commit/d5d1311))
* more robust screen-recording permission detection ([d85ec7b](https://github.com/lwouis/alt-tab-macos/commit/d85ec7b))

### Features

* handle cli commands: --list and --focus=window_id ([0f2c0e7](https://github.com/lwouis/alt-tab-macos/commit/0f2c0e7))
2025-01-05 18:28:55 +00:00
lwouis d85ec7bcfb fix: more robust screen-recording permission detection 2025-01-05 19:21:53 +01:00
lwouis 2855b1bb0b refactor: cache more runningapplication properties for perf 2025-01-05 19:21:53 +01:00
lwouis 2a616e2518 chore: remove unused xcode flag during run 2025-01-05 19:21:53 +01:00
lwouis d5d131185e fix: app icons could sometimes be at the wrong size 2025-01-05 19:21:53 +01:00
lwouis 0f2c0e794c feat: handle cli commands: --list and --focus=window_id 2025-01-05 19:21:53 +01:00
lwouis d4e697c0de docs: document why we don't see queue labels in instruments 2025-01-04 13:28:20 +01:00
semantic-release-bot 720dde1c06 chore(release): 7.16.0 [skip ci]
# [7.16.0](https://github.com/lwouis/alt-tab-macos/compare/v7.15.0...v7.16.0) (2025-01-04)

### Bug Fixes

* app badges could be incorrectly positioned on the very first launch ([c2ccccd](https://github.com/lwouis/alt-tab-macos/commit/c2ccccd))
* app-icons wouldn't show when permissions were skipped ([837fa03](https://github.com/lwouis/alt-tab-macos/commit/837fa03))
* screen recording warnings shouldn't appear with skipped permissions ([f027b47](https://github.com/lwouis/alt-tab-macos/commit/f027b47))

### Features

* improve performance by caching preferences better ([d653a54](https://github.com/lwouis/alt-tab-macos/commit/d653a54))
2025-01-04 01:31:33 +00:00
lwouis 1e017475ff refactor: improve naming 2025-01-04 02:24:03 +01:00
lwouis 95e51d1c27 refactor: more performant methods used 2025-01-04 01:36:15 +01:00
lwouis d653a54fc3 feat: improve performance by caching preferences better 2025-01-04 01:18:50 +01:00
lwouis c2ccccd093 fix: app badges could be incorrectly positioned on the very first launch 2025-01-04 01:08:36 +01:00
lwouis 837fa03f64 fix: app-icons wouldn't show when permissions were skipped
also cached NSScreen.preferred for performance
2025-01-03 23:40:01 +01:00
lwouis f027b4795f fix: screen recording warnings shouldn't appear with skipped permissions 2025-01-03 23:33:55 +01:00
lwouis 6ede54e3e0 refactor: avoid re-fetching runningapplication data for perf 2025-01-03 19:15:06 +01:00
lwouis 922d259193 chore: set xcode to be able to profile alttab 2025-01-03 19:13:17 +01:00
lwouis 56075b5766 refactor: split private apis for clarity 2025-01-03 16:10:40 +01:00
lwouis b0f02c6a36 refactor: separate protocol methods for clarity + clarify required init 2025-01-03 13:58:11 +01:00
lwouis de1326e118 refactor: separate protocol methods for clarity 2025-01-03 13:58:10 +01:00
lwouis 53d1d1fded refactor: reformat + app code inspect + split protocol 2025-01-03 13:58:10 +01:00
lwouis e17f427a5d refactor: reformat + app code inspect 2025-01-03 13:58:10 +01:00
lwouis df5af7d60c refactor: reformat 2025-01-03 13:58:10 +01:00
lwouis 702cb0d140 refactor: split privateapis into used and experiments 2025-01-03 13:58:10 +01:00
lwouis 9e415bff54 refactor: reformat 2025-01-03 13:58:08 +01:00
lwouis a696a0e0b2 chore: update swiftformat rules
swift format does a wrapping that i find too rough, so we can't really use it at the moment, unfortunately
2025-01-03 11:45:55 +01:00
lwouis 52026701e4 refactor: simplify 2025-01-03 11:45:55 +01:00
lwouis 7471488e33 refactor: split preferences and other reorganisation 2025-01-03 11:45:55 +01:00
lwouis 0ef8a0b2d4 refactor: organizing and separating things better 2025-01-03 11:45:54 +01:00
semantic-release-bot 76a72a5ead chore(release): 7.15.0 [skip ci]
# [7.15.0](https://github.com/lwouis/alt-tab-macos/compare/v7.14.1...v7.15.0) (2025-01-02)

### Bug Fixes

* better position preview for fullscreen windows (closes [#4051](https://github.com/lwouis/alt-tab-macos/issues/4051)) ([3b0cba4](https://github.com/lwouis/alt-tab-macos/commit/3b0cba4))
* layout was sometimes broken in app-icons style (closes [#4036](https://github.com/lwouis/alt-tab-macos/issues/4036)) ([be5eb26](https://github.com/lwouis/alt-tab-macos/commit/be5eb26))

### Features

* improve chinese-taiwanese localization ([dfcf9de](https://github.com/lwouis/alt-tab-macos/commit/dfcf9de))
* improve performance and order accuracy at launch ([fc6d636](https://github.com/lwouis/alt-tab-macos/commit/fc6d636))
* improve quality of thumbnails and performance ([a138a92](https://github.com/lwouis/alt-tab-macos/commit/a138a92))
* reduce space between app icon and window title ([295eb2b](https://github.com/lwouis/alt-tab-macos/commit/295eb2b))
* switcher displays faster; other performance improvements ([b51ff65](https://github.com/lwouis/alt-tab-macos/commit/b51ff65))
2025-01-02 18:33:18 +00:00
lwouis 3b0cba493b fix: better position preview for fullscreen windows (closes #4051) 2025-01-02 19:28:35 +01:00
lwouis bc9f97f852 chore: remove unchanging param 2025-01-02 19:28:35 +01:00
lwouis 295eb2bd60 feat: reduce space between app icon and window title 2025-01-02 19:28:35 +01:00
lwouis dfcf9de78e feat: improve chinese-taiwanese localization 2025-01-02 19:28:35 +01:00
lwouis fc6d63603a feat: improve performance and order accuracy at launch 2025-01-02 19:28:34 +01:00
lwouis 9156ad915a refactor: clarify a nstextfield workaround 2025-01-02 19:28:34 +01:00
lwouis a138a922ef feat: improve quality of thumbnails and performance 2025-01-02 19:28:34 +01:00
lwouis b51ff6583d feat: switcher displays faster; other performance improvements 2025-01-02 01:55:27 +01:00
lwouis 7207ad6da7 chore: variadic param was not passed correctly; logging was messy 2024-12-30 23:55:15 +01:00
lwouis e3fafbc6ff chore: migrations would play when debugging local builds 2024-12-30 23:43:50 +01:00
lwouis be5eb26385 fix: layout was sometimes broken in app-icons style (closes #4036) 2024-12-30 12:17:02 +01:00
lwouis e9b529a644 chore: clean up 2 values which are constant 2024-12-30 12:15:56 +01:00
lwouis 250a1bcc81 chore: organize codesign script 2024-12-30 11:12:52 +01:00
semantic-release-bot 96edb065d7 chore(release): 7.14.1 [skip ci]
## [7.14.1](https://github.com/lwouis/alt-tab-macos/compare/v7.14.0...v7.14.1) (2024-12-28)

### Bug Fixes

* improve label display in app-icons style ([7e501a4](https://github.com/lwouis/alt-tab-macos/commit/7e501a4))
* title would sometimes not show when mouse hovering ([dd05ba2](https://github.com/lwouis/alt-tab-macos/commit/dd05ba2))
2024-12-28 18:26:04 +00:00
lwouis 7e501a460a fix: improve label display in app-icons style 2024-12-28 19:20:15 +01:00
lwouis dd05ba239e fix: title would sometimes not show when mouse hovering
this would happen in AppIcons Style, when a window changed in the background, while AltTab was open
2024-12-28 19:20:14 +01:00
lwouis b373fc465b chore: use a constraint add-or-update helper to avoid conflicts 2024-12-28 19:20:14 +01:00
lwouis f92f7ca803 chore: fix new compilation errors from xcode 16.2 2024-12-28 19:20:14 +01:00
lwouis 51062a2499 ci: add add_terms script + organize scripts 2024-12-28 19:20:14 +01:00
semantic-release-bot 48a3967b82 chore(release): 7.14.0 [skip ci]
# [7.14.0](https://github.com/lwouis/alt-tab-macos/compare/v7.13.1...v7.14.0) (2024-12-26)

### Bug Fixes

* improve acknowledgments tab (closes [#4025](https://github.com/lwouis/alt-tab-macos/issues/4025)) ([db5500f](https://github.com/lwouis/alt-tab-macos/commit/db5500f))

### Features

* clear feedback form after submission (closes [#4026](https://github.com/lwouis/alt-tab-macos/issues/4026)) ([42bbd0f](https://github.com/lwouis/alt-tab-macos/commit/42bbd0f))
* improve chinese, irish, italian localizations ([18ef16f](https://github.com/lwouis/alt-tab-macos/commit/18ef16f))
* swipes can now be horizontal or vertical (closes [#4020](https://github.com/lwouis/alt-tab-macos/issues/4020)) ([fda3ada](https://github.com/lwouis/alt-tab-macos/commit/fda3ada))
2024-12-26 23:41:18 +00:00
lwouis 18ef16f6ee feat: improve chinese, irish, italian localizations 2024-12-27 00:33:05 +01:00
lwouis fda3ada055 feat: swipes can now be horizontal or vertical (closes #4020)
swipe recognition has also been improved in many ways
2024-12-27 00:33:05 +01:00
lwouis db5500f130 fix: improve acknowledgments tab (closes #4025) 2024-12-25 01:51:23 +01:00
lwouis 42bbd0fe01 feat: clear feedback form after submission (closes #4026) 2024-12-25 01:04:12 +01:00
lwouis b257752812 chore: make local setup work with openssl v3.x 2024-12-25 00:53:33 +01:00
lwouis 54b7c8d697 chore: update svg-to-png script 2024-12-24 15:32:57 +01:00
lwouis bcafd0790f chore: fix utils folder in pbxproj 2024-12-24 11:46:20 +01:00
semantic-release-bot e07da9cad9 chore(release): 7.13.1 [skip ci]
## [7.13.1](https://github.com/lwouis/alt-tab-macos/compare/v7.13.0...v7.13.1) (2024-12-24)

### Bug Fixes

* acknowledgments tab was hard to read in dark mode (closes [#4019](https://github.com/lwouis/alt-tab-macos/issues/4019)) ([4481d94](https://github.com/lwouis/alt-tab-macos/commit/4481d94))
* app crash from v7.13.0 (closes [#4016](https://github.com/lwouis/alt-tab-macos/issues/4016)) ([d3b5bef](https://github.com/lwouis/alt-tab-macos/commit/d3b5bef))
2024-12-24 09:02:02 +00:00
lwouis d3b5befe3e fix: app crash from v7.13.0 (closes #4016) 2024-12-24 09:55:20 +01:00
lwouis 4481d94fa2 fix: acknowledgments tab was hard to read in dark mode (closes #4019) 2024-12-24 09:55:20 +01:00
lwouis 982a6dd5f2 chore: improve project settings 2024-12-24 09:55:20 +01:00
semantic-release-bot 898fc8c13c chore(release): 7.13.0 [skip ci]
# [7.13.0](https://github.com/lwouis/alt-tab-macos/compare/v7.12.0...v7.13.0) (2024-12-24)

### Bug Fixes

* enabling previews with multiple screens could lead to flickering ([87a2b21](https://github.com/lwouis/alt-tab-macos/commit/87a2b21))
* prevent initial window lastFocusOrder overlaps ([d32f953](https://github.com/lwouis/alt-tab-macos/commit/d32f953))
* previews on multiple screens could get misplaced ([2a0a858](https://github.com/lwouis/alt-tab-macos/commit/2a0a858))
* titles could sometimes be covered when in small size ([c5e13cc](https://github.com/lwouis/alt-tab-macos/commit/c5e13cc))

### Features

* add fade-in for window previews (closes [#2456](https://github.com/lwouis/alt-tab-macos/issues/2456)) ([40c9a18](https://github.com/lwouis/alt-tab-macos/commit/40c9a18))
* allow vertical swipes as trigger (closes [#4012](https://github.com/lwouis/alt-tab-macos/issues/4012)) ([9adf64c](https://github.com/lwouis/alt-tab-macos/commit/9adf64c))
* improve localizations ([6d9059e](https://github.com/lwouis/alt-tab-macos/commit/6d9059e))
* reduce disk size of localizations ([9ec2762](https://github.com/lwouis/alt-tab-macos/commit/9ec2762))
* swiping won't wrap-around to other rows (closes [#3983](https://github.com/lwouis/alt-tab-macos/issues/3983)) ([6215b65](https://github.com/lwouis/alt-tab-macos/commit/6215b65))
2024-12-24 01:55:39 +00:00
lwouis 9ec2762bff feat: reduce disk size of localizations 2024-12-24 02:48:27 +01:00
lwouis 6d9059ee86 feat: improve localizations 2024-12-24 02:30:53 +01:00
lwouis ef6ab620fb refactor: replace titles with nstextfield for performance 2024-12-24 02:17:59 +01:00
lwouis ecf4cb15be chore: improve poeditor override scripts 2024-12-24 02:17:59 +01:00
lwouis c9d36b5bad chore: add script to upload local l10n context to poeditor 2024-12-24 02:17:59 +01:00
lwouis 9e932799ee refactor: use auto-released notification observer api 2024-12-24 02:17:59 +01:00
lwouis 6215b65ec9 feat: swiping won't wrap-around to other rows (closes #3983) 2024-12-24 02:17:58 +01:00
lwouis 9adf64c374 feat: allow vertical swipes as trigger (closes #4012) 2024-12-24 02:17:58 +01:00
Ben Delaney d32f9533e3 fix: prevent initial window lastFocusOrder overlaps
The `sortByLevel` method in the Windows class has been updated to determine window z-order properly across all visible spaces. It now sets the `lastFocusOrder` for each window, using a map from window IDs to their z-order position. Windows not present in the list are set to have `lastFocusOrder` of `Int.max`. Afterwards, windows are sorted by their `lastFocusOrder`, and these values are ensured to be monotonic, starting from 0.
2024-12-24 02:17:58 +01:00
Ben Delaney 2a0a8585df fix: previews on multiple screens could get misplaced 2024-12-24 02:17:58 +01:00
Ben Delaney 87a2b219a5 fix: enabling previews with multiple screens could lead to flickering 2024-12-24 02:17:58 +01:00
allsochen c5e13ccc84 fix: titles could sometimes be covered when in small size 2024-12-24 02:17:58 +01:00
lwouis 40c9a18be4 feat: add fade-in for window previews (closes #2456) 2024-12-12 21:38:39 +01:00
semantic-release-bot 8a4aa7908f chore(release): 7.12.0 [skip ci]
# [7.12.0](https://github.com/lwouis/alt-tab-macos/compare/v7.11.0...v7.12.0) (2024-12-11)

### Bug Fixes

* switcher could appear collapsed in titles style (closes [#3744](https://github.com/lwouis/alt-tab-macos/issues/3744)) ([60534bc](https://github.com/lwouis/alt-tab-macos/commit/60534bc))

### Features

* acknowledgments tab was slow to display (closes [#3957](https://github.com/lwouis/alt-tab-macos/issues/3957)) ([41ddd7c](https://github.com/lwouis/alt-tab-macos/commit/41ddd7c))
2024-12-11 20:59:03 +00:00
lwouis 82879e39e7 docs: update contributors 2024-12-11 21:53:55 +01:00
lwouis 60534bcfe3 fix: switcher could appear collapsed in titles style (closes #3744) 2024-12-11 21:51:09 +01:00
lwouis 41ddd7c1a6 feat: acknowledgments tab was slow to display (closes #3957) 2024-12-10 23:17:01 +01:00
semantic-release-bot 5601a556c9 chore(release): 7.11.0 [skip ci]
# [7.11.0](https://github.com/lwouis/alt-tab-macos/compare/v7.10.0...v7.11.0) (2024-12-09)

### Bug Fixes

* always show a window in show:apps mode (closes [#3950](https://github.com/lwouis/alt-tab-macos/issues/3950)) ([ac70fcc](https://github.com/lwouis/alt-tab-macos/commit/ac70fcc))

### Features

* decrease shortcuts from 5 to 3 ([d65f220](https://github.com/lwouis/alt-tab-macos/commit/d65f220))
* improve chinese localization ([764e0f3](https://github.com/lwouis/alt-tab-macos/commit/764e0f3))
* improve focus in show:apps mode (closes [#3951](https://github.com/lwouis/alt-tab-macos/issues/3951)) ([cb191d6](https://github.com/lwouis/alt-tab-macos/commit/cb191d6))
* support 3 or 4 finger swipes to use the app (closes [#730](https://github.com/lwouis/alt-tab-macos/issues/730)) ([903e758](https://github.com/lwouis/alt-tab-macos/commit/903e758))
* switcher will now show in "show desktop" mode (closes [#783](https://github.com/lwouis/alt-tab-macos/issues/783)) ([9b85f00](https://github.com/lwouis/alt-tab-macos/commit/9b85f00))
2024-12-09 23:06:18 +00:00
lwouis 764e0f3f25 feat: improve chinese localization 2024-12-09 23:52:41 +01:00
lwouis 3619807cb9 refactor: clean up trackpad-events 2024-12-09 23:52:40 +01:00
lwouis d65f220530 feat: decrease shortcuts from 5 to 3 2024-12-09 19:33:49 +01:00
Saswat Bhattacharya 903e758528 feat: support 3 or 4 finger swipes to use the app (closes #730) 2024-12-09 19:33:43 +01:00
lwouis 9b85f00564 feat: switcher will now show in "show desktop" mode (closes #783) 2024-12-09 14:12:06 +01:00
lwouis cb191d60f3 feat: improve focus in show:apps mode (closes #3951) 2024-12-09 14:12:06 +01:00
lwouis ac70fcc5f9 fix: always show a window in show:apps mode (closes #3950) 2024-12-08 18:16:15 +01:00
1999 changed files with 105539 additions and 85788 deletions

No files matched your search

+193
View File
@@ -0,0 +1,193 @@
---
name: assets-optimization
description: Audit and optimize every image asset shipped with AltTab. Apply the right format per asset class (PDF for vectors, HEIC for raster) and the right post-processing (strip Figma cruft from PDFs, extract SF Symbols as minimal vector PDFs, encode raster sources to HEIC at q50 with visual review). Use whenever new assets are added, when the bundle size needs shrinking, or whenever you want a full assets audit.
---
# /assets-optimization — AltTab asset audit and optimization
## Goal
Every byte that ships in `AltTab.app/Contents/Resources/` should justify itself. Vectors stay vector, rasters compress to HEIC, and neither carries metadata, color profiles, accessibility tags, or producer signatures that AppKit doesn't use.
This skill applies a known-good pipeline to each asset class. It is opinionated about the right format and the right encoder for each kind of content.
## When to use
- A designer drops new exports into `~/Desktop/` or `resources/`.
- Someone asks "why is the bundle so big?".
- After adding a new icon, illustration, app icon variant, or menubar variant.
- Periodic audit when nothing else is broken.
## Step 1: Inventory
Run a one-shot enumeration so you know what you're working with:
```sh
find resources -type f \( -iname '*.pdf' -o -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.heic' -o -iname '*.svg' -o -iname '*.icns' \) \
-exec ls -la {} \; | awk '{printf "%8d %s\n", $5, $9}' | sort -k2
```
Group what you see by directory. For AltTab the relevant buckets are:
- `resources/icons/menubar/` — small template icons shown in the macOS menubar.
- `resources/icons/tabs/` — Preferences sidebar icons (template, sized ~13pt).
- `resources/icons/permission-window/` — first-launch permission window icons (~32pt).
- `resources/icons/app/` — the macOS app icon (`.icns` + `.iconset/`). **Don't touch** — `.icns` is required by the bundle and Apple's tooling produces near-optimal output already.
- `resources/illustrations/` — the appearance-tab preview thumbnails. Raster (screenshots inside).
For each asset, decide what category it falls into:
| Source content | Right format | Why |
|---|---|---|
| Custom vector design (Figma/Sketch/Illustrator) | **PDF** | macOS 10.13 doesn't accept SVG; PDF is the universal vector container AppKit reads natively. |
| SF Symbol (Apple system glyph) | **Font glyph** in the bundled `SF-Pro-Text-Regular.otf` subset | Render via `NSImage.fromSymbol(.foo, pointSize:)` (or as text via the `Symbols` enum). Smaller than per-icon PDFs, picks up Apple's latest glyph refinements automatically when the developer updates SF Symbols.app. |
| Photographic / screenshot-heavy | **HEIC** | HEIC at q50 beats JPEG by ~30% at the same perceptual quality. |
| Tiny pixel-precise UI sprite | **PNG @2x** | Below ~40×40px the PDF overhead exceeds the bitmap savings. PNG wins. |
| App icon (the macOS bundle one) | **`.icns`** | Required by `CFBundleIconFile`. |
If an asset is in the wrong format, flag it. If it's in the right format but unoptimized, run the matching pipeline below.
## Step 2: Vector PDFs — Figma exports
Figma's "Export → PDF" output is bloated. For each menubar/illustration/icon vector PDF that came from Figma, you can strip ~50–75% of the bytes without losing a single rendered pixel.
What Figma adds that AppKit doesn't need:
1. **Embedded ICC color profile** (`/ICCBased ...`, ~3.2 KB compressed). Replace every `[/ICCBased N R]` reference with `/DeviceRGB` (or `/DeviceGray` for monochrome). Patches needed in:
- the page `Resources/ColorSpace` dict
- every Form XObject's `Resources/ColorSpace` dict (these are streams, not plain dicts — pikepdf's `pdf.objects` will only catch them if you accept both `Dictionary` and `Stream`)
- every Image XObject's direct `/ColorSpace` key
- every Shading dict inside `Pattern` entries (Figma's color icons use 8+ patterns, each with its own `/ColorSpace N R` reference)
2. **`/Metadata`** XMP packet (~830 B) — Figma's XML manifest.
3. **`/StructTreeRoot`, `/ParentTree`, `/StructElem`** — accessibility tags ("Document" / "Part" structural roles). AppKit's PDF renderer ignores them.
4. **`/Info` dict** — `Producer="Figma"`, `Title="Menubar 22x22@1x white"`. In Figma's exports the Info dict sometimes lives **inline inside the Catalog** rather than at the trailer level, so deleting `pdf.docinfo` isn't enough — also `del root[Name('/Info')]`.
5. **`/Lang`, `/MarkInfo`, `/Annots`, `/StructParents`, `/Tabs`** — empty or trivial page-level entries.
6. **`/ProcSet [/PDF]`** — deprecated since PDF 1.4.
Use the script:
```sh
python3 scripts/assets/optimize_figma_pdf.py resources/icons/menubar/*.pdf
```
It edits in place and prints the savings per file. After running, also pipe through `mutool clean -ggg -z` and `qpdf --object-streams=generate --recompress-flate --compression-level=9` for the final 1–2% squeeze.
Verify each file still renders by sips'ing it back to PNG and eyeballing:
```sh
for f in resources/icons/menubar/*.pdf; do
sips -s format png "$f" --out "/tmp/$(basename $f .pdf).png" -Z 300 >/dev/null 2>&1
done
```
Open the PNGs in Preview to confirm nothing visual changed.
## Step 3: SF Symbols via font subset
Every SF Symbol shipped in AltTab — switcher status icons, sidebar tab icons, button icons, permission/feedback icons — is rendered as a text glyph from a subsetted SF Pro Text font. There are no SF-Symbol PDFs in the bundle.
How it works: SF Symbols are glyphs in the Private Use Area of SF Pro Text. Apple's `SF-Pro-Text-Regular.otf` contains every symbol they've ever shipped. We subset it down to just the codepoints AltTab needs (currently ~36 glyphs, ~17 KB) into `resources/SF-Pro-Text-Regular.otf`, and register it via `Info.plist:ATSApplicationFontsPath = ""`. At runtime, `NSFont(name: "SF Pro Text", size:)` resolves to the bundled subset on macOS <11 (where the system font isn't installed) and to the system font on macOS 11+, with identical glyph appearance either way.
To add a new SF Symbol:
1. Open [SF Symbols.app](https://developer.apple.com/sf-symbols/), search for the symbol, press **Cmd-C** to copy the symbol character to the clipboard. (Apple's name→codepoint mapping is not exposed via public API, and the SF Pro Text font's cmap uses `uniXXXXXX.medium`-style names rather than semantic ones, so this manual lookup is the authoritative path.)
2. Paste the character into a new case on the `Symbols` enum in [src/switcher/main-window/TileFontIconView.swift](src/switcher/main-window/TileFontIconView.swift) — e.g., `case foo = "􀝥" // SF Symbol name`.
3. Paste the same character at the end of the `--text=` argument in [scripts/assets/subset_font.sh](scripts/assets/subset_font.sh).
4. Run `bash scripts/assets/subset_font.sh`. It reads `/Library/Fonts/SF-Pro-Text-Regular.otf` (installed by SF Symbols.app — a standard developer prerequisite) and writes the regenerated subset to `resources/SF-Pro-Text-Regular.otf`. Picks up Apple's latest glyph refinements automatically.
5. Use it in code: `NSImage.fromSymbol(.foo, pointSize: 14)` returns a template `NSImage`; or `TileFontIconView(symbol: .foo, ...)` for the cached-attributed-string path in the switcher hot loop.
The script runs `pyftsubset` via the project's pipenv environment. Warnings about `MERG`/`meta`/`trak` tables being dropped are normal — those tables aren't relevant to glyph rendering.
### Historical note: SF Symbols via PDF (deprecated, scripts removed)
A previous pipeline shipped each SF Symbol as a per-glyph PDF in `resources/icons/`. The pipeline lives only in git history now (`scripts/assets/export_sf_symbol_pdf.swift` was deleted alongside the migrated PDFs). The technique is worth knowing in case a future need arises (e.g., a multi-color symbol that fonts can't represent):
- The naive route — `NSImage(systemSymbolName:).draw(in:)` against a PDF `CGContext` — produces a **black rectangle**, because Quartz emits `image-mask + fill-rectangle` operators where the rectangle paints over the mask. AppKit bug at the PDF emission level; `paletteColors` config does not fix it.
- The working route was to extract the symbol's vector path directly via private selectors that have been stable across macOS 11–15:
`NSImage(systemSymbolName:).representations[0] (NSSymbolImageRep) → .perform("vectorGlyph") (CUINamedVectorGlyph) → .perform("CGPath") (real CGPath)`.
- The CGPath lives in CUI's internal coordinate space (~2× display points, Y-down) — scale to fit the canvas and flip Y. Walk the path via `CGPath.applyWithBlock` and emit raw PDF operators (`m`, `l`, `c`, `h`, `f`). Non-zero winding fill. Fill with DeviceGray (`0 g`), **not** `NSColor.black.cgColor`, which drags in a ~3.4 KB ICC color profile.
- Final PDF wrapper: 4 objects (Catalog, Pages, Page, Content), no `/Info`, no `/Metadata`, no `/Resources/ColorSpace`. ~750–1800 bytes per icon.
Git: see commit `990c1e79` ("feat: pro improve assets") for the PDF pipeline as-it-was; subsequent commit migrated the SF-Symbol PDFs back to font glyphs.
## Step 4: Raster → HEIC at q50
For anything raster (illustration thumbnails, screenshots inside an icon, anything photographic), HEIC at quality 50 is the baseline. q50 is roughly 50% smaller than JPEG at perceptually-equivalent quality, and at the small display sizes used in this app the artifacts are invisible.
Pipeline (built-in to macOS via `sips`):
```sh
sips -Z 1000 -s format heic -s formatOptions 50 input.png --out output.heic
```
- `-Z 1000` resizes the longest edge to 1000px **preserving aspect ratio**. AltTab's illustration display is 500pt wide, so 1000px is the correct @2x ship size. Anything larger wastes bytes; anything smaller looks soft on Retina.
- `formatOptions 50` is the quality. q50 was chosen after a side-by-side comparison at q20/q35/q50/q65/q80 — q50 was the lowest setting where text in screenshots stayed legible and gradient backgrounds didn't band.
Use the script for batch conversion:
```sh
bash scripts/assets/encode_heic.sh ~/Desktop 1000 50
```
That walks all PNG/JPEG files in the source directory, resizes to longest-edge 1000px at q50 HEIC, writes outputs to `/tmp/heic-out/`.
### Visual review (mandatory)
Before swapping the new HEICs into `resources/`, **always** decode a representative sample back to PNG and visually compare against the source:
```sh
sips -s format png /tmp/heic-out/sample.heic --out /tmp/sample-decoded.png >/dev/null 2>&1
open /tmp/sample-decoded.png /Users/you/Desktop/sample.png
```
Pick the visually most demanding file from the batch — usually one with the most text or the strongest gradients. Confirm:
- No banding in flat color regions
- Text edges still crisp at native display size
- No haloing around anti-aliased edges
- Color rendition matches
If anything looks degraded, bump quality to q60 or q65 and re-batch. The user, not the script, is the final arbiter — show them the sample with sizes before committing.
### Bumping quality
If q50 isn't acceptable, the next quality steps are q60 and q65 — beyond that, returns diminish quickly. q80 is the previous default in this repo and roughly 2× the bytes of q50 for no visible improvement on AltTab's content.
## Step 5: pbxproj registration
Whenever you change the file extension of a resource (.jpg → .heic, .png → .pdf, etc.), update [alt-tab-macos.xcodeproj/project.pbxproj](alt-tab-macos.xcodeproj/project.pbxproj). The places that need patching:
1. **PBXBuildFile section** — comment + the comment inside `fileRef = ... /* name.ext */`.
2. **PBXFileReference section** — comment, `lastKnownFileType` (e.g. `image.pdf`, `image.heic`, `image.png`), and `path = "name.ext"`.
3. **PBXGroup section** — the file's entry inside its parent group's `children`.
4. **PBXResourcesBuildPhase section** — the entry in the main app target's `files`.
For pure extension swaps (no new files), `sed -i '' 's|old\.ext|new.ext|g'` plus a `lastKnownFileType` substitution covers it. For new files, generate new 24-char uppercase-hex object IDs (`python3 -c "import secrets; print(secrets.token_hex(12).upper())"`) and insert in all four places.
If you removed an asset entirely (file deleted from disk), delete its 4 entries from pbxproj — otherwise the build fails with "missing file" or ships dangling references.
## Step 6: Verify
```sh
bash ai/build.sh # must show ** BUILD SUCCEEDED **
bash ai/run.sh # launch the app and visually inspect every asset
```
Walk through every UI surface that loads an asset:
- Menubar icon (default + the two alternates from Preferences → General → Menubar icon)
- Preferences sidebar — 4 tab icons (SF Symbol on macOS 11+, bundled PDF below)
- Permissions window — open by revoking a permission
- Preferences → Appearance — illustration thumbnails change per show/hide row
Compare `git diff --stat` before committing. Asset replacements should net negative on bundle size.
## Reporting
After the run, report:
- File-by-file before/after sizes for everything that changed.
- Total bundle delta in KB.
- Any files left untouched and why (e.g., `app.icns` — bundle-required format).
- The encoder settings used (especially HEIC quality if not q50, so the next person knows).
- Anything the visual review revealed (e.g., "had to bump to q60 for `thumbnails_dark` because gradient banding at q50").
+65
View File
@@ -0,0 +1,65 @@
---
name: audit-specs-tests
description: Audit the AltTab test suite for spec/test/code consistency. For every co-located triad in `src/` (`Foo.swift` + `FooSpecs.md` + `FooTests.swift`), it cross-checks that each XCTest method has a matching scenario line in the spec and vice-versa, flags drift between a scenario's description and the test's doc-comment, and reports orphan tests, orphan scenarios, and unpaired files. Use after adding or editing any `*Tests.swift` / `*Specs.md`, before committing a test change, or to get an overall health check of the suite.
---
# /audit-specs-tests
## Project context
AltTab co-locates tests and a living spec next to the source they cover. The convention (see the plan in `.claude/plans/` and `src/pro/license/` as a worked example) is a **triad** per concept:
```
src/<feature>/
├── Foo.swift # production / kernel (app target, or app+test for kernels)
├── FooSpecs.md # the living spec (not compiled)
└── FooTests.swift # XCTest (unit-tests target only)
```
The spec is **documentation tied 1:1 to the test methods**. Its `## Test scenarios` section lists every test, grouped, as:
```markdown
### A. <Group name>
- **testAFooDoesBar** — one-line description of what it pins.
```
This skill's job is to keep the three in sync: every `func test…` ⇔ exactly one `- **test…** —` spec line, descriptions roughly agree, and no triad is missing a leg.
## What counts as a triad
Pair by base name in the **same folder**: `<Base>Tests.swift` ⇔ `<Base>Specs.md`. A `<Base>.swift` (or a kernel like `SelectionResolver.swift`, `SearchTestable.swift`) in the folder is the code under test, but a spec may legitimately cover several classes (e.g. `LicenseManagerSpecs.md` documents `Clock`/`Keychain`/`LicenseAPI` too) — so a missing same-name `.swift` is a note, not an error.
## Workflow
1. **Enumerate.** Find all test and spec files:
```sh
find src -name '*Tests.swift' | sort
find src -name '*Specs.md' | sort
```
Also list any test files still under `unit-tests/` and flag them as **not yet migrated** (the target end-state is zero test files outside `src/`).
2. **For each `*Tests.swift`, extract the test methods and their doc-comments.** Test names:
```sh
grep -nE '^\s*func test[A-Za-z0-9_]+\(' src/<path>/FooTests.swift
```
For each, capture the immediately-preceding `///` or `//` comment lines (the test's intent) and the enclosing `// MARK: -` group. Note methods wrapped in `#if DEBUG`.
3. **For each `*Specs.md`, parse the scenario index.** In the `## Test scenarios` section, collect every `### <Group>` heading and every `- **testName** — description` bullet. Build the set of spec-listed test names and their descriptions.
4. **Cross-check each triad and classify findings:**
- **Orphan test** — `func testX` exists but no `- **testX** —` line in the spec. (Most common drift; spec is stale.)
- **Orphan scenario** — spec lists `testX` but no `func testX` in the suite. (Test deleted/renamed; spec stale.)
- **Group mismatch** — a test's `// MARK:` group and its spec `###` group disagree (readability drift, not fatal).
- **Description drift** — the spec bullet and the test's doc-comment describe materially different behavior. Judge semantically, don't string-match; only flag real divergence.
- **Unpaired file** — a `*Tests.swift` with no `*Specs.md` (or vice-versa).
5. **Lighter code check (kernels only).** For decision-kernel files (`*Testable.swift`, `*Resolver.swift`), list `public`/`static` entry-point functions and `enum … Decision` cases, and flag any with no scenario referencing them — a hint that a branch is undocumented/untested. Skip this for AppKit-coupled production files (intentionally not unit-tested here).
6. **Optionally repair.** If asked, regenerate a spec's `## Test scenarios` section from the live test methods + their doc-comments (preserving the existing `### Group` order where it matches `// MARK:` sections). Never invent behavior — only restate what the test asserts. Do not edit `*Tests.swift` from this skill.
## Reporting
- A per-triad status table: `folder/Base` · #tests · #scenarios · status (✅ in sync / ⚠️ drift / ❌ unpaired).
- A punch list grouped by finding type (orphan tests, orphan scenarios, description drift, unpaired, undocumented kernel branches), each with the file + line.
- The count of test files still outside `src/` (migration progress).
- If nothing is wrong, say so plainly. Then offer to fix the drift (regenerate stale spec scenario indexes) and list exactly which files would change.
+63
View File
@@ -0,0 +1,63 @@
---
name: coverage-explore
description: Measure AltTab test coverage and record it as documentation. Runs the Test scheme with coverage into a throwaway result bundle, parses the per-file/region report, refreshes the per-feature badge atop each `*Specs.md` and the root `src/coverage.md` table, then suggests the highest-value missing tests. These two markdown outputs are the ONLY stored coverage — no lcov/html/xcresult is kept, and routine test runs don't gather coverage. Use to refresh coverage docs, find untested kernel branches, or decide what to test next.
---
# /coverage-explore
## Project context
AltTab follows the **Humble Object** pattern: logic lives in dependency-free **decision kernels**
(`SelectionResolver.swift`, `SearchModeResolver.swift`, the `*Testable.swift` files) compiled into the
`unit-tests` target and tested in isolation; the AppKit layer (windows, views, event taps) is kept thin
and is deliberately *not* unit-tested. So coverage is meaningful **per kernel / per feature-source** —
those should trend to ~100%, every decision branch exercised — and an aggregate app-wide % is not a
goal.
**Coverage is documentation here, not a build artifact.** The only stored coverage is:
1. the per-feature badge (`> **Line coverage:** …`) atop each `*Specs.md`, and
2. the root **`src/coverage.md`** table.
There is intentionally **nothing else**: no lcov, no HTML, no committed `.xcresult`, and coverage is
**not** gathered on routine runs (`scripts/run_tests.sh`, CI, or Xcode) — only when this skill runs it.
(Coverage isn't usefully viewable in IntelliJ, so there's no IDE-integration artifact to maintain.)
## Workflow
1. **Measure into a throwaway bundle** (then delete it — store nothing technical):
```sh
rm -rf /tmp/altcov.xcresult
set -o pipefail && xcodebuild test \
-project alt-tab-macos.xcodeproj -scheme Test -configuration Release \
-enableCodeCoverage YES -resultBundlePath /tmp/altcov.xcresult | scripts/xcbeautify
```
If the build is red, stop and report — coverage on a failing suite is meaningless.
2. **Parse** `xcrun xccov view --report --json /tmp/altcov.xcresult`. Each `targets[].files[]` has
`path`, `lineCoverage`, `coveredLines`, `executableLines`, `functions[]`. For line-by-line counts of
one file while investigating a gap: `xcrun xccov view --file <abs-path> /tmp/altcov.xcresult`.
3. **Refresh `src/coverage.md`.** Rewrite the table with every `src/` file (excluding `*Tests.swift`)
that the test target compiles, sorted worst-coverage-first, as `| NN% (cov/exec) | \`path\` |`.
Keep the header note explaining the Humble-Object scope and that this + the badges are the only
stored coverage. Update the "updated" date.
4. **Offer to refresh the per-spec badges.** For each `<Base>Specs.md` whose `<Base>.swift` (or kernel)
is in the report, propose updating its `> **Line coverage:** …` line with the new % + today's date.
Ask first; only apply the ones the user accepts. Keep honest notes where a file is intentionally
partial (e.g. `PreferencesMigrations.swift`).
5. **Rank gaps & suggest tests.** For kernels below 100%, list the uncovered functions/regions, map each
to the behavior it represents (read the source), and write ready-to-paste additions: a
`- **testGroupScenario** — …` spec line + a short XCTest stub in that suite's builder style. Don't add
tests automatically unless asked.
6. **Clean up:** `rm -rf /tmp/altcov.xcresult`. Leave no technical coverage files in the tree.
## Reporting
- Headline: a small ascending table of kernel `lineCoverage`, and the delta vs the previous `src/coverage.md`.
- Ranked gap list: file → uncovered function/branch → the behavior it represents.
- Suggested scenarios (spec lines + test stubs) for the top gaps.
- State exactly what was rewritten (`src/coverage.md`, which badges). Flag files that are partial *by
design* (AppKit glue, excluded migrations) so a low number isn't mistaken for a problem.
@@ -0,0 +1,75 @@
---
name: translate-missing-l10n
description: Translate missing l10n strings for AltTab using Claude's multilingual ability. Refreshes the source `Localizable.strings` from current Swift code, finds keys missing in each `<lang>.lproj/Localizable.strings`, translates them, then writes them back via `scripts/l10n/apply_translations.ts`.
---
# /translate-missing-l10n
## Project context
AltTab is a macOS app that helps switch between windows, similar to the Windows alt-tab experience. The strings to translate are mostly Settings UI — some tooltips, dialogs, and general user guidance.
## Target languages (20)
`de, ja, fr, es, zh-CN, pt-BR, nl, ko, it, pl, ar, zh-HK, vi, tr, sv, th, zh-TW, he, id, ru`
(`en` is the source — handled automatically by the apply step.)
## Translation guidelines
- **Format specifiers must be preserved exactly**: `%@`, `%d`, `%1$@`, `%2$@`, `\n`, `\t`. The number and order of specifiers in the translation must match the source. Positional and unindexed forms are interchangeable (`%@ %@` ≡ `%1$@ %2$@`), but the count must match.
- **Do not translate proper nouns**: "AltTab", "macOS", "Mission Control", "Spaces", "Dock".
- **Do not translate modifier key names**: "Cmd", "Option", "Alt", "Shift", "Ctrl", "Control", "Fn", "Command".
- **Use Apple's official platform terminology** for the target locale where one exists. For example, prefer the term Apple uses in macOS System Settings for that locale ("Réglages" vs "Préférences" in French) over a literal translation.
- **Match the source brevity**. Settings strings are short; the translation should be short too. Prefer concise, idiomatic phrasing over literal grammatical completeness.
- **Match macOS tone**: neutral, direct, no exclamation marks unless the source has them.
- **Comments in the source file are engineer guidance, not user-visible text**. Use them to disambiguate meaning, but never include them in the translation.
## Workflow
1. **Refresh the source.** Run:
```sh
bash scripts/l10n/extract_l10n_strings.sh
```
This regenerates `resources/l10n/Localizable.strings` from the current Swift code via `genstrings`.
2. **Parse the source.** Read `resources/l10n/Localizable.strings`. Each entry has the shape:
```
/* engineer comment */
"key" = "value";
```
Build the ordered list of `(comment, key, value)` triples. The `value` for the source is usually identical to `key`, but may include positional indices (`%1$@`, `%2$@`) when there are multiple specifiers.
3. **Compute missing keys per language.** For each of the 20 target languages, read `resources/l10n/<lang>.lproj/Localizable.strings`. Each line is `"key" = "translation";`. A key is **missing** if it's present in the source but either (a) absent from the target file, or (b) present with an empty or whitespace-only value. Treat (b) the same as (a) — produce a real translation.
4. **Stop if nothing is missing.** Report and exit.
5. **Translate.** For each language, produce a translation for each missing key, applying the guidelines above. Do not invent keys; only translate keys that appear in the source. Group your work into batches of 5–10 languages per call to keep individual outputs manageable.
6. **Apply each batch.** Write the batch to a fresh file under `/tmp` (not committed) with this shape:
```json
{
"fr": { "About %@": "À propos de %@", "Quit": "Quitter" },
"ja": { "About %@": "%@について" }
}
```
Then run:
```sh
npx ts-node scripts/l10n/apply_translations.ts /tmp/batch-NN.json
```
The helper:
- Validates format specifiers — translations whose specifier set doesn't match the source value are rejected with a clear error and **not merged**.
- Always rewrites `en.lproj/Localizable.strings` from source **keys** (each entry written as `"key" = "key";` for symmetry) — no need to include `en` in your batch. This avoids leaking genstrings-rewritten values like `%1$@` into the English file when the original source key uses plain `%@`.
- Rewrites each `<lang>.lproj/Localizable.strings` using source order: existing translations are preserved, new translations merged in, and keys no longer in the source are pruned.
- Exits with code `2` if any entries were rejected.
7. **Handle rejections.** If `apply_translations.ts` reports format-specifier mismatches, fix those translations and re-run only the affected language(s) in a follow-up batch. Do not move on while rejections are outstanding.
## Reporting
After the run, report:
- Number of languages processed.
- Total translations produced and merged.
- Any entries you intentionally left untranslated (e.g., the source was already a proper noun) — list them so the user can decide.
- Any format-specifier rejections that required manual fixes.
+1
View File
@@ -0,0 +1 @@
v11.3.0
+9 -3
View File
@@ -1,3 +1,9 @@
github: lwouis
patreon: alt_tab_macos
custom: ["paypal.com/donate/?hosted_button_id=ACYAC3UYCM7CN", "donate.stripe.com/4gw9D7bA3g3O0ikaEF"]
# alt-tab-free [depaywall]: upstream's FUNDING.yml routed the GitHub "Sponsor" button on the fork's
# repo to lwouis (github: lwouis / patreon: alt_tab_macos / ko_fi: alt_tab / a lwouis PayPal button) —
# i.e. every donation would have gone to the author the fork just de-paywalled (PLAN §3.5). It has
# been emptied so NO sponsor button renders and no donation routes to the upstream author.
#
# OWNER-OVERRIDABLE-BEFORE-PUBLISH: to accept sponsorships for THIS fork, uncomment and fill in your
# own handles (do NOT re-add lwouis's). Otherwise leave this file empty / delete it.
# github: <fork-owner-handle>
# custom: ["https://<fork-domain>/donate"]
+175 -16
View File
@@ -1,7 +1,27 @@
# alt-tab-free: fork-owned CI/CD workflow (diverged from upstream lwouis/alt-tab-macos).
# Upstream's ci_cd.yml fires `on: push: branches: [master]` ONLY and is the sole workflow,
# so this fork ADDS a `pull_request:` trigger to gate the sync PR pre-merge (see PLAN §4.2),
# gates every release/push-only step under `if: github.event_name == 'push'`, and wires the
# anti-relock + conflict-marker greps as the FIRST push-job steps so a relocked or conflicted
# tree aborts BEFORE update_appcast.sh (Sparkle sign), semantic-release (tag push), and the
# gh-release. This file is in the §6.2 "keep ours" recurring-conflict set — on an upstream
# ci_cd.yml change, reconcile manually and re-confirm the `pull_request:` trigger survives.
on:
push:
branches:
- master
# alt-tab-free [depaywall]: PR trigger so the sync PR runs the guards pre-merge (PLAN §4.2).
# A separate fork-owned .github/workflows/guard.yml ALSO runs the guards on pull_request, so a
# careless upstream-conflict resolution that strips this trigger cannot silently disarm the gate.
pull_request:
branches:
- master
# alt-tab-free [depaywall]: GitHub defaults GITHUB_TOKEN to read-only since 2023; semantic-release
# (@semantic-release/git) pushes commits+tags to master and softprops/action-gh-release creates the
# release — both need contents:write, else they 403 and the appcast enclosure 404s for auto-update
# (PLAN §4.3).
permissions:
contents: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPCENTER_SECRET: ${{ secrets.APPCENTER_SECRET }}
@@ -10,18 +30,21 @@ env:
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_P12_CERTIFICATE: ${{ secrets.APPLE_P12_CERTIFICATE }}
FEEDBACK_TOKEN: ${{ secrets.FEEDBACK_TOKEN }}
NETLIFY_WEBHOOK: ${{ secrets.NETLIFY_WEBHOOK }}
# alt-tab-free [depaywall]: optional .p12 export password (empty if exported password-less).
# Not part of the release-gate AND — the cert import tolerates an empty password.
APPLE_P12_PASSWORD: ${{ secrets.APPLE_P12_PASSWORD }}
SPARKLE_ED_PRIVATE_KEY: ${{ secrets.SPARKLE_ED_PRIVATE_KEY }}
GITHUB_EVENT_BEFORE: ${{ github.event.before }}
GITHUB_EVENT_AFTER: ${{ github.event.after }}
BUILD_DIR: ${{ github.workspace }}
XCODE_BUILD_PATH: DerivedData/Build/Products/Release
VERSION_FILE: VERSION.txt
APP_NAME: AltTab
# alt-tab-free [depaywall]: must equal PRODUCT_NAME in config/local.xcconfig
# (PLAN §3.1/§4.3) or the build/package/appcast scripts mismatch the artifact.
APP_NAME: CommandTabFree
jobs:
build:
runs-on: macos-13 # Intel VM; see https://github.com/actions/runner-images/tree/main
runs-on: macos-15 # all options: https://github.com/actions/runner-images/tree/main
environment: production
steps:
# - env:
@@ -32,36 +55,172 @@ jobs:
COMMITS: ${{ toJson(github.event.commits) }}
run: |
if [[ "${{ github.event_name }}" == "push" ]]; then
COUNT=$(( $(echo "$COMMITS" | jq length) + 1 ))
COUNT=$(( $(echo "$COMMITS" | jq length) + 30 ))
else
COUNT=1
fi
echo "fetch-depth=$COUNT" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v3
- uses: actions/checkout@v6
with:
fetch-depth: ${{ steps.pre-checkout.outputs.fetch-depth }}
- uses: actions/setup-node@v3
# alt-tab-free [depaywall]: Guard B + Guard C run FIRST on the push job (before run_tests.sh,
# and therefore before update_appcast.sh's Sparkle sign + semantic-release's tag push) so a
# relock or a still-conflicted tree aborts the job BEFORE any irreversible side-effect (PLAN
# §4.4 "Where the guards run"). They are near-instant target-independent greps, so running them
# first is free. They also run on the PR path for the fastest red signal. A second copy sits
# just before action-gh-release as belt-and-suspenders.
- name: anti-relock — verify de-paywall marker present (Guard B)
run: |
grep -q 'depaywall' src/pro/license/LicenseManager.swift \
|| { echo "PAYWALL RELOCKED: depaywall marker missing from computeState()"; exit 1; }
# The marker proves the patch is present; pair with the if-false wrap the patch introduces.
# A bare `return .pro` grep is NOT load-bearing (it matches the unpatched line 187 too).
grep -Eq 'guard[[:space:]]+false[[:space:]]+else' src/pro/license/LicenseManager.swift \
|| { echo "PAYWALL RELOCKED: 'guard false else' (forced .pro) missing from computeState()"; exit 1; }
- name: anti-conflict — no unresolved merge markers (Guard C)
run: |
if git -c grep.lineNumber=false grep -nE '^(<<<<<<<|=======|>>>>>>>)' -- . ':(exclude)docs/'; then
echo "UNRESOLVED CONFLICT MARKERS present — resolve before merge/release"; exit 1
fi
# alt-tab-free [depaywall]: release-readiness gate (PLAN §3.3/§4.3 owner-secret checklist).
# The fork ships unsigned/ad-hoc until the OWNER provisions the Apple Developer ID cert and the
# Sparkle key. We do NOT hard-fail when those secrets are absent — that would make every push
# RED on a fork that is correctly built but not yet signing-provisioned. Instead we compute a
# boolean from secret presence and SKIP the sign/notarize/appcast/release tail cleanly when it
# is false. The build + Guard A (run_tests.sh) still run on push, so push CI is GREEN today and
# the release tail FLIPS ON automatically the moment the owner adds the secrets. Secrets are not
# available in step-level `if:` directly, so map them to env and emit an output here.
- name: release-gate — are signing/notarization secrets present?
id: release-gate
env:
HAS_P12: ${{ secrets.APPLE_P12_CERTIFICATE != '' }}
HAS_APPLE_ID: ${{ secrets.APPLE_ID != '' }}
HAS_APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD != '' }}
HAS_APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID != '' }}
HAS_SPARKLE_KEY: ${{ secrets.SPARKLE_ED_PRIVATE_KEY != '' }}
run: |
set -euo pipefail
if [ "$HAS_P12" = "true" ] && [ "$HAS_APPLE_ID" = "true" ] \
&& [ "$HAS_APPLE_PASSWORD" = "true" ] && [ "$HAS_APPLE_TEAM_ID" = "true" ] \
&& [ "$HAS_SPARKLE_KEY" = "true" ]; then
echo "signing-ready=true" >> "$GITHUB_OUTPUT"
echo "All signing/notarization/Sparkle secrets present — release tail WILL run on push."
else
echo "signing-ready=false" >> "$GITHUB_OUTPUT"
echo "::warning::Signing/notarization/Sparkle secrets absent — release tail (codesign/notarize/appcast/semantic-release/gh-release) is SKIPPED. Build + Guard A still run. Provision APPLE_P12_CERTIFICATE / APPLE_ID / APPLE_PASSWORD / APPLE_TEAM_ID / SPARKLE_ED_PRIVATE_KEY in the 'production' Environment to enable releases (PLAN §3.3/§3.4)."
fi
- uses: actions/setup-node@v6
with:
node-version: 16
node-version: 16 # PLAN §4.3: keep node-16; the package.json engines mismatch only warns
cache: 'npm'
- run: sudo xcode-select -s /Applications/Xcode_14.2.app/Contents/Developer
- run: sudo xcode-select -s /Applications/Xcode_26.0.1.app/Contents/Developer
- run: scripts/print_env.sh
- run: npm ci
# alt-tab-free [depaywall]: commitlint is gated to the push path. On push it lints the whole
# pushed range, which drags in upstream's non-conforming messages on a `chore(sync)` merge —
# this is handled by an `ignores` predicate in commitlint.config.js (PLAN §4.3) that drops the
# synthetic merge commit and upstream's own messages; do NOT break commitlint on --no-ff merges.
# $GITHUB_EVENT_BEFORE/AFTER are push-context (empty on pull_request), so a PR-safe variant runs
# below on the PR path instead.
- run: npx commitlint --from "$GITHUB_EVENT_BEFORE" --to "$GITHUB_EVENT_AFTER" --verbose
if: github.event_name == 'push'
# alt-tab-free [depaywall]: PR-safe commitlint — lints base..head (valid on pull_request),
# paired with the commitlint.config.js `ignores` predicate (PLAN §4.2/§4.3).
- run: npx commitlint --from "${{ github.event.pull_request.base.sha }}" --to "${{ github.sha }}" --verbose
if: github.event_name == 'pull_request'
# Runs on both push and PR: catches an un-regenerated l10n/generated-file diff (PLAN §4.2/§4.5).
- run: scripts/ensure_generated_files_are_up_to_date.sh
# alt-tab-free [depaywall]: release-path — a semantic-release dry-run against a PR head is
# meaningless and can mis-bump, so gate to push (PLAN §4.2).
- run: scripts/determine_next_version.sh
if: github.event_name == 'push'
# alt-tab-free [depaywall]: decouple the release apparatus from "every signing-ready push".
# determine_next_version.sh writes an EMPTY VERSION.txt when no commit since the last tag is
# release-worthy (semantic-release dry-run finds no bump). Gate the sign/notarize/release steps
# on this so a docs/ci/chore push still runs guards + commitlint + run_tests (Release-config
# compile check) but does NOT sign-build, notarize, or cut a release — no [skip ci] needed (§4.3).
- name: release-decision — did semantic-release compute a version?
id: release-decision
if: github.event_name == 'push'
run: |
if [ -n "$(tr -d '[:space:]' < "$VERSION_FILE" 2>/dev/null)" ]; then
echo "will-release=true" >> "$GITHUB_OUTPUT"
echo "Release-worthy: semantic-release will cut v$(cat "$VERSION_FILE")."
else
echo "will-release=false" >> "$GITHUB_OUTPUT"
echo "::notice::No release-worthy commit — build/test only; notarize+release tail skipped."
fi
# Inject the release version only when releasing; an empty CURRENT_PROJECT_VERSION would crash
# App.version (see config/local.xcconfig). Non-release builds use the committed 0.0.0 default.
- run: scripts/replace_environment_variables_in_app.sh
if: github.event_name == 'push' && steps.release-decision.outputs.will-release == 'true'
# codesign needs APPLE_P12_CERTIFICATE — gated on signing-ready so a not-yet-provisioned fork
# does not RED on the missing-cert import (PLAN §3.3/§4.3).
- run: scripts/codesign/setup_ci_master.sh
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true' && steps.release-decision.outputs.will-release == 'true'
# Guard A — the anti-relock unit test (appended to LicenseManagerTests.swift). Runs on both
# push and PR (no secrets needed); on the push path it sits before the sign/tag steps below
# so a relock fails BEFORE any irreversible side-effect (PLAN §4.4). This is what keeps push
# CI GREEN today on the signing-unprovisioned fork.
- run: scripts/run_tests.sh
- run: scripts/build_app.sh
# alt-tab-free [depaywall]: build the Release product to prove the tree compiles. The fork
# inherits upstream's Developer ID via config/release.xcconfig (CODE_SIGN_IDENTITY), which is
# absent on CI until the owner provisions the Apple cert — so when the release gate is NOT
# signing-ready we build AD-HOC (CODE_SIGN_IDENTITY=-, signing not required, no timestamp) to
# prove the tree compiles without a cert. When the owner adds the secrets AND sets the fork's
# Developer ID in config/local.xcconfig, this builds signed for the release tail (PLAN §3.3/§4.3).
- name: build app (signed — owner cert provisioned)
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true' && steps.release-decision.outputs.will-release == 'true'
run: scripts/build_app.sh
- name: build app (ad-hoc — until signing-provisioned)
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready != 'true'
run: scripts/build_app.sh CODE_SIGN_IDENTITY=- CODE_SIGNING_REQUIRED=NO OTHER_CODE_SIGN_FLAGS=--timestamp=none
# --- Release tail: requires the owner's Apple Developer ID + Sparkle secrets. Skipped cleanly
# (NOT failed) when they are absent, so push CI stays GREEN until the owner provisions them. ---
- run: scripts/package_and_notarize_release.sh
- run: scripts/upload_symbols_to_appcenter.sh
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true' && steps.release-decision.outputs.will-release == 'true'
# alt-tab-free [depaywall]: upload_symbols_to_appcenter.sh REMOVED — telemetry is off (PLAN §3.4).
- run: scripts/update_appcast.sh
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true' && steps.release-decision.outputs.will-release == 'true'
# alt-tab-free [depaywall]: update_readme_and_website.sh REMOVED — it queried the UPSTREAM
# lwouis/alt-tab-macos GitHub API for stars/downloads and rewrote docs/contributors.md from the
# UPSTREAM contributor graph (semantic mismatch for the fork) and dispatched the lwouis website.
# Cosmetic only; dropped per PLAN §4.0/§4.3 (alongside update_website.sh, already removed).
- run: npx semantic-release
- id: set_tag_name
run: echo "tag_name=v"$(cat $VERSION_FILE)"" >> "$GITHUB_OUTPUT"
- uses: softprops/action-gh-release@v1
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true' && steps.release-decision.outputs.will-release == 'true'
- id: set_release_info
run: scripts/extract_latest_changelog.sh
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true' && steps.release-decision.outputs.will-release == 'true'
# alt-tab-free [depaywall]: belt-and-suspenders copy of Guard B + Guard C immediately before the
# release is created. The load-bearing copy is at the top of the job (pre-tag-push); this second
# copy guards the gh-release object itself (PLAN §4.4).
- name: anti-relock + anti-conflict re-check (belt-and-suspenders)
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true' && steps.release-decision.outputs.will-release == 'true'
run: |
grep -q 'depaywall' src/pro/license/LicenseManager.swift \
|| { echo "PAYWALL RELOCKED: depaywall marker missing from computeState()"; exit 1; }
grep -Eq 'guard[[:space:]]+false[[:space:]]+else' src/pro/license/LicenseManager.swift \
|| { echo "PAYWALL RELOCKED: 'guard false else' (forced .pro) missing from computeState()"; exit 1; }
if git -c grep.lineNumber=false grep -nE '^(<<<<<<<|=======|>>>>>>>)' -- . ':(exclude)docs/'; then
echo "UNRESOLVED CONFLICT MARKERS present — resolve before release"; exit 1
fi
# alt-tab-free [depaywall]: point the release at THIS fork's repo via the ambient GITHUB_TOKEN
# (release.config.js has no @semantic-release/github plugin, so softprops is the sole release
# creator — PLAN §4.3). repository defaults to ${{ github.repository }} = the fork.
- uses: softprops/action-gh-release@v3
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true' && steps.release-decision.outputs.will-release == 'true'
with:
tag_name: ${{ steps.set_tag_name.outputs.tag_name }}
repository: ${{ github.repository }}
token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ steps.set_release_info.outputs.tag_name }}
body: ${{ steps.set_release_info.outputs.body }}
files: ${{ env.XCODE_BUILD_PATH }}/*.zip
- run: scripts/update_website.sh
# alt-tab-free [depaywall]: the release tail intentionally does NOT advance .fork-sync-state.
# That file is the UPSTREAM-sync cursor — the last-synced UPSTREAM tag (e.g. v11.3.0), read by
# upstream_sync.yml to pick "the oldest upstream tag strictly newer than it." The fork versions
# independently (semantic-release cuts v100.x), so a prior revision's step that wrote the FORK
# release tag here set the cursor to v100.x — after which no upstream tag is ever "newer" and
# upstream-sync would silently never fire. The cursor must instead be advanced by the
# upstream-sync merge flow, recording the UPSTREAM tag it synced (to be wired with
# upstream_sync.yml — PLAN §4.2). Until then .fork-sync-state stays at the last real upstream tag.
# alt-tab-free [depaywall]: update_website.sh (lwouis website dispatch) REMOVED (PLAN §3.4/§4.2).
+94
View File
@@ -0,0 +1,94 @@
# alt-tab-free — anti-relock guard workflow (docs/PLAN-maintained-fork.md §4.4)
#
# A SEPARATE, fork-owned workflow that runs the anti-relock guards on every PR,
# INDEPENDENTLY of ci_cd.yml. Rationale (§4.4): ci_cd.yml is the file most likely to take an
# upstream conflict, and a careless "keep ours/theirs" resolution could silently strip its
# pull_request: trigger or its release-step gating — at which point the in-ci_cd.yml guards
# would stop gating PRs with NO error. A guard workflow that does NOT inherit ci_cd.yml's
# trigger survives that. This is the reviewer's primary green/red signal on a sync PR.
#
# Three guards, each fails the job LOUDLY:
# A — the Test scheme (the mock-injected anti-relock unit tests in LicenseManagerTests.swift)
# B — a target-independent grep that the de-paywall flip is still present in computeState()
# C — a tree-wide grep that no unresolved git conflict markers survive into a merge/release
#
# Defense-in-depth note: Guards B + C are ALSO wired into ci_cd.yml as the FIRST push-job
# steps (CI agent owns that) so a relock/conflict-laden tree aborts the release BEFORE the tag
# is pushed or the binary signed, even if this PR gate is ever missing/misconfigured (§4.4).
name: guard
on:
pull_request:
branches: [master]
permissions:
contents: read
jobs:
# Guards B + C are near-instant greps; run them on cheap ubuntu so a relock or a still-
# conflicted tree fails FAST, before the expensive macOS Guard-A job even starts (§4.5).
grep-guards:
name: anti-relock greps (B + C)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
# GUARD B — verify the de-paywall flip is still present at the single state producer.
# §4.4 pitfall: a bare `return .pro` grep MATCHES THE UNPATCHED FILE (computeState() already
# contains `return .pro` in the keychain-valid branch on a fully relocked tree), so it is NOT
# load-bearing. The load-bearing signals are (1) the `depaywall` marker comment, which exists
# ONLY because the fork added it, AND (2) the `if false { … }` wrap that the patch introduces
# around the original (now dead) body. Both are absent on an unpatched/relocked upstream file.
- name: Guard B — de-paywall marker + if-false wrap present in computeState()
run: |
set -euo pipefail
F=src/pro/license/LicenseManager.swift
if [ ! -f "$F" ]; then
echo "::error::Guard B: $F not found — chokepoint moved? Refresh the de-paywall patch (§6.2)."
exit 1
fi
grep -q 'depaywall' "$F" || {
echo "::error::PAYWALL RELOCKED: 'depaywall' marker missing from $F — the de-paywall flip was lost in a merge. Refresh the patch (§6.2)."
exit 1
}
grep -Eq 'guard[[:space:]]+false[[:space:]]+else' "$F" || {
echo "::error::PAYWALL RELOCKED: 'if false { … }' wrap missing from $F — the de-paywall body-suppress was lost. Refresh the patch (§6.2)."
exit 1
}
echo "Guard B OK: de-paywall marker + if-false wrap present in $F."
# GUARD C — no unresolved git conflict markers anywhere in the tree. The §4.2 sync cron
# deliberately commits a conflicted tree (markers + --no-verify) for a human to resolve;
# nothing else guarantees the human removed EVERY marker before merge. A markers-laden
# commit merged to master becomes a permanent ancestor of the published tag (un-compilable
# source), contradicting §5(1). Exclude docs/ so this plan's own literal marker examples
# don't trip the grep.
- name: Guard C — no unresolved merge conflict markers
run: |
set -euo pipefail
if git -c grep.lineNumber=false grep -nE '^(<<<<<<<|=======|>>>>>>>)' -- . ':(exclude)docs/'; then
echo "::error::UNRESOLVED CONFLICT MARKERS present — resolve before merge/release (§4.4 Guard C)."
exit 1
fi
echo "Guard C OK: no unresolved conflict markers."
# GUARD A — the behavioral anti-relock unit tests (mock-injected LicenseManager) via the Test
# scheme. §4.4: this MUST run on macos-15 with the pinned Xcode — run_tests.sh is `xcodebuild
# test`, which cannot run on ubuntu. If left on ubuntu, Guard A silently degrades to greps-only
# and the behavioral relock test never executes (the exact silent-disarming class this plan
# guards against). Bootstrap assertion (§4.4): on the deliberately-relocked acceptance PR,
# confirm THIS job produced a real test result that is RED on the relock — not just the greps.
unit-tests:
name: anti-relock unit tests (A)
runs-on: macos-15 # MUST match ci_cd.yml — `xcodebuild test` needs the pinned Xcode
steps:
- uses: actions/checkout@v6
# Pin the same Xcode as ci_cd.yml (§4.5 bootstrap invariant — re-pin on every upstream bump).
- run: sudo xcode-select -s /Applications/Xcode_26.0.1.app/Contents/Developer
# run_tests.sh runs the `Test` scheme (-configuration Release), which includes the
# appended anti-relock tests in src/pro/license/LicenseManagerTests.swift:
# testDepaywallProNeverLocked — load-bearing `state == .pro` assert
# testDepaywallStillProAfterTrialExpiry — discriminating (expired-trial) assert
# A relock makes computeState() fall back to computeTrialState() and these go RED.
- name: Guard A — run the Test scheme (anti-relock unit tests)
run: scripts/run_tests.sh
+226
View File
@@ -0,0 +1,226 @@
# alt-tab-free — upstream sync workflow (docs/PLAN-maintained-fork.md §4.2)
#
# Polls lwouis/alt-tab-macos for new release tags and opens a reviewable sync PR.
# Selects the OLDEST upstream tag strictly newer than the last-merged tag recorded in
# `.fork-sync-state` (NOT "newest tag minus --is-ancestor"). This is the §4.2
# never-drop-commits invariant: `.fork-sync-state` advances ONLY when a sync PR merges to
# master (a ci_cd.yml push-job step — owned by the CI agent), so a sync PR that is
# closed-without-merge or abandoned can never silently skip its tag — that tag stays "next"
# until it is actually merged. This subsumes the old `merge-base --is-ancestor` guard.
#
# A release is cut only when a human merges the PR to master (ci_cd.yml on: push). This
# workflow never releases; it only opens the PR for review.
name: upstream-sync
on:
# §4.2 cron-durability note: the in-repo `schedule:` SILENTLY auto-disables after 60 days
# of repo inactivity (no error, no notification). It is kept here as belt-and-suspenders.
# The RECOMMENDED PRIMARY trigger is an EXTERNAL scheduler hitting `repository_dispatch`
# carrying the SYNC_BOT_TOKEN (immune to the 60-day rule, and composes with the
# workflow-re-trigger token). See ownerActions / §4.2.
schedule:
- cron: '0 7 * * *' # daily; cheap, idempotent
workflow_dispatch: {}
repository_dispatch:
types: [upstream-sync] # external-scheduler entry point (§4.2 primary durability path)
# GITHUB_TOKEN is read-only by default; opening a PR + pushing a branch need these.
permissions:
contents: write
pull-requests: write
jobs:
sync:
runs-on: ubuntu-latest # pure git, no Xcode
env:
# CRITICAL (§4.2 BLOCKING) — do NOT use ${{ github.token }} here. By GitHub's documented
# recursion-prevention rule, a branch push / PR authored with the default GITHUB_TOKEN
# does NOT trigger other workflows — so guard.yml and ci_cd.yml's pull_request: checks
# would NEVER fire on the sync PR and the entire pre-merge gate would silently never run.
# SYNC_BOT_TOKEN MUST be a fork-owned credential that re-triggers workflows: a GitHub App
# installation token (preferred — least-privilege, short-lived) or a fork-owned PAT.
GH_TOKEN: ${{ secrets.SYNC_BOT_TOKEN }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
# Persist the fork-owned credential (NOT the default GITHUB_TOKEN) as the push
# credential, so the branch push below re-triggers guard.yml / ci_cd.yml PR checks.
token: ${{ secrets.SYNC_BOT_TOKEN }}
- name: Fail closed if SYNC_BOT_TOKEN is missing
run: |
# §4.2: without the workflow-re-triggering token the pre-merge gate is silently
# disarmed. Fail loudly here rather than open a check-less PR.
if [ -z "${SYNC_BOT_TOKEN:-}" ]; then
echo "::error::SYNC_BOT_TOKEN is not set. Refusing to open a check-less sync PR (§4.2)."
echo "Provision a GitHub App installation token (preferred) or fork-owned PAT as SYNC_BOT_TOKEN."
exit 1
fi
env:
SYNC_BOT_TOKEN: ${{ secrets.SYNC_BOT_TOKEN }}
- name: Add upstream + fetch tags
run: |
set -euo pipefail
git remote add upstream https://github.com/lwouis/alt-tab-macos.git || true
git fetch upstream --tags --force
- name: Verify sync labels exist (§4.2 — fail closed, never treat empty as "no open sync")
run: |
set -euo pipefail
# Guard 2 below and the §0.1 trip-wire query `sync` / `conflict` / `chokepoint-refresh`.
# `gh pr list --label <missing>` returns an EMPTY LIST, not an error, for a label that
# was never created — so on a fresh repo Guard 2 would silently no-op. Fail closed if a
# required label is absent; the bootstrap (§6.1) creates them with `gh label create`.
missing=0
for L in sync conflict chokepoint-refresh; do
if ! gh label list --json name --jq '.[].name' | grep -qxF "$L"; then
echo "::error::Required label '$L' is missing. Create it at bootstrap (§6.1): gh label create $L"
missing=1
fi
done
[ "$missing" -eq 0 ] || exit 1
- name: Select oldest upstream tag strictly newer than .fork-sync-state
id: tag
run: |
set -euo pipefail
# State-file-driven selection (§4.2): NOT "newest tag minus --is-ancestor".
last_synced="$(tr -d '[:space:]' < .fork-sync-state)"
if [ -z "$last_synced" ]; then
echo "::error::.fork-sync-state is empty; seed it with the last-merged upstream tag (e.g. v11.3.0)."
exit 1
fi
echo "Last synced (from .fork-sync-state): $last_synced"
# UPSTREAM-ONLY enumeration: `git tag -l 'v*'` would also match the FORK's OWN
# semantic-release tags (the fork cuts vX.Y.Z every sync — §4.3), so list tags from
# the upstream remote explicitly. Sort by version; keep only tags strictly newer than
# the recorded one; take the OLDEST of those (resolve-in-order — §4.2).
all_newer="$(git ls-remote --tags --refs upstream 'v*' \
| awk -F/ '{print $NF}' \
| sort -V \
| awk -v last="$last_synced" '
$0 == last { seen = 1; next }
seen { print }
')"
# Fallback for the case where last_synced is not itself present upstream: take every
# tag that sorts strictly after it.
if [ -z "$all_newer" ]; then
all_newer="$(git ls-remote --tags --refs upstream 'v*' \
| awk -F/ '{print $NF}' \
| sort -V \
| awk -v last="$last_synced" '{ if ($0 != last) print $0 }' \
| while read -r t; do
# keep only tags that sort AFTER last_synced
if [ "$(printf '%s\n%s\n' "$last" "$t" | sort -V | tail -1)" = "$t" ] && [ "$t" != "$last" ]; then
echo "$t"
fi
done)"
fi
next="$(printf '%s\n' "$all_newer" | sed '/^$/d' | head -1)"
if [ -z "$next" ]; then
echo "Up to date: no upstream tag newer than $last_synced."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Next tag to sync (oldest strictly newer): $next"
# Guard — a prior sync is still OPEN (resolve-in-order, §4.2): do NOT open a new PR
# while any sync/* PR is unmerged. A backlog pauses syncing until the human merges it;
# this is the never-drop-commits behavior. The liveness alert keys off the stalled flag.
# `gh pr list --label sync` fails closed because the label existence was verified above.
open_sync="$(gh pr list --state open --label sync --json number,headRefName,createdAt \
--jq 'sort_by(.createdAt) | .[0] // empty')"
if [ -n "$open_sync" ]; then
echo "A prior sync PR is still open (resolve-in-order): $open_sync"
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "stalled=true" >> "$GITHUB_OUTPUT" # liveness alert keys off this (§4.2)
exit 0
fi
echo "latest=$next" >> "$GITHUB_OUTPUT"
- name: Merge onto a sync branch (real merge commit, conventional message)
if: steps.tag.outputs.skip != 'true'
id: merge
run: |
set -euo pipefail
TAG='${{ steps.tag.outputs.latest }}'
git config user.name "fork-sync-bot"
git config user.email "fork-sync-bot@users.noreply.github.com"
git switch -c "sync/${TAG}"
# NO --no-commit: let git author a REAL merge commit with a CONVENTIONAL message so
# commitlint / @semantic-release/commit-analyzer stay happy (§4.3). On conflict, commit
# the conflicted tree (markers included, --no-verify) so the PR shows the markers for a
# human to resolve; Guard C (guard.yml + ci_cd.yml) then blocks it from ever shipping.
if git merge --no-ff -m "chore(sync): merge upstream ${TAG}" "${TAG}"; then
conflicts=false
else
git add -A
git commit --no-verify \
-m "chore(sync): merge upstream ${TAG} (CONFLICTS — resolve before merge)"
conflicts=true
fi
echo "conflicts=${conflicts}" >> "$GITHUB_OUTPUT"
# §0.1 trip-wire A — surface chokepoint churn as a per-sync signal. A nonzero count
# means an upstream change touched a de-paywall chokepoint file in this merge range
# (last-synced tag .. new tag); the PR is labeled `chokepoint-refresh` (below) so the
# trip-wire is a single query, not a memory exercise.
CHOKEPOINTS="src/pro/license/LicenseManager.swift src/pro/ProFeature.swift src/preferences/PreferenceDefinition.swift src/pro/scheduling/ProTransitionManager.swift src/pro/license/LicenseCookie.swift src/vendors/AppCenterCrashes.swift"
LAST_SYNCED="$(tr -d '[:space:]' < .fork-sync-state)"
churn="$(git rev-list --count "${LAST_SYNCED}..${TAG}" -- $CHOKEPOINTS 2>/dev/null || echo 0)"
# Also flag if the merge left a conflict in any chokepoint file (the conflicted commit
# is HEAD; compare against its first parent HEAD~1 = the pre-merge master tip).
chokepoint_conflict=0
if git diff --name-only HEAD~1 HEAD 2>/dev/null | grep -qE 'LicenseManager\.swift|ProFeature\.swift|PreferenceDefinition\.swift|ProTransitionManager\.swift|LicenseCookie\.swift|AppCenterCrashes\.swift'; then
if [ "${conflicts:-false}" = "true" ]; then
chokepoint_conflict=1
fi
fi
echo "churn=${churn}" >> "$GITHUB_OUTPUT"
echo "chokepoint_conflict=${chokepoint_conflict}" >> "$GITHUB_OUTPUT"
git push origin "HEAD:sync/${TAG}"
- name: Open PR
if: steps.tag.outputs.skip != 'true'
run: |
set -euo pipefail
TAG='${{ steps.tag.outputs.latest }}'
CHURN='${{ steps.merge.outputs.churn }}'
CONFLICTS='${{ steps.merge.outputs.conflicts }}'
CHOKEPOINT_CONFLICT='${{ steps.merge.outputs.chokepoint_conflict }}'
# Label fail-closed (§4.2): conflict -> `sync,conflict`, else `sync`.
if [ "$CONFLICTS" = "true" ]; then
LABELS="sync,conflict"
else
LABELS="sync"
fi
BODY="Automated upstream sync to \`${TAG}\`.
Selected as the OLDEST upstream tag strictly newer than \`.fork-sync-state\` (§4.2).
Verify the guard.yml + ci_cd.yml PR checks are GREEN (anti-relock test + marker/conflict greps) before merge.
If checks did not appear, SYNC_BOT_TOKEN is mis-set to the default GITHUB_TOKEN — the gate is disarmed (§4.2).
Chokepoint-churn count for this merge range: ${CHURN} (nonzero => de-paywall chokepoint touched, see §0.1 trip-wire A).
NEVER close this PR to defer it — \`.fork-sync-state\` only advances on MERGE, so leaving it OPEN keeps this tag 'next'; closing it would silently skip the tag (§4.2 / §6.2)."
gh pr create \
--head "sync/${TAG}" \
--base master \
--title "sync: merge upstream ${TAG}" \
--body "$BODY" \
--label "$LABELS"
# §0.1 trip-wire A — auto-apply `chokepoint-refresh` from CI when a chokepoint file
# changed or conflicted, so the trip-wire tally never depends on a human remembering.
if [ "${CHURN:-0}" -gt 0 ] || [ "${CHOKEPOINT_CONFLICT:-0}" = "1" ]; then
gh pr edit "sync/${TAG}" --add-label chokepoint-refresh || true
fi
+13 -2
View File
@@ -1,14 +1,25 @@
/.idea/
xcuserdata/
/.vscode/
/buildServer.json
WorkspaceSettings.xcsettings
IDEWorkspaceChecks.plist
/node_modules/
/DerivedData/
/build/
/vendor/*/.build/
/vendor/*/build/
/vendor/*/.swiftpm/
/vendor/*/Package.resolved
.DS_Store
/docs/_site/
/docs/vendor/
codesign.conf
codesign.crt
codesign.key
codesign.p12
/.claude/*
!/.claude/skills/
/scripts/l10n/missing-translations.json
/ai/output/
# alt-tab-free [depaywall]: the Sparkle feed is published OUT OF TREE to the gh-pages branch by
# scripts/update_appcast.sh; the in-tree appcast.xml is removed (PLAN §3.3).
/appcast.xml
+5 -7
View File
@@ -1,8 +1,6 @@
retain_objc_accessible: true
project: alt-tab-macos.xcodeproj
schemes:
- Release
targets:
- alt-tab-macos
workspace: alt-tab-macos.xcworkspace
report_exclude:
- src/api-wrappers/PrivateApis.swift
- Release
index_exclude:
- vendor/**
- src/api-wrappers/private-apis/**
+9 -5
View File
@@ -1,6 +1,10 @@
# We can find the rules here.
# https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md
# rules: https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md
--swiftversion 5.5
--maxwidth 120
--swiftversion 5.8
--maxwidth 110
--nowrapoperators .,==,!=,<,>,>=,<=
--wrapternary before-operators
--disable andOperator
--disable wrapConditionalBodies
--disable wrapLoopBodies
--disable wrapMultilineStatementBraces
-1
View File
@@ -2,7 +2,6 @@
# src/**/*.swift: Matches all .swift files in the src directory and all its subdirectories.
# !node_modules/**: Excludes all files in the node_modules directory and all its subdirectories.
Pods/**
Generated/**
**/PrivateApis.swift
+14
View File
@@ -0,0 +1,14 @@
# macOS development
- Don't use xcode directly to develop
- Use pure swift 5.8 code to make the app. No interface builder. No SwiftUI.
- Aim for compact code. Within methods, don't have groups of statements separated with newlines. No inline comments for simple code. Instead, split statements into sub-methods.
- Use guard closes as much as possible to separate the happy-path under them
- Organize source files into folders. Folders should group files that change together, at the same pace (e.g. one feature)
- Favor low latency and responsiveness. Reuse objects, avoid wasting memory or I/O.
# Workflow
- Copy commands from ai/build.sh and run them, to confirm compilation works after you're done with implementing a change
# License / Keychain invariant
- The app's Developer ID, TeamID, and bundle ID must remain stable across builds. Keychain items are tied to the code signature; changing any of these orphans every user's stored license key and forces mass re-activation. If a rotation is unavoidable, plan a migration first (e.g., a backup-restore handler, or `kSecAttrAccessGroup` with a stable group identifier).
- Do not introduce legacy `SecKeychain*` API or `kSecAccessControl` (biometric/PIN gating) into license code — both can trigger Keychain password prompts, which is bad UX for license activation.
+1
View File
@@ -0,0 +1 @@
@include ./AGENTS.md
+57 -29
View File
@@ -2,55 +2,83 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ATSApplicationFontsPath</key>
<string></string>
<key>AppCenterApplicationForwarderEnabled</key>
<string>0</string>
<key>AppCenterSecret</key>
<string>#APPCENTER_SECRET#</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string>app.icns</string>
<!-- ===== Bundle identity (required by macOS / App Store) ===== -->
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>#VERSION#</string>
<key>CFBundleVersion</key>
<string>#VERSION#</string>
<key>FeedbackToken</key>
<string>#FEEDBACK_TOKEN#</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleIconFile</key>
<string>app.icns</string>
<key>NSHumanReadableCopyright</key>
<string>GPL-3.0 licence</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<!-- ===== Versioning (substituted from xcconfig; CI overrides via config/local.xcconfig) ===== -->
<key>CFBundleShortVersionString</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<!-- ===== Launch behavior (read by LaunchServices before app starts) ===== -->
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key>
<string>true</string>
<key>NSHumanReadableCopyright</key>
<string>GPL-3.0 licence</string>
<key>NSPrincipalClass</key>
<string>AppCenterApplication</string>
<key>NSSupportsAutomaticTermination</key>
<string>false</string>
<key>NSSupportsSuddenTermination</key>
<string>false</string>
<key>SUEnableAutomaticChecks</key>
<string>true</string>
<key>SUEnableJavaScript</key>
<string>true</string>
<key>SUFeedURL</key>
<string>https://raw.githubusercontent.com/lwouis/alt-tab-macos/master/appcast.xml</string>
<key>ATSApplicationFontsPath</key>
<string></string>
<!-- ===== URL scheme registration (LaunchServices dispatches $(PRODUCT_BUNDLE_IDENTIFIER):// to us) ===== -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
</dict>
</array>
<!-- ===== Sparkle (auto-update framework — reads these directly from the bundle) ===== -->
<key>SUPublicEDKey</key>
<string>2e9SQOBoaKElchSa/4QDli/nvYkyuDNfynfzBF6vJK4=</string>
<!-- Fork EdDSA public key for Sparkle update verification. The matching private key
is held as CI secret SPARKLE_ED_PRIVATE_KEY (see docs/EXECUTION-STATUS.md §3.3).
Auto-checks stay off (below) until DOMAIN serves a real appcast host. -->
<string>1YfoCJDk/T8GQx1Gpf3O4ApFgDkBiN6oe/z/Kfnxs/M=</string>
<key>SUEnableAutomaticChecks</key>
<!-- alt-tab-free: enabled 2026-06-16 — DOMAIN serves the appcast on GitHub Pages (gh-pages). -->
<string>true</string>
<key>SUScheduledCheckInterval</key>
<string>604800</string>
<!-- ===== AppCenter (crash reporter — read by AppCenterApplication superclass at init) ===== -->
<key>AppCenterApplicationForwarderEnabled</key>
<string>0</string>
<!-- ===== Build-time secrets (substituted from xcconfig; override per-dev via config/local.xcconfig) ===== -->
<key>AppCenterSecret</key>
<string>$(APPCENTER_SECRET)</string>
<key>Domain</key>
<string>$(DOMAIN)</string>
<key>ApiDomain</key>
<string>$(API_DOMAIN)</string>
</dict>
</plist>
+34
View File
@@ -0,0 +1,34 @@
# NOTICE — Statement of Changes (GPL-3.0 §5(a))
This file carries the prominent notice, required by GNU GPL v3.0 §5(a), that this work
has been modified, and gives the relevant date. It is a **living document**: whenever a
sync from upstream changes this fork's modification surface, update the change list and
the date below (see `docs/PLAN-maintained-fork.md` §6.2).
**Forked from:** [lwouis/alt-tab-macos](https://github.com/lwouis/alt-tab-macos) v11.3.0,
© Louis Pontoise, licensed GPL-3.0.
**Modified by:** the CommandTabFree fork. This fork neutralizes the AltTab Pro paywall so that
all features are free.
**Date of modification:** 2026-06-10.
**License:** CommandTabFree is released under the **GNU General Public License v3.0**, the same
license as upstream. The full license text is in [`LICENCE.md`](LICENCE.md), which is kept
byte-for-byte identical to upstream and is never edited.
## Changes made in this fork
- **`LicenseManager.computeState`** (`src/pro/license/LicenseManager.swift`) — forced to
return `.pro`, opening every Pro feature gate. This is the single live license-state
producer, so this one change unlocks all paywalled features.
- **`LicenseCookie.syncLicenseCookie`** (`src/pro/license/LicenseCookie.swift`) — made a
no-op, so no license cookie is written to the upstream domain.
- **`AppCenterCrash.init`** (`src/vendors/AppCenterCrashes.swift`) — telemetry disabled;
AppCenter is never started.
- **`App.handleCustomUrl`** (`src/App.swift`) — the `activate` deep-link handler is
disabled, so a crafted `…://activate?license_key=…` URL can no longer POST the machine
hardware fingerprint to a license backend.
The upstream copyright, contributor credits (`docs/contributors.md`), and third-party
acknowledgments (`docs/acknowledgments.md`) are retained unchanged.
+1 -1
View File
@@ -14,4 +14,4 @@ python_version = "3.6"
[scripts]
font2png = "scripts/convert_font_to_png.sh"
translate = "python scripts/translate_i18n_tools.py resources/l10n --retry_translate"
translate = "python scripts/l10n/google_translate_all_terms_locally.py resources/l10n --retry_translate"
Generated
+11 -9
View File
@@ -1,10 +1,12 @@
{
"_meta": {
"hash": {
"sha256": "00c7c75d00988a027e56c90f3a0bbba05aec3b41b2f7fd9be24f3cb27bf15eaf"
"sha256": "3646221352b85667ac21f1b528dc8b29f56ff1e24cb97e7eaba79b5040c78e21"
},
"pipfile-spec": 6,
"requires": {},
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
@@ -16,11 +18,11 @@
"default": {
"certifi": {
"hashes": [
"sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8",
"sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"
"sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407",
"sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"
],
"markers": "python_version >= '3.6'",
"version": "==2024.8.30"
"markers": "python_version >= '3.7'",
"version": "==2025.8.3"
},
"chardet": {
"hashes": [
@@ -68,11 +70,11 @@
},
"hstspreload": {
"hashes": [
"sha256:2ab4518495a132c4ae430c474afffd12938852c6eec68ce1368c8f7858dc3076",
"sha256:9c1b2d0313899d3ff9dac03ab39d53fed95c32eef9862e7eabee8dc07dfd589c"
"sha256:02bd5b0885b62f0d5239ca6c6876ffcad8d9c08dc97cee54292598141a16e9dc",
"sha256:346552a807b3a1762376de8ecce097544e7fcd64fb64231b4652da52f86fa6f1"
],
"markers": "python_version >= '3.6'",
"version": "==2024.9.1"
"version": "==2025.1.1"
},
"httpcore": {
"hashes": [
-25
View File
@@ -1,25 +0,0 @@
platform :osx, '10.12'
target 'alt-tab-macos' do
use_frameworks!
pod 'LetsMove', :git => 'https://github.com/lwouis/LetsMove.git', :commit => '7abf4daed1a25218f2b52f2dfd190aee5a50071c'
pod 'Sparkle', :podspec => 'https://raw.githubusercontent.com/lwouis/Sparkle/fix-iframe-popup-1.24/Sparkle.podspec'
pod 'ShortcutRecorder', :git => 'https://github.com/lwouis/ShortcutRecorder.git', :branch => 'alt-tab-current'
pod 'SwiftyMarkdown', '1.1.0'
pod 'AppCenter/Crashes', '4.3.0'
pod 'SwiftyBeaver', '1.9.0'
end
target 'unit-tests' do
use_frameworks!
pod 'ShortcutRecorder', :git => 'https://github.com/lwouis/ShortcutRecorder.git', :branch => 'alt-tab-current'
# disable code signing which is unnecessary for tests
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
end
end
end
end
-53
View File
@@ -1,53 +0,0 @@
PODS:
- AppCenter/Core (4.3.0)
- AppCenter/Crashes (4.3.0):
- AppCenter/Core
- LetsMove (1.24)
- ShortcutRecorder (3.1)
- Sparkle (1.24.0)
- SwiftyBeaver (1.9.0)
- SwiftyMarkdown (1.1.0)
DEPENDENCIES:
- AppCenter/Crashes (= 4.3.0)
- LetsMove (from `https://github.com/lwouis/LetsMove.git`, commit `7abf4daed1a25218f2b52f2dfd190aee5a50071c`)
- ShortcutRecorder (from `https://github.com/lwouis/ShortcutRecorder.git`, branch `alt-tab-current`)
- Sparkle (from `https://raw.githubusercontent.com/lwouis/Sparkle/fix-iframe-popup-1.24/Sparkle.podspec`)
- SwiftyBeaver (= 1.9.0)
- SwiftyMarkdown (= 1.1.0)
SPEC REPOS:
trunk:
- AppCenter
- SwiftyBeaver
- SwiftyMarkdown
EXTERNAL SOURCES:
LetsMove:
:commit: 7abf4daed1a25218f2b52f2dfd190aee5a50071c
:git: https://github.com/lwouis/LetsMove.git
ShortcutRecorder:
:branch: alt-tab-current
:git: https://github.com/lwouis/ShortcutRecorder.git
Sparkle:
:podspec: https://raw.githubusercontent.com/lwouis/Sparkle/fix-iframe-popup-1.24/Sparkle.podspec
CHECKOUT OPTIONS:
LetsMove:
:commit: 7abf4daed1a25218f2b52f2dfd190aee5a50071c
:git: https://github.com/lwouis/LetsMove.git
ShortcutRecorder:
:commit: 5bb32febdab48038ce1762bf14f5ce8024b11fe7
:git: https://github.com/lwouis/ShortcutRecorder.git
SPEC CHECKSUMS:
AppCenter: 883369ab78427b0561c688158d689dfe1f993ea9
LetsMove: fefe56bc7bc7fb7d37049e28a14f297961229fc5
ShortcutRecorder: fdf620aca34101b0cba3b10fca815e0459254189
Sparkle: 1fa490bb4ab2a9b37cfb9ea4feec19dd33b81cd2
SwiftyBeaver: d39e7c376bf15e9fffca8263b8fd1f42ea56aa2d
SwiftyMarkdown: 033abc9dad9a37903f81aec5188cade436f40520
PODFILE CHECKSUM: 29e9c8f00c3b594083545d6218fdfecdcd6e0037
COCOAPODS: 1.16.2
BIN
View File
Binary file not shown.
@@ -1,99 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>tvos-arm64</string>
<key>LibraryPath</key>
<string>AppCenter.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>tvos</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-maccatalyst</string>
<key>LibraryPath</key>
<string>AppCenter.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>maccatalyst</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_i386_x86_64-simulator</string>
<key>LibraryPath</key>
<string>AppCenter.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>i386</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_arm64e_armv7_armv7s</string>
<key>LibraryPath</key>
<string>AppCenter.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>arm64e</string>
<string>armv7</string>
<string>armv7s</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>tvos-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>AppCenter.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>tvos</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>macos-arm64_x86_64</string>
<key>LibraryPath</key>
<string>AppCenter.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>macos</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>
@@ -1,13 +0,0 @@
framework module AppCenter {
umbrella header "AppCenter.h"
export *
module * { export * }
link framework "Foundation"
link framework "CoreTelephony"
link framework "SystemConfiguration"
link framework "UIKit"
link "sqlite3"
link "z"
}
@@ -1,44 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACAppCenter.h>)
#import <AppCenter/MSACAbstractLog.h>
#import <AppCenter/MSACAppCenter.h>
#import <AppCenter/MSACAppCenterErrors.h>
#import <AppCenter/MSACChannelGroupProtocol.h>
#import <AppCenter/MSACChannelProtocol.h>
#import <AppCenter/MSACConstants+Flags.h>
#import <AppCenter/MSACConstants.h>
#import <AppCenter/MSACCustomProperties.h>
#import <AppCenter/MSACDevice.h>
#import <AppCenter/MSACEnable.h>
#import <AppCenter/MSACLog.h>
#import <AppCenter/MSACLogWithProperties.h>
#import <AppCenter/MSACLogger.h>
#import <AppCenter/MSACSerializableObject.h>
#import <AppCenter/MSACService.h>
#import <AppCenter/MSACServiceAbstract.h>
#import <AppCenter/MSACWrapperLogger.h>
#import <AppCenter/MSACWrapperSdk.h>
#else
#import "MSACAbstractLog.h"
#import "MSACAppCenter.h"
#import "MSACAppCenterErrors.h"
#import "MSACChannelGroupProtocol.h"
#import "MSACChannelProtocol.h"
#import "MSACConstants+Flags.h"
#import "MSACConstants.h"
#import "MSACCustomProperties.h"
#import "MSACDevice.h"
#import "MSACEnable.h"
#import "MSACLog.h"
#import "MSACLogWithProperties.h"
#import "MSACLogger.h"
#import "MSACSerializableObject.h"
#import "MSACService.h"
#import "MSACServiceAbstract.h"
#import "MSACWrapperLogger.h"
#import "MSACWrapperSdk.h"
#endif
@@ -1,203 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#ifndef MSAC_APP_CENTER
#define MSAC_APP_CENTER
#if __has_include(<AppCenter/MSACConstants.h>)
#import <AppCenter/MSACConstants.h>
#else
#import "MSACConstants.h"
#endif
@class MSACWrapperSdk;
#if !TARGET_OS_TV
@class MSACCustomProperties;
#endif
NS_SWIFT_NAME(AppCenter)
@interface MSACAppCenter : NSObject
/**
* Returns the singleton instance of MSACAppCenter.
*/
+ (instancetype)sharedInstance;
/**
* Configure the SDK with an application secret.
*
* @param appSecret A unique and secret key used to identify the application.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)configureWithAppSecret:(NSString *)appSecret NS_SWIFT_NAME(configure(withAppSecret:));
/**
* Configure the SDK.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)configure;
/**
* Configure the SDK with an application secret and an array of services to start.
*
* @param appSecret A unique and secret key used to identify the application.
* @param services Array of services to start.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)start:(NSString *)appSecret withServices:(NSArray<Class> *)services NS_SWIFT_NAME(start(withAppSecret:services:));
/**
* Start the SDK with an array of services.
*
* @param services Array of services to start.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)startWithServices:(NSArray<Class> *)services NS_SWIFT_NAME(start(services:));
/**
* Start a service.
*
* @param service A service to start.
*
* @discussion This may be called only once per service per application process lifetime.
*/
+ (void)startService:(Class)service;
/**
* Configure the SDK with an array of services to start from a library. This will not start the service at application level, it will enable
* the service only for the library.
*
* @param services Array of services to start.
*/
+ (void)startFromLibraryWithServices:(NSArray<Class> *)services NS_SWIFT_NAME(startFromLibrary(services:));
/**
* The flag indicates whether the SDK has already been configured or not.
*/
@property(class, atomic, readonly, getter=isConfigured) BOOL configured;
/**
* The flag indicates whether app is running in App Center Test Cloud.
*/
@property(class, atomic, readonly, getter=isRunningInAppCenterTestCloud) BOOL runningInAppCenterTestCloud;
/**
* The flag indicates whether or not the SDK was enabled as a whole
*
* The state is persisted in the device's storage across application launches.
*/
@property(class, nonatomic, getter=isEnabled, setter=setEnabled:) BOOL enabled NS_SWIFT_NAME(enabled);
/**
* Flag indicating whether SDK can send network requests.
*
* The state is persisted in the device's storage across application launches.
*/
@property(class, nonatomic, getter=isNetworkRequestsAllowed, setter=setNetworkRequestsAllowed:)
BOOL networkRequestsAllowed NS_SWIFT_NAME(networkRequestsAllowed);
/**
* The SDK's log level.
*/
@property(class, nonatomic) MSACLogLevel logLevel;
/**
* Base URL to use for backend communication.
*/
@property(class, nonatomic, strong) NSString *logUrl;
/**
* Set log handler.
*/
@property(class, nonatomic) MSACLogHandler logHandler;
/**
* Set wrapper SDK information to use when building device properties. This is intended in case you are building a SDK that uses the App
* Center SDK under the hood, e.g. our Xamarin SDK or ReactNative SDk.
*/
@property(class, nonatomic, strong) MSACWrapperSdk *wrapperSdk;
#if !TARGET_OS_TV
/**
* Set the custom properties.
*
* @param customProperties Custom properties object.
*/
+ (void)setCustomProperties:(MSACCustomProperties *)customProperties;
#endif
/**
* Check whether the application delegate forwarder is enabled or not.
*
* @discussion The application delegate forwarder forwards messages that target your application delegate methods via swizzling to the SDK.
* It simplifies the SDK integration but may not be suitable to any situations. For
* instance it should be disabled if you or one of your third party SDK is doing message forwarding on the application delegate. Message
* forwarding usually implies the implementation of @see NSObject#forwardingTargetForSelector: or @see NSObject#forwardInvocation: methods.
* To disable the application delegate forwarder just add the `AppCenterAppDelegateForwarderEnabled` tag to your Info .plist file and set it
* to `0`. Then you will have to forward any application delegate needed by the SDK manually.
*/
@property(class, readonly, nonatomic, getter=isAppDelegateForwarderEnabled) BOOL appDelegateForwarderEnabled;
/**
* Unique installation identifier.
*
*/
@property(class, readonly, nonatomic) NSUUID *installId;
/**
* Detect if a debugger is attached to the app process. This is only invoked once on app startup and can not detect
* if the debugger is being attached during runtime!
*
*/
@property(class, readonly, nonatomic, getter=isDebuggerAttached) BOOL debuggerAttached;
/**
* Current version of AppCenter SDK.
*
*/
@property(class, readonly, nonatomic) NSString *sdkVersion;
/**
* Set the maximum size of the internal storage. This method must be called before App Center is started. This method is only intended for
* applications.
*
* @param sizeInBytes Maximum size of the internal storage in bytes. This will be rounded up to the nearest multiple of a SQLite page size
* (default is 4096 bytes). Values below 20,480 bytes (20 KiB) will be ignored.
*
* @param completionHandler Callback that is invoked when the database size has been set. The `BOOL` parameter is `YES` if changing the size
* is successful, and `NO` otherwise. This parameter can be null.
*
* @discussion This only sets the maximum size of the database, but App Center modules might store additional data.
* The value passed to this method is not persisted on disk. The default maximum database size is 10485760 bytes (10 MiB).
*/
+ (void)setMaxStorageSize:(long)sizeInBytes completionHandler:(void (^)(BOOL))completionHandler;
/**
* Set the user identifier.
*
* @discussion Set the user identifier for logs sent for the default target token when the secret passed in @c
* MSACAppCenter:start:withServices: contains "target={targetToken}".
*
* For App Center backend the user identifier maximum length is 256 characters.
*
* AppCenter must be configured or started before this API can be used.
*/
@property(class, nonatomic, strong) NSString *userId;
/**
* Set country code to use when building device properties.
*
* @see https://www.iso.org/obp/ui/#search for more information.
*/
@property(class, nonatomic, strong) NSString *countryCode;
@end
#endif
@@ -1,41 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_APP_CENTER_ERRORS_H
#define MSAC_APP_CENTER_ERRORS_H
#import <Foundation/Foundation.h>
#define MSAC_APP_CENTER_BASE_DOMAIN @"com.Microsoft.AppCenter."
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Domain
static NSString *const kMSACACErrorDomain = MSAC_APP_CENTER_BASE_DOMAIN @"ErrorDomain";
#pragma mark - General
// Error codes.
NS_ENUM(NSInteger){MSACACLogInvalidContainerErrorCode = 1, MSACACCanceledErrorCode = 2, MSACACDisabledErrorCode = 3};
// Error descriptions.
static NSString const *kMSACACLogInvalidContainerErrorDesc = @"Invalid log container.";
static NSString const *kMSACACCanceledErrorDesc = @"The operation was canceled.";
static NSString const *kMSACACDisabledErrorDesc = @"The service is disabled.";
#pragma mark - Connection
// Error codes.
NS_ENUM(NSInteger){MSACACConnectionPausedErrorCode = 100, MSACACConnectionHttpErrorCode = 101};
// Error descriptions.
static NSString const *kMSACACConnectionHttpErrorDesc = @"An HTTP error occured.";
static NSString const *kMSACACConnectionPausedErrorDesc = @"Canceled, connection paused with log deletion.";
// Error user info keys.
static NSString const *kMSACACConnectionHttpCodeErrorKey = @"MSConnectionHttpCode";
NS_ASSUME_NONNULL_END
#endif
@@ -1,87 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CHANNEL_GROUP_PROTOCOL_H
#define MSAC_CHANNEL_GROUP_PROTOCOL_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACChannelProtocol.h>)
#import <AppCenter/MSACChannelProtocol.h>
#else
#import "MSACChannelProtocol.h"
#endif
NS_ASSUME_NONNULL_BEGIN
@class MSACChannelUnitConfiguration;
@protocol MSACIngestionProtocol;
@protocol MSACChannelUnitProtocol;
/**
* `MSACChannelGroupProtocol` represents a kind of channel that contains constituent MSACChannelUnit objects. When an operation from the
* `MSACChannelProtocol` is performed on the group, that operation should be propagated to its constituent MSACChannelUnit objects.
*/
NS_SWIFT_NAME(ChannelGroupProtocol)
@protocol MSACChannelGroupProtocol <MSACChannelProtocol>
/**
* Initialize a channel unit with the given configuration.
*
* @param configuration channel configuration.
*
* @return The added `MSACChannelUnitProtocol`. Use this object to enqueue logs.
*/
- (id<MSACChannelUnitProtocol>)addChannelUnitWithConfiguration:(MSACChannelUnitConfiguration *)configuration
NS_SWIFT_NAME(addChannelUnit(withConfiguration:));
/**
* Initialize a channel unit with the given configuration.
*
* @param configuration channel configuration.
* @param ingestion The alternative ingestion object
*
* @return The added `MSACChannelUnitProtocol`. Use this object to enqueue logs.
*/
- (id<MSACChannelUnitProtocol>)addChannelUnitWithConfiguration:(MSACChannelUnitConfiguration *)configuration
withIngestion:(nullable id<MSACIngestionProtocol>)ingestion
NS_SWIFT_NAME(addChannelUnit(_:ingestion:));
/**
* Change the base URL (schema + authority + port only) used to communicate with the backend.
*/
@property(nonatomic, strong) NSString *_Nullable logUrl;
/**
* Set the app secret.
*/
@property(nonatomic, strong) NSString *_Nullable appSecret;
/**
* Set the maximum size of the internal storage. This method must be called before App Center is started.
*
* @discussion The default maximum database size is 10485760 bytes (10 MiB).
*
* @param sizeInBytes Maximum size of the internal storage in bytes. This will be rounded up to the nearest multiple of a SQLite page size
* (default is 4096 bytes). Values below 24576 bytes (24 KiB) will be ignored.
* @param completionHandler Callback that is invoked when the database size has been set. The `BOOL` parameter is `YES` if changing the size
* is successful, and `NO` otherwise.
*/
- (void)setMaxStorageSize:(long)sizeInBytes
completionHandler:(nullable void (^)(BOOL))completionHandler NS_SWIFT_NAME(setMaxStorageSize(_:completionHandler:));
/**
* Return a channel unit instance for the given groupId.
*
* @param groupId The group ID for a channel unit.
*
* @return A channel unit instance or `nil`.
*/
- (nullable id<MSACChannelUnitProtocol>)channelUnitForGroupId:(NSString *)groupId;
@end
NS_ASSUME_NONNULL_END
#endif
@@ -1,68 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CHANNEL_PROTOCOL_H
#define MSAC_CHANNEL_PROTOCOL_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACEnable.h>)
#import <AppCenter/MSACEnable.h>
#else
#import "MSACEnable.h"
#endif
NS_ASSUME_NONNULL_BEGIN
@protocol MSACChannelDelegate;
/**
* `MSACChannelProtocol` contains the essential operations of a channel. Channels are broadly responsible for enqueuing logs to be sent to
* the backend and/or stored on disk.
*/
NS_SWIFT_NAME(ChannelProtocol)
@protocol MSACChannelProtocol <NSObject, MSACEnable>
/**
* Add delegate.
*
* @param delegate delegate.
*/
- (void)addDelegate:(id<MSACChannelDelegate>)delegate;
/**
* Remove delegate.
*
* @param delegate delegate.
*/
- (void)removeDelegate:(id<MSACChannelDelegate>)delegate;
/**
* Pause operations, logs will be stored but not sent.
*
* @param identifyingObject Object used to identify the pause request.
*
* @discussion A paused channel doesn't forward logs to the ingestion. The identifying object used to pause the channel can be any unique
* object. The same identifying object must be used to call resume. For simplicity if the caller is the one owning the channel then @c self
* can be used as identifying object.
*
* @see resumeWithIdentifyingObject:
*/
- (void)pauseWithIdentifyingObject:(id<NSObject>)identifyingObject;
/**
* Resume operations, logs can be sent again.
*
* @param identifyingObject Object used to passed to the pause method.
*
* @discussion The channel only resume when all the outstanding identifying objects have been resumed.
*
* @see pauseWithIdentifyingObject:
*/
- (void)resumeWithIdentifyingObject:(id<NSObject>)identifyingObject;
@end
NS_ASSUME_NONNULL_END
#endif
@@ -1,18 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CONSTANTS_FLAGS_H
#define MSAC_CONSTANTS_FLAGS_H
#import <Foundation/Foundation.h>
typedef NS_OPTIONS(NSUInteger, MSACFlags) {
MSACFlagsNone = (0 << 0), // => 00000000
MSACFlagsNormal = (1 << 0), // => 00000001
MSACFlagsCritical = (1 << 1), // => 00000010
MSACFlagsPersistenceNormal DEPRECATED_MSG_ATTRIBUTE("please use MSACFlagsNormal") = MSACFlagsNormal,
MSACFlagsPersistenceCritical DEPRECATED_MSG_ATTRIBUTE("please use MSACFlagsCritical") = MSACFlagsCritical,
MSACFlagsDefault = MSACFlagsNormal
} NS_SWIFT_NAME(Flags);
#endif
@@ -1,170 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
/**
* Log Levels
*/
typedef NS_ENUM(NSUInteger, MSACLogLevel) {
/**
* Logging will be very chatty
*/
MSACLogLevelVerbose = 2,
/**
* Debug information will be logged
*/
MSACLogLevelDebug = 3,
/**
* Information will be logged
*/
MSACLogLevelInfo = 4,
/**
* Errors and warnings will be logged
*/
MSACLogLevelWarning = 5,
/**
* Errors will be logged
*/
MSACLogLevelError = 6,
/**
* Only critical errors will be logged
*/
MSACLogLevelAssert = 7,
/**
* Logging is disabled
*/
MSACLogLevelNone = 99
} NS_SWIFT_NAME(LogLevel);
typedef NSString * (^MSACLogMessageProvider)(void)NS_SWIFT_NAME(LogMessageProvider);
typedef void (^MSACLogHandler)(MSACLogMessageProvider messageProvider, MSACLogLevel logLevel, NSString *tag, const char *file,
const char *function, uint line) NS_SWIFT_NAME(LogHandler);
/**
* Channel priorities, check the kMSACPriorityCount if you add a new value.
* The order matters here! Values NEED to range from low priority to high priority.
*/
typedef NS_ENUM(NSInteger, MSACPriority) { MSACPriorityBackground, MSACPriorityDefault, MSACPriorityHigh } NS_SWIFT_NAME(Priority);
static short const kMSACPriorityCount = MSACPriorityHigh + 1;
/**
* The priority by which the modules are initialized.
* MSACPriorityMax is reserved for only 1 module and this needs to be Crashes.
* Crashes needs to be initialized first to catch crashes in our other SDK Modules (which will hopefully never happen) and to avoid losing
* any log at crash time.
*/
typedef NS_ENUM(NSInteger, MSACInitializationPriority) {
MSACInitializationPriorityDefault = 500,
MSACInitializationPriorityHigh = 750,
MSACInitializationPriorityMax = 999
} NS_SWIFT_NAME(InitializationPriority);
/**
* Enum with the different HTTP status codes.
*/
typedef NS_ENUM(NSInteger, MSACHTTPCodesNo) {
// Invalid
MSACHTTPCodesNo0XXInvalidUnknown = 0,
// Informational
MSACHTTPCodesNo1XXInformationalUnknown = 1,
MSACHTTPCodesNo100Continue = 100,
MSACHTTPCodesNo101SwitchingProtocols = 101,
MSACHTTPCodesNo102Processing = 102,
// Success
MSACHTTPCodesNo2XXSuccessUnknown = 2,
MSACHTTPCodesNo200OK = 200,
MSACHTTPCodesNo201Created = 201,
MSACHTTPCodesNo202Accepted = 202,
MSACHTTPCodesNo203NonAuthoritativeInformation = 203,
MSACHTTPCodesNo204NoContent = 204,
MSACHTTPCodesNo205ResetContent = 205,
MSACHTTPCodesNo206PartialContent = 206,
MSACHTTPCodesNo207MultiStatus = 207,
MSACHTTPCodesNo208AlreadyReported = 208,
MSACHTTPCodesNo209IMUsed = 209,
// Redirection
MSACHTTPCodesNo3XXSuccessUnknown = 3,
MSACHTTPCodesNo300MultipleChoices = 300,
MSACHTTPCodesNo301MovedPermanently = 301,
MSACHTTPCodesNo302Found = 302,
MSACHTTPCodesNo303SeeOther = 303,
MSACHTTPCodesNo304NotModified = 304,
MSACHTTPCodesNo305UseProxy = 305,
MSACHTTPCodesNo306SwitchProxy = 306,
MSACHTTPCodesNo307TemporaryRedirect = 307,
MSACHTTPCodesNo308PermanentRedirect = 308,
// Client error
MSACHTTPCodesNo4XXSuccessUnknown = 4,
MSACHTTPCodesNo400BadRequest = 400,
MSACHTTPCodesNo401Unauthorised = 401,
MSACHTTPCodesNo402PaymentRequired = 402,
MSACHTTPCodesNo403Forbidden = 403,
MSACHTTPCodesNo404NotFound = 404,
MSACHTTPCodesNo405MethodNotAllowed = 405,
MSACHTTPCodesNo406NotAcceptable = 406,
MSACHTTPCodesNo407ProxyAuthenticationRequired = 407,
MSACHTTPCodesNo408RequestTimeout = 408,
MSACHTTPCodesNo409Conflict = 409,
MSACHTTPCodesNo410Gone = 410,
MSACHTTPCodesNo411LengthRequired = 411,
MSACHTTPCodesNo412PreconditionFailed = 412,
MSACHTTPCodesNo413RequestEntityTooLarge = 413,
MSACHTTPCodesNo414RequestURITooLong = 414,
MSACHTTPCodesNo415UnsupportedMediaType = 415,
MSACHTTPCodesNo416RequestedRangeNotSatisfiable = 416,
MSACHTTPCodesNo417ExpectationFailed = 417,
MSACHTTPCodesNo418IamATeapot = 418,
MSACHTTPCodesNo419AuthenticationTimeout = 419,
MSACHTTPCodesNo420MethodFailureSpringFramework = 420,
MSACHTTPCodesNo420EnhanceYourCalmTwitter = 4200,
MSACHTTPCodesNo422UnprocessableEntity = 422,
MSACHTTPCodesNo423Locked = 423,
MSACHTTPCodesNo424FailedDependency = 424,
MSACHTTPCodesNo424MethodFailureWebDaw = 4240,
MSACHTTPCodesNo425UnorderedCollection = 425,
MSACHTTPCodesNo426UpgradeRequired = 426,
MSACHTTPCodesNo428PreconditionRequired = 428,
MSACHTTPCodesNo429TooManyRequests = 429,
MSACHTTPCodesNo431RequestHeaderFieldsTooLarge = 431,
MSACHTTPCodesNo444NoResponseNginx = 444,
MSACHTTPCodesNo449RetryWithMicrosoft = 449,
MSACHTTPCodesNo450BlockedByWindowsParentalControls = 450,
MSACHTTPCodesNo451RedirectMicrosoft = 451,
MSACHTTPCodesNo451UnavailableForLegalReasons = 4510,
MSACHTTPCodesNo494RequestHeaderTooLargeNginx = 494,
MSACHTTPCodesNo495CertErrorNginx = 495,
MSACHTTPCodesNo496NoCertNginx = 496,
MSACHTTPCodesNo497HTTPToHTTPSNginx = 497,
MSACHTTPCodesNo499ClientClosedRequestNginx = 499,
// Server error
MSACHTTPCodesNo5XXSuccessUnknown = 5,
MSACHTTPCodesNo500InternalServerError = 500,
MSACHTTPCodesNo501NotImplemented = 501,
MSACHTTPCodesNo502BadGateway = 502,
MSACHTTPCodesNo503ServiceUnavailable = 503,
MSACHTTPCodesNo504GatewayTimeout = 504,
MSACHTTPCodesNo505HTTPVersionNotSupported = 505,
MSACHTTPCodesNo506VariantAlsoNegotiates = 506,
MSACHTTPCodesNo507InsufficientStorage = 507,
MSACHTTPCodesNo508LoopDetected = 508,
MSACHTTPCodesNo509BandwidthLimitExceeded = 509,
MSACHTTPCodesNo510NotExtended = 510,
MSACHTTPCodesNo511NetworkAuthenticationRequired = 511,
MSACHTTPCodesNo522ConnectionTimedOut = 522,
MSACHTTPCodesNo598NetworkReadTimeoutErrorUnknown = 598,
MSACHTTPCodesNo599NetworkConnectTimeoutErrorUnknown = 599
} NS_SWIFT_NAME(HTTPCodesNo);
@@ -1,71 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CUSTOM_PROPERTIES_H
#define MSAC_CUSTOM_PROPERTIES_H
#import <Foundation/Foundation.h>
/**
* Custom properties builder.
* Collects multiple properties to send in one log.
*/
NS_SWIFT_NAME(CustomProperties)
@interface MSACCustomProperties : NSObject
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setString:(NSString *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setNumber:(NSNumber *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setBool:(BOOL)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setDate:(NSDate *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Clear the property for the specified key.
*
* @param key Key whose mapping is to be cleared.
*
* @return This instance.
*/
- (instancetype)clearPropertyForKey:(NSString *)key NS_SWIFT_NAME(clearProperty(forKey:));
@end
#endif
@@ -1,101 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_DEVICE_H
#define MSAC_DEVICE_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACWrapperSdk.h>)
#import <AppCenter/MSACWrapperSdk.h>
#else
#import "MSACWrapperSdk.h"
#endif
NS_SWIFT_NAME(Device)
@interface MSACDevice : MSACWrapperSdk
/*
* Name of the SDK. Consists of the name of the SDK and the platform, e.g. "appcenter.ios", "appcenter.android"
*/
@property(nonatomic, copy, readonly) NSString *sdkName;
/*
* Version of the SDK in semver format, e.g. "1.2.0" or "0.12.3-alpha.1".
*/
@property(nonatomic, copy, readonly) NSString *sdkVersion;
/*
* Device model (example: iPad2,3).
*/
@property(nonatomic, copy, readonly) NSString *model;
/*
* Device manufacturer (example: HTC).
*/
@property(nonatomic, copy, readonly) NSString *oemName;
/*
* OS name (example: iOS).
*/
@property(nonatomic, copy, readonly) NSString *osName;
/*
* OS version (example: 9.3.0).
*/
@property(nonatomic, copy, readonly) NSString *osVersion;
/*
* OS build code (example: LMY47X). [optional]
*/
@property(nonatomic, copy, readonly) NSString *osBuild;
/*
* API level when applicable like in Android (example: 15). [optional]
*/
@property(nonatomic, copy, readonly) NSNumber *osApiLevel;
/*
* Language code (example: en_US).
*/
@property(nonatomic, copy, readonly) NSString *locale;
/*
* The offset in minutes from UTC for the device time zone, including daylight savings time.
*/
@property(nonatomic, readonly, strong) NSNumber *timeZoneOffset;
/*
* Screen size of the device in pixels (example: 640x480).
*/
@property(nonatomic, copy, readonly) NSString *screenSize;
/*
* Application version name, e.g. 1.1.0
*/
@property(nonatomic, copy, readonly) NSString *appVersion;
/*
* Carrier name (for mobile devices). [optional]
*/
@property(nonatomic, copy, readonly) NSString *carrierName;
/*
* Carrier country code (for mobile devices). [optional]
*/
@property(nonatomic, copy, readonly) NSString *carrierCountry;
/*
* The app's build number, e.g. 42.
*/
@property(nonatomic, copy, readonly) NSString *appBuild;
/*
* The bundle identifier, package identifier, or namespace, depending on what the individual plattforms use, .e.g com.microsoft.example.
* [optional]
*/
@property(nonatomic, copy, readonly) NSString *appNamespace;
@end
#endif
@@ -1,27 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_ENABLE_H
#define MSAC_ENABLE_H
#import <Foundation/Foundation.h>
/**
* Protocol to define an instance that can be enabled/disabled.
*/
NS_SWIFT_NAME(Enable)
@protocol MSACEnable <NSObject>
@required
/**
* Enable/disable this instance and delete data on disabled state.
*
* @param isEnabled A boolean value set to YES to enable the instance or NO to disable it.
* @param deleteData A boolean value set to YES to delete data or NO to keep it.
*/
- (void)setEnabled:(BOOL)isEnabled andDeleteDataOnDisabled:(BOOL)deleteData NS_SWIFT_NAME(setEnabled(_:deleteDataOnDisabled:));
@end
#endif
@@ -1,74 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_LOG_H
#define MSAC_LOG_H
#import <Foundation/Foundation.h>
@class MSACDevice;
NS_SWIFT_NAME(Log)
@protocol MSACLog <NSObject>
/**
* Log type.
*/
@property(nonatomic, copy) NSString *type;
/**
* Log timestamp.
*/
@property(nonatomic, strong) NSDate *timestamp;
/**
* A session identifier is used to correlate logs together. A session is an abstract concept in the API and is not necessarily an analytics
* session, it can be used to only track crashes.
*/
@property(nonatomic, copy) NSString *sid;
/**
* Optional distribution group ID value.
*/
@property(nonatomic, copy) NSString *distributionGroupId;
/**
* Optional user identifier.
*/
@property(nonatomic, copy) NSString *userId;
/**
* Device properties associated to this log.
*/
@property(nonatomic, strong) MSACDevice *device;
/**
* Transient object tag. For example, a log can be tagged with a transmission target. We do this currently to prevent properties being
* applied retroactively to previous logs by comparing their tags.
*/
@property(nonatomic, strong) NSObject *tag;
/**
* Checks if the object's values are valid.
*
* @return YES, if the object is valid.
*/
- (BOOL)isValid;
/**
* Adds a transmission target token that this log should be sent to.
*
* @param token The transmission target token.
*/
- (void)addTransmissionTargetToken:(NSString *)token;
/**
* Gets all transmission target tokens that this log should be sent to.
*
* @returns Collection of transmission target tokens that this log should be sent to.
*/
- (NSSet *)transmissionTargetTokens;
@end
#endif
@@ -1,25 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_LOG_WITH_PROPERTIES_H
#define MSAC_LOG_WITH_PROPERTIES_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACAbstractLog.h>)
#import <AppCenter/MSACAbstractLog.h>
#else
#import "MSACAbstractLog.h"
#endif
NS_SWIFT_NAME(LogWithProperties)
@interface MSACLogWithProperties : MSACAbstractLog
/**
* Additional key/value pair parameters. [optional]
*/
@property(nonatomic, strong) NSDictionary<NSString *, NSString *> *properties;
@end
#endif
@@ -1,54 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#ifndef MSAC_LOGGER
#define MSAC_LOGGER
#if __has_include(<AppCenter/MSACConstants.h>)
#import <AppCenter/MSACConstants.h>
#else
#import "MSACConstants.h"
#endif
#define MSACLog(_level, _tag, _message) \
[MSACLogger logMessage:_message level:_level tag:_tag file:__FILE__ function:__PRETTY_FUNCTION__ line:__LINE__]
#define MSACLogAssert(tag, format, ...) \
MSACLog(MSACLogLevelAssert, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogError(tag, format, ...) \
MSACLog(MSACLogLevelError, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogWarning(tag, format, ...) \
MSACLog(MSACLogLevelWarning, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogInfo(tag, format, ...) \
MSACLog(MSACLogLevelInfo, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogDebug(tag, format, ...) \
MSACLog(MSACLogLevelDebug, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogVerbose(tag, format, ...) \
MSACLog(MSACLogLevelVerbose, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
NS_SWIFT_NAME(Logger)
@interface MSACLogger : NSObject
+ (void)logMessage:(MSACLogMessageProvider)messageProvider
level:(MSACLogLevel)loglevel
tag:(NSString *)tag
file:(const char *)file
function:(const char *)function
line:(uint)line;
@end
#endif
@@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#ifndef SERIALIZABLE_OBJECT_H
#define SERIALIZABLE_OBJECT_H
@protocol MSACSerializableObject <NSCoding>
/**
* Serialize this object to a dictionary.
*
* @return A dictionary representing this object.
*/
- (NSMutableDictionary *)serializeToDictionary;
@end
#endif
@@ -1,23 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_SERVICE_H
#define MSAC_SERVICE_H
#import <Foundation/Foundation.h>
/**
* Protocol declaring service logic.
*/
NS_SWIFT_NAME(Service)
@protocol MSACService <NSObject>
/**
* Indicates whether this service is enabled.
* The state is persisted in the device's storage across application launches.
*/
@property(class, nonatomic, getter=isEnabled, setter=setEnabled:) BOOL enabled NS_SWIFT_NAME(enabled);
@end
#endif
@@ -1,58 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_SERVICE_ABSTRACT_H
#define MSAC_SERVICE_ABSTRACT_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACService.h>)
#import <AppCenter/MSACService.h>
#else
#import "MSACService.h"
#endif
@protocol MSACChannelGroupProtocol;
/**
* Abstraction of services common logic.
* This class is intended to be subclassed only not instantiated directly.
*/
NS_SWIFT_NAME(ServiceAbstract)
@interface MSACServiceAbstract : NSObject <MSACService>
/**
* The flag indicates whether the service is started from application or not.
*/
@property(nonatomic, assign) BOOL startedFromApplication;
/**
* Start this service with a channel group. Also sets the flag that indicates that a service has been started.
*
* @param channelGroup channel group used to persist and send logs.
* @param appSecret app secret for the SDK.
* @param token default transmission target token for this service.
* @param fromApplication indicates whether the service started from an application or not.
*/
- (void)startWithChannelGroup:(id<MSACChannelGroupProtocol>)channelGroup
appSecret:(NSString *)appSecret
transmissionTargetToken:(NSString *)token
fromApplication:(BOOL)fromApplication;
/**
* Update configuration when the service requires to start again. This method should only be called if the service is started from libraries
* and then is being started from an application.
*
* @param appSecret app secret for the SDK.
* @param token default transmission target token for this service.
*/
- (void)updateConfigurationWithAppSecret:(NSString *)appSecret transmissionTargetToken:(NSString *)token;
/**
* The flag indicate whether the service needs the application secret or not.
*/
@property(atomic, readonly) BOOL isAppSecretRequired;
@end
#endif
@@ -1,21 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACConstants.h>)
#import <AppCenter/MSACConstants.h>
#else
#import "MSACConstants.h"
#endif
/**
* This is a utility for producing App Center style log messages. It is only intended for use by App Center services and wrapper SDKs of App
* Center.
*/
NS_SWIFT_NAME(WrapperLogger)
@interface MSACWrapperLogger : NSObject
+ (void)MSACWrapperLog:(MSACLogMessageProvider)message tag:(NSString *)tag level:(MSACLogLevel)level;
@end
@@ -1,60 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_WRAPPER_SDK_H
#define MSAC_WRAPPER_SDK_H
#import <Foundation/Foundation.h>
NS_SWIFT_NAME(WrapperSdk)
@interface MSACWrapperSdk : NSObject
/*
* Version of the wrapper SDK. When the SDK is embedding another base SDK (for example Xamarin.Android wraps Android), the Xamarin specific
* version is populated into this field while sdkVersion refers to the original Android SDK. [optional]
*/
@property(nonatomic, copy, readonly) NSString *wrapperSdkVersion;
/*
* Name of the wrapper SDK (examples: Xamarin, Cordova). [optional]
*/
@property(nonatomic, copy, readonly) NSString *wrapperSdkName;
/*
* Version of the wrapper technology framework (Xamarin runtime version or ReactNative or Cordova etc...). [optional]
*/
@property(nonatomic, copy, readonly) NSString *wrapperRuntimeVersion;
/*
* Label that is used to identify application code 'version' released via Live Update beacon running on device.
*/
@property(nonatomic, copy, readonly) NSString *liveUpdateReleaseLabel;
/*
* Identifier of environment that current application release belongs to, deployment key then maps to environment like Production, Staging.
*/
@property(nonatomic, copy, readonly) NSString *liveUpdateDeploymentKey;
/*
* Hash of all files (ReactNative or Cordova) deployed to device via LiveUpdate beacon. Helps identify the Release version on device or need
* to download updates in future
*/
@property(nonatomic, copy, readonly) NSString *liveUpdatePackageHash;
- (instancetype)initWithWrapperSdkVersion:(NSString *)wrapperSdkVersion
wrapperSdkName:(NSString *)wrapperSdkName
wrapperRuntimeVersion:(NSString *)wrapperRuntimeVersion
liveUpdateReleaseLabel:(NSString *)liveUpdateReleaseLabel
liveUpdateDeploymentKey:(NSString *)liveUpdateDeploymentKey
liveUpdatePackageHash:(NSString *)liveUpdatePackageHash;
/**
* Checks if the object's values are valid.
*
* @return YES, if the object is valid.
*/
- (BOOL)isValid;
@end
#endif
@@ -1,13 +0,0 @@
framework module AppCenter {
umbrella header "AppCenter.h"
export *
module * { export * }
link framework "Foundation"
link framework "CoreTelephony"
link framework "SystemConfiguration"
link framework "UIKit"
link "sqlite3"
link "z"
}
@@ -1,114 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#import "MSACConstants+Flags.h"
@protocol MSACChannelUnitProtocol;
@protocol MSACChannelGroupProtocol;
@protocol MSACChannelProtocol;
@protocol MSACLog;
NS_ASSUME_NONNULL_BEGIN
@protocol MSACChannelDelegate <NSObject>
@optional
/**
* A callback that is called when a channel unit is added to the channel group.
*
* @param channelGroup The channel group.
* @param channel The newly added channel.
*/
- (void)channelGroup:(id<MSACChannelGroupProtocol>)channelGroup didAddChannelUnit:(id<MSACChannelUnitProtocol>)channel;
/**
* A callback that is called when a log is just enqueued. Delegates may want to prepare the log a little more before further processing.
*
* @param log The log to prepare.
*/
- (void)channel:(id<MSACChannelProtocol>)channel prepareLog:(id<MSACLog>)log;
/**
* A callback that is called after a log is definitely prepared.
*
* @param log The log.
* @param internalId An internal Id to keep track of logs.
* @param flags Options for the log.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didPrepareLog:(id<MSACLog>)log internalId:(NSString *)internalId flags:(MSACFlags)flags;
/**
* A callback that is called after a log completed the enqueueing process whether it was successful or not.
*
* @param log The log.
* @param internalId An internal Id to keep track of logs.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didCompleteEnqueueingLog:(id<MSACLog>)log internalId:(NSString *)internalId;
/**
* Callback method that will be called before each log will be send to the server.
*
* @param channel The channel object.
* @param log The log to be sent.
*/
- (void)channel:(id<MSACChannelProtocol>)channel willSendLog:(id<MSACLog>)log;
/**
* Callback method that will be called in case the SDK was able to send a log.
*
* @param channel The channel object.
* @param log The log to be sent.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didSucceedSendingLog:(id<MSACLog>)log;
/**
* Callback method that will be called in case the SDK was unable to send a log.
*
* @param channel The channel object.
* @param log The log to be sent.
* @param error The error that occured.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didFailSendingLog:(id<MSACLog>)log withError:(nullable NSError *)error;
/**
* A callback that is called when setEnabled has been invoked.
*
* @param channel The channel.
* @param isEnabled The boolean that indicates enabled.
* @param deletedData The boolean that indicates deleting data on disabled.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didSetEnabled:(BOOL)isEnabled andDeleteDataOnDisabled:(BOOL)deletedData;
/**
* A callback that is called when pause has been invoked.
*
* @param channel The channel.
* @param identifyingObject The identifying object used to pause the channel.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didPauseWithIdentifyingObject:(id<NSObject>)identifyingObject;
/**
* A callback that is called when resume has been invoked.
*
* @param channel The channel.
* @param identifyingObject The identifying object used to resume the channel.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didResumeWithIdentifyingObject:(id<NSObject>)identifyingObject;
/**
* Callback method that will determine if a log should be filtered out from the usual processing pipeline. If any delegate returns true, the
* log is filtered.
*
* @param channelUnit The channel unit that is going to send the log.
* @param log The log to be filtered or not.
*
* @return `true` if the log should be filtered out.
*/
- (BOOL)channelUnit:(id<MSACChannelUnitProtocol>)channelUnit shouldFilterLog:(id<MSACLog>)log;
@end
NS_ASSUME_NONNULL_END
@@ -1,417 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Headers/AppCenter.h</key>
<data>
w9sW6K7DVhGfORLCjGXijaR25m0=
</data>
<key>Headers/MSACAbstractLog.h</key>
<data>
+Ikfy/fTOpqwPZM3Fpii3cpsx8Y=
</data>
<key>Headers/MSACAppCenter.h</key>
<data>
2cUgfgx3odOGivdk+n6FXq94KgU=
</data>
<key>Headers/MSACAppCenterErrors.h</key>
<data>
x7h4qpHD4GI3jrJ3F7n4UXAANsk=
</data>
<key>Headers/MSACChannelGroupProtocol.h</key>
<data>
jyWCHN4PSygLVy0IM5565DvDQAc=
</data>
<key>Headers/MSACChannelProtocol.h</key>
<data>
Y1rKi/TsirTR0MGBf1rIO/TTG0A=
</data>
<key>Headers/MSACConstants+Flags.h</key>
<data>
GK1gUSyIjWdv7KBP68wNxjxaH+E=
</data>
<key>Headers/MSACConstants.h</key>
<data>
d9HwKA0/VH3+pLRj1Pd49mqn2gI=
</data>
<key>Headers/MSACCustomProperties.h</key>
<data>
m7A9hEgL3d0gV4SyKmXJYRtwqoQ=
</data>
<key>Headers/MSACDevice.h</key>
<data>
suv4Wkt36Nkscy7jX2SSYzrkLRs=
</data>
<key>Headers/MSACEnable.h</key>
<data>
3DnplEFkD1LImYNk+84TqcQvBho=
</data>
<key>Headers/MSACLog.h</key>
<data>
1/7NIwYuYLGHIVMZps8b6/zOpJg=
</data>
<key>Headers/MSACLogWithProperties.h</key>
<data>
I4y13KVE36pyXv85mc5OWlCjplE=
</data>
<key>Headers/MSACLogger.h</key>
<data>
CaYHmB3+psy5/txfMvd2+bWGJkc=
</data>
<key>Headers/MSACSerializableObject.h</key>
<data>
or5nqKvOQVn2ZieUCmYK6fIZkWY=
</data>
<key>Headers/MSACService.h</key>
<data>
lz5atiMe+oTdu9e6g74KPC0CjOs=
</data>
<key>Headers/MSACServiceAbstract.h</key>
<data>
rBHatSAJK78PLgsMIpFqkby4tgA=
</data>
<key>Headers/MSACWrapperLogger.h</key>
<data>
qBVuNkF12BZYytRhCKwZ7zkiKhc=
</data>
<key>Headers/MSACWrapperSdk.h</key>
<data>
W9sdhEGnIGk/aFHS3gWwQ6FxUfI=
</data>
<key>Info.plist</key>
<data>
vQsDzcm1lLcpUNIaE5cw31rdoVk=
</data>
<key>Modules/module.modulemap</key>
<data>
go9b9XYQJIVcGlS/K5PS+8A+0dI=
</data>
<key>PrivateHeaders/MSACChannelDelegate.h</key>
<data>
Msff4BZ/b1IjaYeKTDBHtNtT7wI=
</data>
</dict>
<key>files2</key>
<dict>
<key>Headers/AppCenter.h</key>
<dict>
<key>hash</key>
<data>
w9sW6K7DVhGfORLCjGXijaR25m0=
</data>
<key>hash2</key>
<data>
e9qe35Ew1pz0RMBfwa2Jv+3188p8iTwwktkIgCa/ztg=
</data>
</dict>
<key>Headers/MSACAbstractLog.h</key>
<dict>
<key>hash</key>
<data>
+Ikfy/fTOpqwPZM3Fpii3cpsx8Y=
</data>
<key>hash2</key>
<data>
7hsXFv3UkGsJLcc3eh2pMUrGbGYP2hCUC854z05SzNQ=
</data>
</dict>
<key>Headers/MSACAppCenter.h</key>
<dict>
<key>hash</key>
<data>
2cUgfgx3odOGivdk+n6FXq94KgU=
</data>
<key>hash2</key>
<data>
C10z0NrhN4J4qdWbypOdjlQ8QLlq4tvPMP21geOS4vI=
</data>
</dict>
<key>Headers/MSACAppCenterErrors.h</key>
<dict>
<key>hash</key>
<data>
x7h4qpHD4GI3jrJ3F7n4UXAANsk=
</data>
<key>hash2</key>
<data>
OcNwIIu4yFxG62mZtiABP3/9DoN9tj1fL/7nSvF8u8s=
</data>
</dict>
<key>Headers/MSACChannelGroupProtocol.h</key>
<dict>
<key>hash</key>
<data>
jyWCHN4PSygLVy0IM5565DvDQAc=
</data>
<key>hash2</key>
<data>
d36rCjxsURqDkFv+g5BwWNybz5Zksc9B91gqArFcJbk=
</data>
</dict>
<key>Headers/MSACChannelProtocol.h</key>
<dict>
<key>hash</key>
<data>
Y1rKi/TsirTR0MGBf1rIO/TTG0A=
</data>
<key>hash2</key>
<data>
fI1fLkJvo9SXh2bAUWKIYlretRCOoGWJwlyvqMfQZNc=
</data>
</dict>
<key>Headers/MSACConstants+Flags.h</key>
<dict>
<key>hash</key>
<data>
GK1gUSyIjWdv7KBP68wNxjxaH+E=
</data>
<key>hash2</key>
<data>
UDnw7GyNXzip13MvAvNKQQsWIUgU296uJHjPEkReCY8=
</data>
</dict>
<key>Headers/MSACConstants.h</key>
<dict>
<key>hash</key>
<data>
d9HwKA0/VH3+pLRj1Pd49mqn2gI=
</data>
<key>hash2</key>
<data>
xx69UfYa0qw6aSDuVsUAqd/1+t90QCPkQUae+elZwZ0=
</data>
</dict>
<key>Headers/MSACCustomProperties.h</key>
<dict>
<key>hash</key>
<data>
m7A9hEgL3d0gV4SyKmXJYRtwqoQ=
</data>
<key>hash2</key>
<data>
FveTXq+kqUdHHlSdLAoQisgT+95bzAuXTrTOQG/b/P8=
</data>
</dict>
<key>Headers/MSACDevice.h</key>
<dict>
<key>hash</key>
<data>
suv4Wkt36Nkscy7jX2SSYzrkLRs=
</data>
<key>hash2</key>
<data>
i3TVX2C+DfcRKn2HTBaydWBYHjryX2Cy/eJJxjTFiT8=
</data>
</dict>
<key>Headers/MSACEnable.h</key>
<dict>
<key>hash</key>
<data>
3DnplEFkD1LImYNk+84TqcQvBho=
</data>
<key>hash2</key>
<data>
XrDKc7bXZaW8JW4NMItSBrHLR6a+LRG1JSLXZ0U0NsI=
</data>
</dict>
<key>Headers/MSACLog.h</key>
<dict>
<key>hash</key>
<data>
1/7NIwYuYLGHIVMZps8b6/zOpJg=
</data>
<key>hash2</key>
<data>
3GF6xCTfpLDmOqKnacEOEDr5mkM/llKm0IoIEyISZKA=
</data>
</dict>
<key>Headers/MSACLogWithProperties.h</key>
<dict>
<key>hash</key>
<data>
I4y13KVE36pyXv85mc5OWlCjplE=
</data>
<key>hash2</key>
<data>
WIrz7Xsi04AboAmZ5dA3d3t8D/8PomKLwsp7oorznVM=
</data>
</dict>
<key>Headers/MSACLogger.h</key>
<dict>
<key>hash</key>
<data>
CaYHmB3+psy5/txfMvd2+bWGJkc=
</data>
<key>hash2</key>
<data>
GipSaz+D+Z5eWauQP+10U8xvbAnxPeIRD4HTvn0F5DQ=
</data>
</dict>
<key>Headers/MSACSerializableObject.h</key>
<dict>
<key>hash</key>
<data>
or5nqKvOQVn2ZieUCmYK6fIZkWY=
</data>
<key>hash2</key>
<data>
TdCeoNla8kUqc5HPES6WNwi7ycy+4vRr3HGDipEXNVE=
</data>
</dict>
<key>Headers/MSACService.h</key>
<dict>
<key>hash</key>
<data>
lz5atiMe+oTdu9e6g74KPC0CjOs=
</data>
<key>hash2</key>
<data>
aiO/PWAQDwhbPW1HDGqNM0kn4xYSwqPmdpmcTgpW/CE=
</data>
</dict>
<key>Headers/MSACServiceAbstract.h</key>
<dict>
<key>hash</key>
<data>
rBHatSAJK78PLgsMIpFqkby4tgA=
</data>
<key>hash2</key>
<data>
vi9/mVDQylipTtHNfUe9r4GXjlc2bEnKFV8wmN/IXaE=
</data>
</dict>
<key>Headers/MSACWrapperLogger.h</key>
<dict>
<key>hash</key>
<data>
qBVuNkF12BZYytRhCKwZ7zkiKhc=
</data>
<key>hash2</key>
<data>
h2VHxvALAogCMocFQMUjmOkhCm+qkJwpGTzxwdxTdwo=
</data>
</dict>
<key>Headers/MSACWrapperSdk.h</key>
<dict>
<key>hash</key>
<data>
W9sdhEGnIGk/aFHS3gWwQ6FxUfI=
</data>
<key>hash2</key>
<data>
5x+0epJnQN2wZKY2xjvsjAYrr6H1QGYIGz0ptux72dU=
</data>
</dict>
<key>Modules/module.modulemap</key>
<dict>
<key>hash</key>
<data>
go9b9XYQJIVcGlS/K5PS+8A+0dI=
</data>
<key>hash2</key>
<data>
o0lkqm4+xeVosltUC3U+jCZnS35Tg8gUiUaKXbo0ZbQ=
</data>
</dict>
<key>PrivateHeaders/MSACChannelDelegate.h</key>
<dict>
<key>hash</key>
<data>
Msff4BZ/b1IjaYeKTDBHtNtT7wI=
</data>
<key>hash2</key>
<data>
d1uS+ptvOX/o3CCB23FEJAtvcf7KIf/8ozlruAf1f0g=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>
@@ -1 +0,0 @@
Versions/Current/AppCenter
@@ -1 +0,0 @@
Versions/Current/PrivateHeaders
@@ -1,44 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACAppCenter.h>)
#import <AppCenter/MSACAbstractLog.h>
#import <AppCenter/MSACAppCenter.h>
#import <AppCenter/MSACAppCenterErrors.h>
#import <AppCenter/MSACChannelGroupProtocol.h>
#import <AppCenter/MSACChannelProtocol.h>
#import <AppCenter/MSACConstants+Flags.h>
#import <AppCenter/MSACConstants.h>
#import <AppCenter/MSACCustomProperties.h>
#import <AppCenter/MSACDevice.h>
#import <AppCenter/MSACEnable.h>
#import <AppCenter/MSACLog.h>
#import <AppCenter/MSACLogWithProperties.h>
#import <AppCenter/MSACLogger.h>
#import <AppCenter/MSACSerializableObject.h>
#import <AppCenter/MSACService.h>
#import <AppCenter/MSACServiceAbstract.h>
#import <AppCenter/MSACWrapperLogger.h>
#import <AppCenter/MSACWrapperSdk.h>
#else
#import "MSACAbstractLog.h"
#import "MSACAppCenter.h"
#import "MSACAppCenterErrors.h"
#import "MSACChannelGroupProtocol.h"
#import "MSACChannelProtocol.h"
#import "MSACConstants+Flags.h"
#import "MSACConstants.h"
#import "MSACCustomProperties.h"
#import "MSACDevice.h"
#import "MSACEnable.h"
#import "MSACLog.h"
#import "MSACLogWithProperties.h"
#import "MSACLogger.h"
#import "MSACSerializableObject.h"
#import "MSACService.h"
#import "MSACServiceAbstract.h"
#import "MSACWrapperLogger.h"
#import "MSACWrapperSdk.h"
#endif
@@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_ABSTRACT_LOG_H
#define MSAC_ABSTRACT_LOG_H
#import <Foundation/Foundation.h>
NS_SWIFT_NAME(AbstractLog)
@interface MSACAbstractLog : NSObject
@end
#endif
@@ -1,203 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#ifndef MSAC_APP_CENTER
#define MSAC_APP_CENTER
#if __has_include(<AppCenter/MSACConstants.h>)
#import <AppCenter/MSACConstants.h>
#else
#import "MSACConstants.h"
#endif
@class MSACWrapperSdk;
#if !TARGET_OS_TV
@class MSACCustomProperties;
#endif
NS_SWIFT_NAME(AppCenter)
@interface MSACAppCenter : NSObject
/**
* Returns the singleton instance of MSACAppCenter.
*/
+ (instancetype)sharedInstance;
/**
* Configure the SDK with an application secret.
*
* @param appSecret A unique and secret key used to identify the application.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)configureWithAppSecret:(NSString *)appSecret NS_SWIFT_NAME(configure(withAppSecret:));
/**
* Configure the SDK.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)configure;
/**
* Configure the SDK with an application secret and an array of services to start.
*
* @param appSecret A unique and secret key used to identify the application.
* @param services Array of services to start.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)start:(NSString *)appSecret withServices:(NSArray<Class> *)services NS_SWIFT_NAME(start(withAppSecret:services:));
/**
* Start the SDK with an array of services.
*
* @param services Array of services to start.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)startWithServices:(NSArray<Class> *)services NS_SWIFT_NAME(start(services:));
/**
* Start a service.
*
* @param service A service to start.
*
* @discussion This may be called only once per service per application process lifetime.
*/
+ (void)startService:(Class)service;
/**
* Configure the SDK with an array of services to start from a library. This will not start the service at application level, it will enable
* the service only for the library.
*
* @param services Array of services to start.
*/
+ (void)startFromLibraryWithServices:(NSArray<Class> *)services NS_SWIFT_NAME(startFromLibrary(services:));
/**
* The flag indicates whether the SDK has already been configured or not.
*/
@property(class, atomic, readonly, getter=isConfigured) BOOL configured;
/**
* The flag indicates whether app is running in App Center Test Cloud.
*/
@property(class, atomic, readonly, getter=isRunningInAppCenterTestCloud) BOOL runningInAppCenterTestCloud;
/**
* The flag indicates whether or not the SDK was enabled as a whole
*
* The state is persisted in the device's storage across application launches.
*/
@property(class, nonatomic, getter=isEnabled, setter=setEnabled:) BOOL enabled NS_SWIFT_NAME(enabled);
/**
* Flag indicating whether SDK can send network requests.
*
* The state is persisted in the device's storage across application launches.
*/
@property(class, nonatomic, getter=isNetworkRequestsAllowed, setter=setNetworkRequestsAllowed:)
BOOL networkRequestsAllowed NS_SWIFT_NAME(networkRequestsAllowed);
/**
* The SDK's log level.
*/
@property(class, nonatomic) MSACLogLevel logLevel;
/**
* Base URL to use for backend communication.
*/
@property(class, nonatomic, strong) NSString *logUrl;
/**
* Set log handler.
*/
@property(class, nonatomic) MSACLogHandler logHandler;
/**
* Set wrapper SDK information to use when building device properties. This is intended in case you are building a SDK that uses the App
* Center SDK under the hood, e.g. our Xamarin SDK or ReactNative SDk.
*/
@property(class, nonatomic, strong) MSACWrapperSdk *wrapperSdk;
#if !TARGET_OS_TV
/**
* Set the custom properties.
*
* @param customProperties Custom properties object.
*/
+ (void)setCustomProperties:(MSACCustomProperties *)customProperties;
#endif
/**
* Check whether the application delegate forwarder is enabled or not.
*
* @discussion The application delegate forwarder forwards messages that target your application delegate methods via swizzling to the SDK.
* It simplifies the SDK integration but may not be suitable to any situations. For
* instance it should be disabled if you or one of your third party SDK is doing message forwarding on the application delegate. Message
* forwarding usually implies the implementation of @see NSObject#forwardingTargetForSelector: or @see NSObject#forwardInvocation: methods.
* To disable the application delegate forwarder just add the `AppCenterAppDelegateForwarderEnabled` tag to your Info .plist file and set it
* to `0`. Then you will have to forward any application delegate needed by the SDK manually.
*/
@property(class, readonly, nonatomic, getter=isAppDelegateForwarderEnabled) BOOL appDelegateForwarderEnabled;
/**
* Unique installation identifier.
*
*/
@property(class, readonly, nonatomic) NSUUID *installId;
/**
* Detect if a debugger is attached to the app process. This is only invoked once on app startup and can not detect
* if the debugger is being attached during runtime!
*
*/
@property(class, readonly, nonatomic, getter=isDebuggerAttached) BOOL debuggerAttached;
/**
* Current version of AppCenter SDK.
*
*/
@property(class, readonly, nonatomic) NSString *sdkVersion;
/**
* Set the maximum size of the internal storage. This method must be called before App Center is started. This method is only intended for
* applications.
*
* @param sizeInBytes Maximum size of the internal storage in bytes. This will be rounded up to the nearest multiple of a SQLite page size
* (default is 4096 bytes). Values below 20,480 bytes (20 KiB) will be ignored.
*
* @param completionHandler Callback that is invoked when the database size has been set. The `BOOL` parameter is `YES` if changing the size
* is successful, and `NO` otherwise. This parameter can be null.
*
* @discussion This only sets the maximum size of the database, but App Center modules might store additional data.
* The value passed to this method is not persisted on disk. The default maximum database size is 10485760 bytes (10 MiB).
*/
+ (void)setMaxStorageSize:(long)sizeInBytes completionHandler:(void (^)(BOOL))completionHandler;
/**
* Set the user identifier.
*
* @discussion Set the user identifier for logs sent for the default target token when the secret passed in @c
* MSACAppCenter:start:withServices: contains "target={targetToken}".
*
* For App Center backend the user identifier maximum length is 256 characters.
*
* AppCenter must be configured or started before this API can be used.
*/
@property(class, nonatomic, strong) NSString *userId;
/**
* Set country code to use when building device properties.
*
* @see https://www.iso.org/obp/ui/#search for more information.
*/
@property(class, nonatomic, strong) NSString *countryCode;
@end
#endif
@@ -1,41 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_APP_CENTER_ERRORS_H
#define MSAC_APP_CENTER_ERRORS_H
#import <Foundation/Foundation.h>
#define MSAC_APP_CENTER_BASE_DOMAIN @"com.Microsoft.AppCenter."
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Domain
static NSString *const kMSACACErrorDomain = MSAC_APP_CENTER_BASE_DOMAIN @"ErrorDomain";
#pragma mark - General
// Error codes.
NS_ENUM(NSInteger){MSACACLogInvalidContainerErrorCode = 1, MSACACCanceledErrorCode = 2, MSACACDisabledErrorCode = 3};
// Error descriptions.
static NSString const *kMSACACLogInvalidContainerErrorDesc = @"Invalid log container.";
static NSString const *kMSACACCanceledErrorDesc = @"The operation was canceled.";
static NSString const *kMSACACDisabledErrorDesc = @"The service is disabled.";
#pragma mark - Connection
// Error codes.
NS_ENUM(NSInteger){MSACACConnectionPausedErrorCode = 100, MSACACConnectionHttpErrorCode = 101};
// Error descriptions.
static NSString const *kMSACACConnectionHttpErrorDesc = @"An HTTP error occured.";
static NSString const *kMSACACConnectionPausedErrorDesc = @"Canceled, connection paused with log deletion.";
// Error user info keys.
static NSString const *kMSACACConnectionHttpCodeErrorKey = @"MSConnectionHttpCode";
NS_ASSUME_NONNULL_END
#endif
@@ -1,87 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CHANNEL_GROUP_PROTOCOL_H
#define MSAC_CHANNEL_GROUP_PROTOCOL_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACChannelProtocol.h>)
#import <AppCenter/MSACChannelProtocol.h>
#else
#import "MSACChannelProtocol.h"
#endif
NS_ASSUME_NONNULL_BEGIN
@class MSACChannelUnitConfiguration;
@protocol MSACIngestionProtocol;
@protocol MSACChannelUnitProtocol;
/**
* `MSACChannelGroupProtocol` represents a kind of channel that contains constituent MSACChannelUnit objects. When an operation from the
* `MSACChannelProtocol` is performed on the group, that operation should be propagated to its constituent MSACChannelUnit objects.
*/
NS_SWIFT_NAME(ChannelGroupProtocol)
@protocol MSACChannelGroupProtocol <MSACChannelProtocol>
/**
* Initialize a channel unit with the given configuration.
*
* @param configuration channel configuration.
*
* @return The added `MSACChannelUnitProtocol`. Use this object to enqueue logs.
*/
- (id<MSACChannelUnitProtocol>)addChannelUnitWithConfiguration:(MSACChannelUnitConfiguration *)configuration
NS_SWIFT_NAME(addChannelUnit(withConfiguration:));
/**
* Initialize a channel unit with the given configuration.
*
* @param configuration channel configuration.
* @param ingestion The alternative ingestion object
*
* @return The added `MSACChannelUnitProtocol`. Use this object to enqueue logs.
*/
- (id<MSACChannelUnitProtocol>)addChannelUnitWithConfiguration:(MSACChannelUnitConfiguration *)configuration
withIngestion:(nullable id<MSACIngestionProtocol>)ingestion
NS_SWIFT_NAME(addChannelUnit(_:ingestion:));
/**
* Change the base URL (schema + authority + port only) used to communicate with the backend.
*/
@property(nonatomic, strong) NSString *_Nullable logUrl;
/**
* Set the app secret.
*/
@property(nonatomic, strong) NSString *_Nullable appSecret;
/**
* Set the maximum size of the internal storage. This method must be called before App Center is started.
*
* @discussion The default maximum database size is 10485760 bytes (10 MiB).
*
* @param sizeInBytes Maximum size of the internal storage in bytes. This will be rounded up to the nearest multiple of a SQLite page size
* (default is 4096 bytes). Values below 24576 bytes (24 KiB) will be ignored.
* @param completionHandler Callback that is invoked when the database size has been set. The `BOOL` parameter is `YES` if changing the size
* is successful, and `NO` otherwise.
*/
- (void)setMaxStorageSize:(long)sizeInBytes
completionHandler:(nullable void (^)(BOOL))completionHandler NS_SWIFT_NAME(setMaxStorageSize(_:completionHandler:));
/**
* Return a channel unit instance for the given groupId.
*
* @param groupId The group ID for a channel unit.
*
* @return A channel unit instance or `nil`.
*/
- (nullable id<MSACChannelUnitProtocol>)channelUnitForGroupId:(NSString *)groupId;
@end
NS_ASSUME_NONNULL_END
#endif
@@ -1,68 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CHANNEL_PROTOCOL_H
#define MSAC_CHANNEL_PROTOCOL_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACEnable.h>)
#import <AppCenter/MSACEnable.h>
#else
#import "MSACEnable.h"
#endif
NS_ASSUME_NONNULL_BEGIN
@protocol MSACChannelDelegate;
/**
* `MSACChannelProtocol` contains the essential operations of a channel. Channels are broadly responsible for enqueuing logs to be sent to
* the backend and/or stored on disk.
*/
NS_SWIFT_NAME(ChannelProtocol)
@protocol MSACChannelProtocol <NSObject, MSACEnable>
/**
* Add delegate.
*
* @param delegate delegate.
*/
- (void)addDelegate:(id<MSACChannelDelegate>)delegate;
/**
* Remove delegate.
*
* @param delegate delegate.
*/
- (void)removeDelegate:(id<MSACChannelDelegate>)delegate;
/**
* Pause operations, logs will be stored but not sent.
*
* @param identifyingObject Object used to identify the pause request.
*
* @discussion A paused channel doesn't forward logs to the ingestion. The identifying object used to pause the channel can be any unique
* object. The same identifying object must be used to call resume. For simplicity if the caller is the one owning the channel then @c self
* can be used as identifying object.
*
* @see resumeWithIdentifyingObject:
*/
- (void)pauseWithIdentifyingObject:(id<NSObject>)identifyingObject;
/**
* Resume operations, logs can be sent again.
*
* @param identifyingObject Object used to passed to the pause method.
*
* @discussion The channel only resume when all the outstanding identifying objects have been resumed.
*
* @see pauseWithIdentifyingObject:
*/
- (void)resumeWithIdentifyingObject:(id<NSObject>)identifyingObject;
@end
NS_ASSUME_NONNULL_END
#endif
@@ -1,18 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CONSTANTS_FLAGS_H
#define MSAC_CONSTANTS_FLAGS_H
#import <Foundation/Foundation.h>
typedef NS_OPTIONS(NSUInteger, MSACFlags) {
MSACFlagsNone = (0 << 0), // => 00000000
MSACFlagsNormal = (1 << 0), // => 00000001
MSACFlagsCritical = (1 << 1), // => 00000010
MSACFlagsPersistenceNormal DEPRECATED_MSG_ATTRIBUTE("please use MSACFlagsNormal") = MSACFlagsNormal,
MSACFlagsPersistenceCritical DEPRECATED_MSG_ATTRIBUTE("please use MSACFlagsCritical") = MSACFlagsCritical,
MSACFlagsDefault = MSACFlagsNormal
} NS_SWIFT_NAME(Flags);
#endif
@@ -1,170 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
/**
* Log Levels
*/
typedef NS_ENUM(NSUInteger, MSACLogLevel) {
/**
* Logging will be very chatty
*/
MSACLogLevelVerbose = 2,
/**
* Debug information will be logged
*/
MSACLogLevelDebug = 3,
/**
* Information will be logged
*/
MSACLogLevelInfo = 4,
/**
* Errors and warnings will be logged
*/
MSACLogLevelWarning = 5,
/**
* Errors will be logged
*/
MSACLogLevelError = 6,
/**
* Only critical errors will be logged
*/
MSACLogLevelAssert = 7,
/**
* Logging is disabled
*/
MSACLogLevelNone = 99
} NS_SWIFT_NAME(LogLevel);
typedef NSString * (^MSACLogMessageProvider)(void)NS_SWIFT_NAME(LogMessageProvider);
typedef void (^MSACLogHandler)(MSACLogMessageProvider messageProvider, MSACLogLevel logLevel, NSString *tag, const char *file,
const char *function, uint line) NS_SWIFT_NAME(LogHandler);
/**
* Channel priorities, check the kMSACPriorityCount if you add a new value.
* The order matters here! Values NEED to range from low priority to high priority.
*/
typedef NS_ENUM(NSInteger, MSACPriority) { MSACPriorityBackground, MSACPriorityDefault, MSACPriorityHigh } NS_SWIFT_NAME(Priority);
static short const kMSACPriorityCount = MSACPriorityHigh + 1;
/**
* The priority by which the modules are initialized.
* MSACPriorityMax is reserved for only 1 module and this needs to be Crashes.
* Crashes needs to be initialized first to catch crashes in our other SDK Modules (which will hopefully never happen) and to avoid losing
* any log at crash time.
*/
typedef NS_ENUM(NSInteger, MSACInitializationPriority) {
MSACInitializationPriorityDefault = 500,
MSACInitializationPriorityHigh = 750,
MSACInitializationPriorityMax = 999
} NS_SWIFT_NAME(InitializationPriority);
/**
* Enum with the different HTTP status codes.
*/
typedef NS_ENUM(NSInteger, MSACHTTPCodesNo) {
// Invalid
MSACHTTPCodesNo0XXInvalidUnknown = 0,
// Informational
MSACHTTPCodesNo1XXInformationalUnknown = 1,
MSACHTTPCodesNo100Continue = 100,
MSACHTTPCodesNo101SwitchingProtocols = 101,
MSACHTTPCodesNo102Processing = 102,
// Success
MSACHTTPCodesNo2XXSuccessUnknown = 2,
MSACHTTPCodesNo200OK = 200,
MSACHTTPCodesNo201Created = 201,
MSACHTTPCodesNo202Accepted = 202,
MSACHTTPCodesNo203NonAuthoritativeInformation = 203,
MSACHTTPCodesNo204NoContent = 204,
MSACHTTPCodesNo205ResetContent = 205,
MSACHTTPCodesNo206PartialContent = 206,
MSACHTTPCodesNo207MultiStatus = 207,
MSACHTTPCodesNo208AlreadyReported = 208,
MSACHTTPCodesNo209IMUsed = 209,
// Redirection
MSACHTTPCodesNo3XXSuccessUnknown = 3,
MSACHTTPCodesNo300MultipleChoices = 300,
MSACHTTPCodesNo301MovedPermanently = 301,
MSACHTTPCodesNo302Found = 302,
MSACHTTPCodesNo303SeeOther = 303,
MSACHTTPCodesNo304NotModified = 304,
MSACHTTPCodesNo305UseProxy = 305,
MSACHTTPCodesNo306SwitchProxy = 306,
MSACHTTPCodesNo307TemporaryRedirect = 307,
MSACHTTPCodesNo308PermanentRedirect = 308,
// Client error
MSACHTTPCodesNo4XXSuccessUnknown = 4,
MSACHTTPCodesNo400BadRequest = 400,
MSACHTTPCodesNo401Unauthorised = 401,
MSACHTTPCodesNo402PaymentRequired = 402,
MSACHTTPCodesNo403Forbidden = 403,
MSACHTTPCodesNo404NotFound = 404,
MSACHTTPCodesNo405MethodNotAllowed = 405,
MSACHTTPCodesNo406NotAcceptable = 406,
MSACHTTPCodesNo407ProxyAuthenticationRequired = 407,
MSACHTTPCodesNo408RequestTimeout = 408,
MSACHTTPCodesNo409Conflict = 409,
MSACHTTPCodesNo410Gone = 410,
MSACHTTPCodesNo411LengthRequired = 411,
MSACHTTPCodesNo412PreconditionFailed = 412,
MSACHTTPCodesNo413RequestEntityTooLarge = 413,
MSACHTTPCodesNo414RequestURITooLong = 414,
MSACHTTPCodesNo415UnsupportedMediaType = 415,
MSACHTTPCodesNo416RequestedRangeNotSatisfiable = 416,
MSACHTTPCodesNo417ExpectationFailed = 417,
MSACHTTPCodesNo418IamATeapot = 418,
MSACHTTPCodesNo419AuthenticationTimeout = 419,
MSACHTTPCodesNo420MethodFailureSpringFramework = 420,
MSACHTTPCodesNo420EnhanceYourCalmTwitter = 4200,
MSACHTTPCodesNo422UnprocessableEntity = 422,
MSACHTTPCodesNo423Locked = 423,
MSACHTTPCodesNo424FailedDependency = 424,
MSACHTTPCodesNo424MethodFailureWebDaw = 4240,
MSACHTTPCodesNo425UnorderedCollection = 425,
MSACHTTPCodesNo426UpgradeRequired = 426,
MSACHTTPCodesNo428PreconditionRequired = 428,
MSACHTTPCodesNo429TooManyRequests = 429,
MSACHTTPCodesNo431RequestHeaderFieldsTooLarge = 431,
MSACHTTPCodesNo444NoResponseNginx = 444,
MSACHTTPCodesNo449RetryWithMicrosoft = 449,
MSACHTTPCodesNo450BlockedByWindowsParentalControls = 450,
MSACHTTPCodesNo451RedirectMicrosoft = 451,
MSACHTTPCodesNo451UnavailableForLegalReasons = 4510,
MSACHTTPCodesNo494RequestHeaderTooLargeNginx = 494,
MSACHTTPCodesNo495CertErrorNginx = 495,
MSACHTTPCodesNo496NoCertNginx = 496,
MSACHTTPCodesNo497HTTPToHTTPSNginx = 497,
MSACHTTPCodesNo499ClientClosedRequestNginx = 499,
// Server error
MSACHTTPCodesNo5XXSuccessUnknown = 5,
MSACHTTPCodesNo500InternalServerError = 500,
MSACHTTPCodesNo501NotImplemented = 501,
MSACHTTPCodesNo502BadGateway = 502,
MSACHTTPCodesNo503ServiceUnavailable = 503,
MSACHTTPCodesNo504GatewayTimeout = 504,
MSACHTTPCodesNo505HTTPVersionNotSupported = 505,
MSACHTTPCodesNo506VariantAlsoNegotiates = 506,
MSACHTTPCodesNo507InsufficientStorage = 507,
MSACHTTPCodesNo508LoopDetected = 508,
MSACHTTPCodesNo509BandwidthLimitExceeded = 509,
MSACHTTPCodesNo510NotExtended = 510,
MSACHTTPCodesNo511NetworkAuthenticationRequired = 511,
MSACHTTPCodesNo522ConnectionTimedOut = 522,
MSACHTTPCodesNo598NetworkReadTimeoutErrorUnknown = 598,
MSACHTTPCodesNo599NetworkConnectTimeoutErrorUnknown = 599
} NS_SWIFT_NAME(HTTPCodesNo);
@@ -1,71 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CUSTOM_PROPERTIES_H
#define MSAC_CUSTOM_PROPERTIES_H
#import <Foundation/Foundation.h>
/**
* Custom properties builder.
* Collects multiple properties to send in one log.
*/
NS_SWIFT_NAME(CustomProperties)
@interface MSACCustomProperties : NSObject
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setString:(NSString *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setNumber:(NSNumber *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setBool:(BOOL)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setDate:(NSDate *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Clear the property for the specified key.
*
* @param key Key whose mapping is to be cleared.
*
* @return This instance.
*/
- (instancetype)clearPropertyForKey:(NSString *)key NS_SWIFT_NAME(clearProperty(forKey:));
@end
#endif
@@ -1,101 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_DEVICE_H
#define MSAC_DEVICE_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACWrapperSdk.h>)
#import <AppCenter/MSACWrapperSdk.h>
#else
#import "MSACWrapperSdk.h"
#endif
NS_SWIFT_NAME(Device)
@interface MSACDevice : MSACWrapperSdk
/*
* Name of the SDK. Consists of the name of the SDK and the platform, e.g. "appcenter.ios", "appcenter.android"
*/
@property(nonatomic, copy, readonly) NSString *sdkName;
/*
* Version of the SDK in semver format, e.g. "1.2.0" or "0.12.3-alpha.1".
*/
@property(nonatomic, copy, readonly) NSString *sdkVersion;
/*
* Device model (example: iPad2,3).
*/
@property(nonatomic, copy, readonly) NSString *model;
/*
* Device manufacturer (example: HTC).
*/
@property(nonatomic, copy, readonly) NSString *oemName;
/*
* OS name (example: iOS).
*/
@property(nonatomic, copy, readonly) NSString *osName;
/*
* OS version (example: 9.3.0).
*/
@property(nonatomic, copy, readonly) NSString *osVersion;
/*
* OS build code (example: LMY47X). [optional]
*/
@property(nonatomic, copy, readonly) NSString *osBuild;
/*
* API level when applicable like in Android (example: 15). [optional]
*/
@property(nonatomic, copy, readonly) NSNumber *osApiLevel;
/*
* Language code (example: en_US).
*/
@property(nonatomic, copy, readonly) NSString *locale;
/*
* The offset in minutes from UTC for the device time zone, including daylight savings time.
*/
@property(nonatomic, readonly, strong) NSNumber *timeZoneOffset;
/*
* Screen size of the device in pixels (example: 640x480).
*/
@property(nonatomic, copy, readonly) NSString *screenSize;
/*
* Application version name, e.g. 1.1.0
*/
@property(nonatomic, copy, readonly) NSString *appVersion;
/*
* Carrier name (for mobile devices). [optional]
*/
@property(nonatomic, copy, readonly) NSString *carrierName;
/*
* Carrier country code (for mobile devices). [optional]
*/
@property(nonatomic, copy, readonly) NSString *carrierCountry;
/*
* The app's build number, e.g. 42.
*/
@property(nonatomic, copy, readonly) NSString *appBuild;
/*
* The bundle identifier, package identifier, or namespace, depending on what the individual plattforms use, .e.g com.microsoft.example.
* [optional]
*/
@property(nonatomic, copy, readonly) NSString *appNamespace;
@end
#endif
@@ -1,27 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_ENABLE_H
#define MSAC_ENABLE_H
#import <Foundation/Foundation.h>
/**
* Protocol to define an instance that can be enabled/disabled.
*/
NS_SWIFT_NAME(Enable)
@protocol MSACEnable <NSObject>
@required
/**
* Enable/disable this instance and delete data on disabled state.
*
* @param isEnabled A boolean value set to YES to enable the instance or NO to disable it.
* @param deleteData A boolean value set to YES to delete data or NO to keep it.
*/
- (void)setEnabled:(BOOL)isEnabled andDeleteDataOnDisabled:(BOOL)deleteData NS_SWIFT_NAME(setEnabled(_:deleteDataOnDisabled:));
@end
#endif
@@ -1,74 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_LOG_H
#define MSAC_LOG_H
#import <Foundation/Foundation.h>
@class MSACDevice;
NS_SWIFT_NAME(Log)
@protocol MSACLog <NSObject>
/**
* Log type.
*/
@property(nonatomic, copy) NSString *type;
/**
* Log timestamp.
*/
@property(nonatomic, strong) NSDate *timestamp;
/**
* A session identifier is used to correlate logs together. A session is an abstract concept in the API and is not necessarily an analytics
* session, it can be used to only track crashes.
*/
@property(nonatomic, copy) NSString *sid;
/**
* Optional distribution group ID value.
*/
@property(nonatomic, copy) NSString *distributionGroupId;
/**
* Optional user identifier.
*/
@property(nonatomic, copy) NSString *userId;
/**
* Device properties associated to this log.
*/
@property(nonatomic, strong) MSACDevice *device;
/**
* Transient object tag. For example, a log can be tagged with a transmission target. We do this currently to prevent properties being
* applied retroactively to previous logs by comparing their tags.
*/
@property(nonatomic, strong) NSObject *tag;
/**
* Checks if the object's values are valid.
*
* @return YES, if the object is valid.
*/
- (BOOL)isValid;
/**
* Adds a transmission target token that this log should be sent to.
*
* @param token The transmission target token.
*/
- (void)addTransmissionTargetToken:(NSString *)token;
/**
* Gets all transmission target tokens that this log should be sent to.
*
* @returns Collection of transmission target tokens that this log should be sent to.
*/
- (NSSet *)transmissionTargetTokens;
@end
#endif
@@ -1,25 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_LOG_WITH_PROPERTIES_H
#define MSAC_LOG_WITH_PROPERTIES_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACAbstractLog.h>)
#import <AppCenter/MSACAbstractLog.h>
#else
#import "MSACAbstractLog.h"
#endif
NS_SWIFT_NAME(LogWithProperties)
@interface MSACLogWithProperties : MSACAbstractLog
/**
* Additional key/value pair parameters. [optional]
*/
@property(nonatomic, strong) NSDictionary<NSString *, NSString *> *properties;
@end
#endif
@@ -1,54 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#ifndef MSAC_LOGGER
#define MSAC_LOGGER
#if __has_include(<AppCenter/MSACConstants.h>)
#import <AppCenter/MSACConstants.h>
#else
#import "MSACConstants.h"
#endif
#define MSACLog(_level, _tag, _message) \
[MSACLogger logMessage:_message level:_level tag:_tag file:__FILE__ function:__PRETTY_FUNCTION__ line:__LINE__]
#define MSACLogAssert(tag, format, ...) \
MSACLog(MSACLogLevelAssert, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogError(tag, format, ...) \
MSACLog(MSACLogLevelError, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogWarning(tag, format, ...) \
MSACLog(MSACLogLevelWarning, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogInfo(tag, format, ...) \
MSACLog(MSACLogLevelInfo, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogDebug(tag, format, ...) \
MSACLog(MSACLogLevelDebug, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogVerbose(tag, format, ...) \
MSACLog(MSACLogLevelVerbose, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
NS_SWIFT_NAME(Logger)
@interface MSACLogger : NSObject
+ (void)logMessage:(MSACLogMessageProvider)messageProvider
level:(MSACLogLevel)loglevel
tag:(NSString *)tag
file:(const char *)file
function:(const char *)function
line:(uint)line;
@end
#endif
@@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#ifndef SERIALIZABLE_OBJECT_H
#define SERIALIZABLE_OBJECT_H
@protocol MSACSerializableObject <NSCoding>
/**
* Serialize this object to a dictionary.
*
* @return A dictionary representing this object.
*/
- (NSMutableDictionary *)serializeToDictionary;
@end
#endif
@@ -1,23 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_SERVICE_H
#define MSAC_SERVICE_H
#import <Foundation/Foundation.h>
/**
* Protocol declaring service logic.
*/
NS_SWIFT_NAME(Service)
@protocol MSACService <NSObject>
/**
* Indicates whether this service is enabled.
* The state is persisted in the device's storage across application launches.
*/
@property(class, nonatomic, getter=isEnabled, setter=setEnabled:) BOOL enabled NS_SWIFT_NAME(enabled);
@end
#endif
@@ -1,58 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_SERVICE_ABSTRACT_H
#define MSAC_SERVICE_ABSTRACT_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACService.h>)
#import <AppCenter/MSACService.h>
#else
#import "MSACService.h"
#endif
@protocol MSACChannelGroupProtocol;
/**
* Abstraction of services common logic.
* This class is intended to be subclassed only not instantiated directly.
*/
NS_SWIFT_NAME(ServiceAbstract)
@interface MSACServiceAbstract : NSObject <MSACService>
/**
* The flag indicates whether the service is started from application or not.
*/
@property(nonatomic, assign) BOOL startedFromApplication;
/**
* Start this service with a channel group. Also sets the flag that indicates that a service has been started.
*
* @param channelGroup channel group used to persist and send logs.
* @param appSecret app secret for the SDK.
* @param token default transmission target token for this service.
* @param fromApplication indicates whether the service started from an application or not.
*/
- (void)startWithChannelGroup:(id<MSACChannelGroupProtocol>)channelGroup
appSecret:(NSString *)appSecret
transmissionTargetToken:(NSString *)token
fromApplication:(BOOL)fromApplication;
/**
* Update configuration when the service requires to start again. This method should only be called if the service is started from libraries
* and then is being started from an application.
*
* @param appSecret app secret for the SDK.
* @param token default transmission target token for this service.
*/
- (void)updateConfigurationWithAppSecret:(NSString *)appSecret transmissionTargetToken:(NSString *)token;
/**
* The flag indicate whether the service needs the application secret or not.
*/
@property(atomic, readonly) BOOL isAppSecretRequired;
@end
#endif
@@ -1,21 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACConstants.h>)
#import <AppCenter/MSACConstants.h>
#else
#import "MSACConstants.h"
#endif
/**
* This is a utility for producing App Center style log messages. It is only intended for use by App Center services and wrapper SDKs of App
* Center.
*/
NS_SWIFT_NAME(WrapperLogger)
@interface MSACWrapperLogger : NSObject
+ (void)MSACWrapperLog:(MSACLogMessageProvider)message tag:(NSString *)tag level:(MSACLogLevel)level;
@end
@@ -1,60 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_WRAPPER_SDK_H
#define MSAC_WRAPPER_SDK_H
#import <Foundation/Foundation.h>
NS_SWIFT_NAME(WrapperSdk)
@interface MSACWrapperSdk : NSObject
/*
* Version of the wrapper SDK. When the SDK is embedding another base SDK (for example Xamarin.Android wraps Android), the Xamarin specific
* version is populated into this field while sdkVersion refers to the original Android SDK. [optional]
*/
@property(nonatomic, copy, readonly) NSString *wrapperSdkVersion;
/*
* Name of the wrapper SDK (examples: Xamarin, Cordova). [optional]
*/
@property(nonatomic, copy, readonly) NSString *wrapperSdkName;
/*
* Version of the wrapper technology framework (Xamarin runtime version or ReactNative or Cordova etc...). [optional]
*/
@property(nonatomic, copy, readonly) NSString *wrapperRuntimeVersion;
/*
* Label that is used to identify application code 'version' released via Live Update beacon running on device.
*/
@property(nonatomic, copy, readonly) NSString *liveUpdateReleaseLabel;
/*
* Identifier of environment that current application release belongs to, deployment key then maps to environment like Production, Staging.
*/
@property(nonatomic, copy, readonly) NSString *liveUpdateDeploymentKey;
/*
* Hash of all files (ReactNative or Cordova) deployed to device via LiveUpdate beacon. Helps identify the Release version on device or need
* to download updates in future
*/
@property(nonatomic, copy, readonly) NSString *liveUpdatePackageHash;
- (instancetype)initWithWrapperSdkVersion:(NSString *)wrapperSdkVersion
wrapperSdkName:(NSString *)wrapperSdkName
wrapperRuntimeVersion:(NSString *)wrapperRuntimeVersion
liveUpdateReleaseLabel:(NSString *)liveUpdateReleaseLabel
liveUpdateDeploymentKey:(NSString *)liveUpdateDeploymentKey
liveUpdatePackageHash:(NSString *)liveUpdatePackageHash;
/**
* Checks if the object's values are valid.
*
* @return YES, if the object is valid.
*/
- (BOOL)isValid;
@end
#endif
@@ -1,13 +0,0 @@
framework module AppCenter {
umbrella header "AppCenter.h"
export *
module * { export * }
link framework "Foundation"
link framework "CoreTelephony"
link framework "SystemConfiguration"
link framework "UIKit"
link "sqlite3"
link "z"
}
@@ -1,114 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#import "MSACConstants+Flags.h"
@protocol MSACChannelUnitProtocol;
@protocol MSACChannelGroupProtocol;
@protocol MSACChannelProtocol;
@protocol MSACLog;
NS_ASSUME_NONNULL_BEGIN
@protocol MSACChannelDelegate <NSObject>
@optional
/**
* A callback that is called when a channel unit is added to the channel group.
*
* @param channelGroup The channel group.
* @param channel The newly added channel.
*/
- (void)channelGroup:(id<MSACChannelGroupProtocol>)channelGroup didAddChannelUnit:(id<MSACChannelUnitProtocol>)channel;
/**
* A callback that is called when a log is just enqueued. Delegates may want to prepare the log a little more before further processing.
*
* @param log The log to prepare.
*/
- (void)channel:(id<MSACChannelProtocol>)channel prepareLog:(id<MSACLog>)log;
/**
* A callback that is called after a log is definitely prepared.
*
* @param log The log.
* @param internalId An internal Id to keep track of logs.
* @param flags Options for the log.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didPrepareLog:(id<MSACLog>)log internalId:(NSString *)internalId flags:(MSACFlags)flags;
/**
* A callback that is called after a log completed the enqueueing process whether it was successful or not.
*
* @param log The log.
* @param internalId An internal Id to keep track of logs.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didCompleteEnqueueingLog:(id<MSACLog>)log internalId:(NSString *)internalId;
/**
* Callback method that will be called before each log will be send to the server.
*
* @param channel The channel object.
* @param log The log to be sent.
*/
- (void)channel:(id<MSACChannelProtocol>)channel willSendLog:(id<MSACLog>)log;
/**
* Callback method that will be called in case the SDK was able to send a log.
*
* @param channel The channel object.
* @param log The log to be sent.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didSucceedSendingLog:(id<MSACLog>)log;
/**
* Callback method that will be called in case the SDK was unable to send a log.
*
* @param channel The channel object.
* @param log The log to be sent.
* @param error The error that occured.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didFailSendingLog:(id<MSACLog>)log withError:(nullable NSError *)error;
/**
* A callback that is called when setEnabled has been invoked.
*
* @param channel The channel.
* @param isEnabled The boolean that indicates enabled.
* @param deletedData The boolean that indicates deleting data on disabled.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didSetEnabled:(BOOL)isEnabled andDeleteDataOnDisabled:(BOOL)deletedData;
/**
* A callback that is called when pause has been invoked.
*
* @param channel The channel.
* @param identifyingObject The identifying object used to pause the channel.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didPauseWithIdentifyingObject:(id<NSObject>)identifyingObject;
/**
* A callback that is called when resume has been invoked.
*
* @param channel The channel.
* @param identifyingObject The identifying object used to resume the channel.
*/
- (void)channel:(id<MSACChannelProtocol>)channel didResumeWithIdentifyingObject:(id<NSObject>)identifyingObject;
/**
* Callback method that will determine if a log should be filtered out from the usual processing pipeline. If any delegate returns true, the
* log is filtered.
*
* @param channelUnit The channel unit that is going to send the log.
* @param log The log to be filtered or not.
*
* @return `true` if the log should be filtered out.
*/
- (BOOL)channelUnit:(id<MSACChannelUnitProtocol>)channelUnit shouldFilterLog:(id<MSACLog>)log;
@end
NS_ASSUME_NONNULL_END
@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19H1323</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>AppCenter</string>
<key>CFBundleIdentifier</key>
<string>com.microsoft.appcenter</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>AppCenter</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11C505</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>19B90</string>
<key>DTSDKName</key>
<string>macosx10.15</string>
<key>DTXcode</key>
<string>1130</string>
<key>DTXcodeBuild</key>
<string>11C505</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<key>UIDeviceFamily</key>
<array>
<integer>2</integer>
</array>
</dict>
</plist>
@@ -1 +0,0 @@
Versions/Current/AppCenter
@@ -1 +0,0 @@
Versions/Current/Headers
@@ -1 +0,0 @@
Versions/Current/Modules
@@ -1 +0,0 @@
Versions/Current/PrivateHeaders
@@ -1 +0,0 @@
Versions/Current/Resources
@@ -1,44 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACAppCenter.h>)
#import <AppCenter/MSACAbstractLog.h>
#import <AppCenter/MSACAppCenter.h>
#import <AppCenter/MSACAppCenterErrors.h>
#import <AppCenter/MSACChannelGroupProtocol.h>
#import <AppCenter/MSACChannelProtocol.h>
#import <AppCenter/MSACConstants+Flags.h>
#import <AppCenter/MSACConstants.h>
#import <AppCenter/MSACCustomProperties.h>
#import <AppCenter/MSACDevice.h>
#import <AppCenter/MSACEnable.h>
#import <AppCenter/MSACLog.h>
#import <AppCenter/MSACLogWithProperties.h>
#import <AppCenter/MSACLogger.h>
#import <AppCenter/MSACSerializableObject.h>
#import <AppCenter/MSACService.h>
#import <AppCenter/MSACServiceAbstract.h>
#import <AppCenter/MSACWrapperLogger.h>
#import <AppCenter/MSACWrapperSdk.h>
#else
#import "MSACAbstractLog.h"
#import "MSACAppCenter.h"
#import "MSACAppCenterErrors.h"
#import "MSACChannelGroupProtocol.h"
#import "MSACChannelProtocol.h"
#import "MSACConstants+Flags.h"
#import "MSACConstants.h"
#import "MSACCustomProperties.h"
#import "MSACDevice.h"
#import "MSACEnable.h"
#import "MSACLog.h"
#import "MSACLogWithProperties.h"
#import "MSACLogger.h"
#import "MSACSerializableObject.h"
#import "MSACService.h"
#import "MSACServiceAbstract.h"
#import "MSACWrapperLogger.h"
#import "MSACWrapperSdk.h"
#endif
@@ -1,203 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#ifndef MSAC_APP_CENTER
#define MSAC_APP_CENTER
#if __has_include(<AppCenter/MSACConstants.h>)
#import <AppCenter/MSACConstants.h>
#else
#import "MSACConstants.h"
#endif
@class MSACWrapperSdk;
#if !TARGET_OS_TV
@class MSACCustomProperties;
#endif
NS_SWIFT_NAME(AppCenter)
@interface MSACAppCenter : NSObject
/**
* Returns the singleton instance of MSACAppCenter.
*/
+ (instancetype)sharedInstance;
/**
* Configure the SDK with an application secret.
*
* @param appSecret A unique and secret key used to identify the application.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)configureWithAppSecret:(NSString *)appSecret NS_SWIFT_NAME(configure(withAppSecret:));
/**
* Configure the SDK.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)configure;
/**
* Configure the SDK with an application secret and an array of services to start.
*
* @param appSecret A unique and secret key used to identify the application.
* @param services Array of services to start.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)start:(NSString *)appSecret withServices:(NSArray<Class> *)services NS_SWIFT_NAME(start(withAppSecret:services:));
/**
* Start the SDK with an array of services.
*
* @param services Array of services to start.
*
* @discussion This may be called only once per application process lifetime.
*/
+ (void)startWithServices:(NSArray<Class> *)services NS_SWIFT_NAME(start(services:));
/**
* Start a service.
*
* @param service A service to start.
*
* @discussion This may be called only once per service per application process lifetime.
*/
+ (void)startService:(Class)service;
/**
* Configure the SDK with an array of services to start from a library. This will not start the service at application level, it will enable
* the service only for the library.
*
* @param services Array of services to start.
*/
+ (void)startFromLibraryWithServices:(NSArray<Class> *)services NS_SWIFT_NAME(startFromLibrary(services:));
/**
* The flag indicates whether the SDK has already been configured or not.
*/
@property(class, atomic, readonly, getter=isConfigured) BOOL configured;
/**
* The flag indicates whether app is running in App Center Test Cloud.
*/
@property(class, atomic, readonly, getter=isRunningInAppCenterTestCloud) BOOL runningInAppCenterTestCloud;
/**
* The flag indicates whether or not the SDK was enabled as a whole
*
* The state is persisted in the device's storage across application launches.
*/
@property(class, nonatomic, getter=isEnabled, setter=setEnabled:) BOOL enabled NS_SWIFT_NAME(enabled);
/**
* Flag indicating whether SDK can send network requests.
*
* The state is persisted in the device's storage across application launches.
*/
@property(class, nonatomic, getter=isNetworkRequestsAllowed, setter=setNetworkRequestsAllowed:)
BOOL networkRequestsAllowed NS_SWIFT_NAME(networkRequestsAllowed);
/**
* The SDK's log level.
*/
@property(class, nonatomic) MSACLogLevel logLevel;
/**
* Base URL to use for backend communication.
*/
@property(class, nonatomic, strong) NSString *logUrl;
/**
* Set log handler.
*/
@property(class, nonatomic) MSACLogHandler logHandler;
/**
* Set wrapper SDK information to use when building device properties. This is intended in case you are building a SDK that uses the App
* Center SDK under the hood, e.g. our Xamarin SDK or ReactNative SDk.
*/
@property(class, nonatomic, strong) MSACWrapperSdk *wrapperSdk;
#if !TARGET_OS_TV
/**
* Set the custom properties.
*
* @param customProperties Custom properties object.
*/
+ (void)setCustomProperties:(MSACCustomProperties *)customProperties;
#endif
/**
* Check whether the application delegate forwarder is enabled or not.
*
* @discussion The application delegate forwarder forwards messages that target your application delegate methods via swizzling to the SDK.
* It simplifies the SDK integration but may not be suitable to any situations. For
* instance it should be disabled if you or one of your third party SDK is doing message forwarding on the application delegate. Message
* forwarding usually implies the implementation of @see NSObject#forwardingTargetForSelector: or @see NSObject#forwardInvocation: methods.
* To disable the application delegate forwarder just add the `AppCenterAppDelegateForwarderEnabled` tag to your Info .plist file and set it
* to `0`. Then you will have to forward any application delegate needed by the SDK manually.
*/
@property(class, readonly, nonatomic, getter=isAppDelegateForwarderEnabled) BOOL appDelegateForwarderEnabled;
/**
* Unique installation identifier.
*
*/
@property(class, readonly, nonatomic) NSUUID *installId;
/**
* Detect if a debugger is attached to the app process. This is only invoked once on app startup and can not detect
* if the debugger is being attached during runtime!
*
*/
@property(class, readonly, nonatomic, getter=isDebuggerAttached) BOOL debuggerAttached;
/**
* Current version of AppCenter SDK.
*
*/
@property(class, readonly, nonatomic) NSString *sdkVersion;
/**
* Set the maximum size of the internal storage. This method must be called before App Center is started. This method is only intended for
* applications.
*
* @param sizeInBytes Maximum size of the internal storage in bytes. This will be rounded up to the nearest multiple of a SQLite page size
* (default is 4096 bytes). Values below 20,480 bytes (20 KiB) will be ignored.
*
* @param completionHandler Callback that is invoked when the database size has been set. The `BOOL` parameter is `YES` if changing the size
* is successful, and `NO` otherwise. This parameter can be null.
*
* @discussion This only sets the maximum size of the database, but App Center modules might store additional data.
* The value passed to this method is not persisted on disk. The default maximum database size is 10485760 bytes (10 MiB).
*/
+ (void)setMaxStorageSize:(long)sizeInBytes completionHandler:(void (^)(BOOL))completionHandler;
/**
* Set the user identifier.
*
* @discussion Set the user identifier for logs sent for the default target token when the secret passed in @c
* MSACAppCenter:start:withServices: contains "target={targetToken}".
*
* For App Center backend the user identifier maximum length is 256 characters.
*
* AppCenter must be configured or started before this API can be used.
*/
@property(class, nonatomic, strong) NSString *userId;
/**
* Set country code to use when building device properties.
*
* @see https://www.iso.org/obp/ui/#search for more information.
*/
@property(class, nonatomic, strong) NSString *countryCode;
@end
#endif
@@ -1,41 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_APP_CENTER_ERRORS_H
#define MSAC_APP_CENTER_ERRORS_H
#import <Foundation/Foundation.h>
#define MSAC_APP_CENTER_BASE_DOMAIN @"com.Microsoft.AppCenter."
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Domain
static NSString *const kMSACACErrorDomain = MSAC_APP_CENTER_BASE_DOMAIN @"ErrorDomain";
#pragma mark - General
// Error codes.
NS_ENUM(NSInteger){MSACACLogInvalidContainerErrorCode = 1, MSACACCanceledErrorCode = 2, MSACACDisabledErrorCode = 3};
// Error descriptions.
static NSString const *kMSACACLogInvalidContainerErrorDesc = @"Invalid log container.";
static NSString const *kMSACACCanceledErrorDesc = @"The operation was canceled.";
static NSString const *kMSACACDisabledErrorDesc = @"The service is disabled.";
#pragma mark - Connection
// Error codes.
NS_ENUM(NSInteger){MSACACConnectionPausedErrorCode = 100, MSACACConnectionHttpErrorCode = 101};
// Error descriptions.
static NSString const *kMSACACConnectionHttpErrorDesc = @"An HTTP error occured.";
static NSString const *kMSACACConnectionPausedErrorDesc = @"Canceled, connection paused with log deletion.";
// Error user info keys.
static NSString const *kMSACACConnectionHttpCodeErrorKey = @"MSConnectionHttpCode";
NS_ASSUME_NONNULL_END
#endif
@@ -1,87 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CHANNEL_GROUP_PROTOCOL_H
#define MSAC_CHANNEL_GROUP_PROTOCOL_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACChannelProtocol.h>)
#import <AppCenter/MSACChannelProtocol.h>
#else
#import "MSACChannelProtocol.h"
#endif
NS_ASSUME_NONNULL_BEGIN
@class MSACChannelUnitConfiguration;
@protocol MSACIngestionProtocol;
@protocol MSACChannelUnitProtocol;
/**
* `MSACChannelGroupProtocol` represents a kind of channel that contains constituent MSACChannelUnit objects. When an operation from the
* `MSACChannelProtocol` is performed on the group, that operation should be propagated to its constituent MSACChannelUnit objects.
*/
NS_SWIFT_NAME(ChannelGroupProtocol)
@protocol MSACChannelGroupProtocol <MSACChannelProtocol>
/**
* Initialize a channel unit with the given configuration.
*
* @param configuration channel configuration.
*
* @return The added `MSACChannelUnitProtocol`. Use this object to enqueue logs.
*/
- (id<MSACChannelUnitProtocol>)addChannelUnitWithConfiguration:(MSACChannelUnitConfiguration *)configuration
NS_SWIFT_NAME(addChannelUnit(withConfiguration:));
/**
* Initialize a channel unit with the given configuration.
*
* @param configuration channel configuration.
* @param ingestion The alternative ingestion object
*
* @return The added `MSACChannelUnitProtocol`. Use this object to enqueue logs.
*/
- (id<MSACChannelUnitProtocol>)addChannelUnitWithConfiguration:(MSACChannelUnitConfiguration *)configuration
withIngestion:(nullable id<MSACIngestionProtocol>)ingestion
NS_SWIFT_NAME(addChannelUnit(_:ingestion:));
/**
* Change the base URL (schema + authority + port only) used to communicate with the backend.
*/
@property(nonatomic, strong) NSString *_Nullable logUrl;
/**
* Set the app secret.
*/
@property(nonatomic, strong) NSString *_Nullable appSecret;
/**
* Set the maximum size of the internal storage. This method must be called before App Center is started.
*
* @discussion The default maximum database size is 10485760 bytes (10 MiB).
*
* @param sizeInBytes Maximum size of the internal storage in bytes. This will be rounded up to the nearest multiple of a SQLite page size
* (default is 4096 bytes). Values below 24576 bytes (24 KiB) will be ignored.
* @param completionHandler Callback that is invoked when the database size has been set. The `BOOL` parameter is `YES` if changing the size
* is successful, and `NO` otherwise.
*/
- (void)setMaxStorageSize:(long)sizeInBytes
completionHandler:(nullable void (^)(BOOL))completionHandler NS_SWIFT_NAME(setMaxStorageSize(_:completionHandler:));
/**
* Return a channel unit instance for the given groupId.
*
* @param groupId The group ID for a channel unit.
*
* @return A channel unit instance or `nil`.
*/
- (nullable id<MSACChannelUnitProtocol>)channelUnitForGroupId:(NSString *)groupId;
@end
NS_ASSUME_NONNULL_END
#endif
@@ -1,68 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CHANNEL_PROTOCOL_H
#define MSAC_CHANNEL_PROTOCOL_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACEnable.h>)
#import <AppCenter/MSACEnable.h>
#else
#import "MSACEnable.h"
#endif
NS_ASSUME_NONNULL_BEGIN
@protocol MSACChannelDelegate;
/**
* `MSACChannelProtocol` contains the essential operations of a channel. Channels are broadly responsible for enqueuing logs to be sent to
* the backend and/or stored on disk.
*/
NS_SWIFT_NAME(ChannelProtocol)
@protocol MSACChannelProtocol <NSObject, MSACEnable>
/**
* Add delegate.
*
* @param delegate delegate.
*/
- (void)addDelegate:(id<MSACChannelDelegate>)delegate;
/**
* Remove delegate.
*
* @param delegate delegate.
*/
- (void)removeDelegate:(id<MSACChannelDelegate>)delegate;
/**
* Pause operations, logs will be stored but not sent.
*
* @param identifyingObject Object used to identify the pause request.
*
* @discussion A paused channel doesn't forward logs to the ingestion. The identifying object used to pause the channel can be any unique
* object. The same identifying object must be used to call resume. For simplicity if the caller is the one owning the channel then @c self
* can be used as identifying object.
*
* @see resumeWithIdentifyingObject:
*/
- (void)pauseWithIdentifyingObject:(id<NSObject>)identifyingObject;
/**
* Resume operations, logs can be sent again.
*
* @param identifyingObject Object used to passed to the pause method.
*
* @discussion The channel only resume when all the outstanding identifying objects have been resumed.
*
* @see pauseWithIdentifyingObject:
*/
- (void)resumeWithIdentifyingObject:(id<NSObject>)identifyingObject;
@end
NS_ASSUME_NONNULL_END
#endif
@@ -1,18 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CONSTANTS_FLAGS_H
#define MSAC_CONSTANTS_FLAGS_H
#import <Foundation/Foundation.h>
typedef NS_OPTIONS(NSUInteger, MSACFlags) {
MSACFlagsNone = (0 << 0), // => 00000000
MSACFlagsNormal = (1 << 0), // => 00000001
MSACFlagsCritical = (1 << 1), // => 00000010
MSACFlagsPersistenceNormal DEPRECATED_MSG_ATTRIBUTE("please use MSACFlagsNormal") = MSACFlagsNormal,
MSACFlagsPersistenceCritical DEPRECATED_MSG_ATTRIBUTE("please use MSACFlagsCritical") = MSACFlagsCritical,
MSACFlagsDefault = MSACFlagsNormal
} NS_SWIFT_NAME(Flags);
#endif
@@ -1,170 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
/**
* Log Levels
*/
typedef NS_ENUM(NSUInteger, MSACLogLevel) {
/**
* Logging will be very chatty
*/
MSACLogLevelVerbose = 2,
/**
* Debug information will be logged
*/
MSACLogLevelDebug = 3,
/**
* Information will be logged
*/
MSACLogLevelInfo = 4,
/**
* Errors and warnings will be logged
*/
MSACLogLevelWarning = 5,
/**
* Errors will be logged
*/
MSACLogLevelError = 6,
/**
* Only critical errors will be logged
*/
MSACLogLevelAssert = 7,
/**
* Logging is disabled
*/
MSACLogLevelNone = 99
} NS_SWIFT_NAME(LogLevel);
typedef NSString * (^MSACLogMessageProvider)(void)NS_SWIFT_NAME(LogMessageProvider);
typedef void (^MSACLogHandler)(MSACLogMessageProvider messageProvider, MSACLogLevel logLevel, NSString *tag, const char *file,
const char *function, uint line) NS_SWIFT_NAME(LogHandler);
/**
* Channel priorities, check the kMSACPriorityCount if you add a new value.
* The order matters here! Values NEED to range from low priority to high priority.
*/
typedef NS_ENUM(NSInteger, MSACPriority) { MSACPriorityBackground, MSACPriorityDefault, MSACPriorityHigh } NS_SWIFT_NAME(Priority);
static short const kMSACPriorityCount = MSACPriorityHigh + 1;
/**
* The priority by which the modules are initialized.
* MSACPriorityMax is reserved for only 1 module and this needs to be Crashes.
* Crashes needs to be initialized first to catch crashes in our other SDK Modules (which will hopefully never happen) and to avoid losing
* any log at crash time.
*/
typedef NS_ENUM(NSInteger, MSACInitializationPriority) {
MSACInitializationPriorityDefault = 500,
MSACInitializationPriorityHigh = 750,
MSACInitializationPriorityMax = 999
} NS_SWIFT_NAME(InitializationPriority);
/**
* Enum with the different HTTP status codes.
*/
typedef NS_ENUM(NSInteger, MSACHTTPCodesNo) {
// Invalid
MSACHTTPCodesNo0XXInvalidUnknown = 0,
// Informational
MSACHTTPCodesNo1XXInformationalUnknown = 1,
MSACHTTPCodesNo100Continue = 100,
MSACHTTPCodesNo101SwitchingProtocols = 101,
MSACHTTPCodesNo102Processing = 102,
// Success
MSACHTTPCodesNo2XXSuccessUnknown = 2,
MSACHTTPCodesNo200OK = 200,
MSACHTTPCodesNo201Created = 201,
MSACHTTPCodesNo202Accepted = 202,
MSACHTTPCodesNo203NonAuthoritativeInformation = 203,
MSACHTTPCodesNo204NoContent = 204,
MSACHTTPCodesNo205ResetContent = 205,
MSACHTTPCodesNo206PartialContent = 206,
MSACHTTPCodesNo207MultiStatus = 207,
MSACHTTPCodesNo208AlreadyReported = 208,
MSACHTTPCodesNo209IMUsed = 209,
// Redirection
MSACHTTPCodesNo3XXSuccessUnknown = 3,
MSACHTTPCodesNo300MultipleChoices = 300,
MSACHTTPCodesNo301MovedPermanently = 301,
MSACHTTPCodesNo302Found = 302,
MSACHTTPCodesNo303SeeOther = 303,
MSACHTTPCodesNo304NotModified = 304,
MSACHTTPCodesNo305UseProxy = 305,
MSACHTTPCodesNo306SwitchProxy = 306,
MSACHTTPCodesNo307TemporaryRedirect = 307,
MSACHTTPCodesNo308PermanentRedirect = 308,
// Client error
MSACHTTPCodesNo4XXSuccessUnknown = 4,
MSACHTTPCodesNo400BadRequest = 400,
MSACHTTPCodesNo401Unauthorised = 401,
MSACHTTPCodesNo402PaymentRequired = 402,
MSACHTTPCodesNo403Forbidden = 403,
MSACHTTPCodesNo404NotFound = 404,
MSACHTTPCodesNo405MethodNotAllowed = 405,
MSACHTTPCodesNo406NotAcceptable = 406,
MSACHTTPCodesNo407ProxyAuthenticationRequired = 407,
MSACHTTPCodesNo408RequestTimeout = 408,
MSACHTTPCodesNo409Conflict = 409,
MSACHTTPCodesNo410Gone = 410,
MSACHTTPCodesNo411LengthRequired = 411,
MSACHTTPCodesNo412PreconditionFailed = 412,
MSACHTTPCodesNo413RequestEntityTooLarge = 413,
MSACHTTPCodesNo414RequestURITooLong = 414,
MSACHTTPCodesNo415UnsupportedMediaType = 415,
MSACHTTPCodesNo416RequestedRangeNotSatisfiable = 416,
MSACHTTPCodesNo417ExpectationFailed = 417,
MSACHTTPCodesNo418IamATeapot = 418,
MSACHTTPCodesNo419AuthenticationTimeout = 419,
MSACHTTPCodesNo420MethodFailureSpringFramework = 420,
MSACHTTPCodesNo420EnhanceYourCalmTwitter = 4200,
MSACHTTPCodesNo422UnprocessableEntity = 422,
MSACHTTPCodesNo423Locked = 423,
MSACHTTPCodesNo424FailedDependency = 424,
MSACHTTPCodesNo424MethodFailureWebDaw = 4240,
MSACHTTPCodesNo425UnorderedCollection = 425,
MSACHTTPCodesNo426UpgradeRequired = 426,
MSACHTTPCodesNo428PreconditionRequired = 428,
MSACHTTPCodesNo429TooManyRequests = 429,
MSACHTTPCodesNo431RequestHeaderFieldsTooLarge = 431,
MSACHTTPCodesNo444NoResponseNginx = 444,
MSACHTTPCodesNo449RetryWithMicrosoft = 449,
MSACHTTPCodesNo450BlockedByWindowsParentalControls = 450,
MSACHTTPCodesNo451RedirectMicrosoft = 451,
MSACHTTPCodesNo451UnavailableForLegalReasons = 4510,
MSACHTTPCodesNo494RequestHeaderTooLargeNginx = 494,
MSACHTTPCodesNo495CertErrorNginx = 495,
MSACHTTPCodesNo496NoCertNginx = 496,
MSACHTTPCodesNo497HTTPToHTTPSNginx = 497,
MSACHTTPCodesNo499ClientClosedRequestNginx = 499,
// Server error
MSACHTTPCodesNo5XXSuccessUnknown = 5,
MSACHTTPCodesNo500InternalServerError = 500,
MSACHTTPCodesNo501NotImplemented = 501,
MSACHTTPCodesNo502BadGateway = 502,
MSACHTTPCodesNo503ServiceUnavailable = 503,
MSACHTTPCodesNo504GatewayTimeout = 504,
MSACHTTPCodesNo505HTTPVersionNotSupported = 505,
MSACHTTPCodesNo506VariantAlsoNegotiates = 506,
MSACHTTPCodesNo507InsufficientStorage = 507,
MSACHTTPCodesNo508LoopDetected = 508,
MSACHTTPCodesNo509BandwidthLimitExceeded = 509,
MSACHTTPCodesNo510NotExtended = 510,
MSACHTTPCodesNo511NetworkAuthenticationRequired = 511,
MSACHTTPCodesNo522ConnectionTimedOut = 522,
MSACHTTPCodesNo598NetworkReadTimeoutErrorUnknown = 598,
MSACHTTPCodesNo599NetworkConnectTimeoutErrorUnknown = 599
} NS_SWIFT_NAME(HTTPCodesNo);
@@ -1,71 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_CUSTOM_PROPERTIES_H
#define MSAC_CUSTOM_PROPERTIES_H
#import <Foundation/Foundation.h>
/**
* Custom properties builder.
* Collects multiple properties to send in one log.
*/
NS_SWIFT_NAME(CustomProperties)
@interface MSACCustomProperties : NSObject
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setString:(NSString *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setNumber:(NSNumber *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setBool:(BOOL)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Set the specified property value with the specified key.
* If the properties previously contained a property for the key, the old value is replaced.
*
* @param key Key with which the specified value is to be set.
* @param value Value to be set with the specified key.
*
* @return This instance.
*/
- (instancetype)setDate:(NSDate *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
/**
* Clear the property for the specified key.
*
* @param key Key whose mapping is to be cleared.
*
* @return This instance.
*/
- (instancetype)clearPropertyForKey:(NSString *)key NS_SWIFT_NAME(clearProperty(forKey:));
@end
#endif
@@ -1,101 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_DEVICE_H
#define MSAC_DEVICE_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACWrapperSdk.h>)
#import <AppCenter/MSACWrapperSdk.h>
#else
#import "MSACWrapperSdk.h"
#endif
NS_SWIFT_NAME(Device)
@interface MSACDevice : MSACWrapperSdk
/*
* Name of the SDK. Consists of the name of the SDK and the platform, e.g. "appcenter.ios", "appcenter.android"
*/
@property(nonatomic, copy, readonly) NSString *sdkName;
/*
* Version of the SDK in semver format, e.g. "1.2.0" or "0.12.3-alpha.1".
*/
@property(nonatomic, copy, readonly) NSString *sdkVersion;
/*
* Device model (example: iPad2,3).
*/
@property(nonatomic, copy, readonly) NSString *model;
/*
* Device manufacturer (example: HTC).
*/
@property(nonatomic, copy, readonly) NSString *oemName;
/*
* OS name (example: iOS).
*/
@property(nonatomic, copy, readonly) NSString *osName;
/*
* OS version (example: 9.3.0).
*/
@property(nonatomic, copy, readonly) NSString *osVersion;
/*
* OS build code (example: LMY47X). [optional]
*/
@property(nonatomic, copy, readonly) NSString *osBuild;
/*
* API level when applicable like in Android (example: 15). [optional]
*/
@property(nonatomic, copy, readonly) NSNumber *osApiLevel;
/*
* Language code (example: en_US).
*/
@property(nonatomic, copy, readonly) NSString *locale;
/*
* The offset in minutes from UTC for the device time zone, including daylight savings time.
*/
@property(nonatomic, readonly, strong) NSNumber *timeZoneOffset;
/*
* Screen size of the device in pixels (example: 640x480).
*/
@property(nonatomic, copy, readonly) NSString *screenSize;
/*
* Application version name, e.g. 1.1.0
*/
@property(nonatomic, copy, readonly) NSString *appVersion;
/*
* Carrier name (for mobile devices). [optional]
*/
@property(nonatomic, copy, readonly) NSString *carrierName;
/*
* Carrier country code (for mobile devices). [optional]
*/
@property(nonatomic, copy, readonly) NSString *carrierCountry;
/*
* The app's build number, e.g. 42.
*/
@property(nonatomic, copy, readonly) NSString *appBuild;
/*
* The bundle identifier, package identifier, or namespace, depending on what the individual plattforms use, .e.g com.microsoft.example.
* [optional]
*/
@property(nonatomic, copy, readonly) NSString *appNamespace;
@end
#endif
@@ -1,27 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_ENABLE_H
#define MSAC_ENABLE_H
#import <Foundation/Foundation.h>
/**
* Protocol to define an instance that can be enabled/disabled.
*/
NS_SWIFT_NAME(Enable)
@protocol MSACEnable <NSObject>
@required
/**
* Enable/disable this instance and delete data on disabled state.
*
* @param isEnabled A boolean value set to YES to enable the instance or NO to disable it.
* @param deleteData A boolean value set to YES to delete data or NO to keep it.
*/
- (void)setEnabled:(BOOL)isEnabled andDeleteDataOnDisabled:(BOOL)deleteData NS_SWIFT_NAME(setEnabled(_:deleteDataOnDisabled:));
@end
#endif
@@ -1,74 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_LOG_H
#define MSAC_LOG_H
#import <Foundation/Foundation.h>
@class MSACDevice;
NS_SWIFT_NAME(Log)
@protocol MSACLog <NSObject>
/**
* Log type.
*/
@property(nonatomic, copy) NSString *type;
/**
* Log timestamp.
*/
@property(nonatomic, strong) NSDate *timestamp;
/**
* A session identifier is used to correlate logs together. A session is an abstract concept in the API and is not necessarily an analytics
* session, it can be used to only track crashes.
*/
@property(nonatomic, copy) NSString *sid;
/**
* Optional distribution group ID value.
*/
@property(nonatomic, copy) NSString *distributionGroupId;
/**
* Optional user identifier.
*/
@property(nonatomic, copy) NSString *userId;
/**
* Device properties associated to this log.
*/
@property(nonatomic, strong) MSACDevice *device;
/**
* Transient object tag. For example, a log can be tagged with a transmission target. We do this currently to prevent properties being
* applied retroactively to previous logs by comparing their tags.
*/
@property(nonatomic, strong) NSObject *tag;
/**
* Checks if the object's values are valid.
*
* @return YES, if the object is valid.
*/
- (BOOL)isValid;
/**
* Adds a transmission target token that this log should be sent to.
*
* @param token The transmission target token.
*/
- (void)addTransmissionTargetToken:(NSString *)token;
/**
* Gets all transmission target tokens that this log should be sent to.
*
* @returns Collection of transmission target tokens that this log should be sent to.
*/
- (NSSet *)transmissionTargetTokens;
@end
#endif
@@ -1,25 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_LOG_WITH_PROPERTIES_H
#define MSAC_LOG_WITH_PROPERTIES_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACAbstractLog.h>)
#import <AppCenter/MSACAbstractLog.h>
#else
#import "MSACAbstractLog.h"
#endif
NS_SWIFT_NAME(LogWithProperties)
@interface MSACLogWithProperties : MSACAbstractLog
/**
* Additional key/value pair parameters. [optional]
*/
@property(nonatomic, strong) NSDictionary<NSString *, NSString *> *properties;
@end
#endif
@@ -1,54 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#ifndef MSAC_LOGGER
#define MSAC_LOGGER
#if __has_include(<AppCenter/MSACConstants.h>)
#import <AppCenter/MSACConstants.h>
#else
#import "MSACConstants.h"
#endif
#define MSACLog(_level, _tag, _message) \
[MSACLogger logMessage:_message level:_level tag:_tag file:__FILE__ function:__PRETTY_FUNCTION__ line:__LINE__]
#define MSACLogAssert(tag, format, ...) \
MSACLog(MSACLogLevelAssert, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogError(tag, format, ...) \
MSACLog(MSACLogLevelError, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogWarning(tag, format, ...) \
MSACLog(MSACLogLevelWarning, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogInfo(tag, format, ...) \
MSACLog(MSACLogLevelInfo, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogDebug(tag, format, ...) \
MSACLog(MSACLogLevelDebug, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
#define MSACLogVerbose(tag, format, ...) \
MSACLog(MSACLogLevelVerbose, tag, (^{ \
return [NSString stringWithFormat:(format), ##__VA_ARGS__]; \
}))
NS_SWIFT_NAME(Logger)
@interface MSACLogger : NSObject
+ (void)logMessage:(MSACLogMessageProvider)messageProvider
level:(MSACLogLevel)loglevel
tag:(NSString *)tag
file:(const char *)file
function:(const char *)function
line:(uint)line;
@end
#endif
@@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#import <Foundation/Foundation.h>
#ifndef SERIALIZABLE_OBJECT_H
#define SERIALIZABLE_OBJECT_H
@protocol MSACSerializableObject <NSCoding>
/**
* Serialize this object to a dictionary.
*
* @return A dictionary representing this object.
*/
- (NSMutableDictionary *)serializeToDictionary;
@end
#endif
@@ -1,23 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_SERVICE_H
#define MSAC_SERVICE_H
#import <Foundation/Foundation.h>
/**
* Protocol declaring service logic.
*/
NS_SWIFT_NAME(Service)
@protocol MSACService <NSObject>
/**
* Indicates whether this service is enabled.
* The state is persisted in the device's storage across application launches.
*/
@property(class, nonatomic, getter=isEnabled, setter=setEnabled:) BOOL enabled NS_SWIFT_NAME(enabled);
@end
#endif
@@ -1,58 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef MSAC_SERVICE_ABSTRACT_H
#define MSAC_SERVICE_ABSTRACT_H
#import <Foundation/Foundation.h>
#if __has_include(<AppCenter/MSACService.h>)
#import <AppCenter/MSACService.h>
#else
#import "MSACService.h"
#endif
@protocol MSACChannelGroupProtocol;
/**
* Abstraction of services common logic.
* This class is intended to be subclassed only not instantiated directly.
*/
NS_SWIFT_NAME(ServiceAbstract)
@interface MSACServiceAbstract : NSObject <MSACService>
/**
* The flag indicates whether the service is started from application or not.
*/
@property(nonatomic, assign) BOOL startedFromApplication;
/**
* Start this service with a channel group. Also sets the flag that indicates that a service has been started.
*
* @param channelGroup channel group used to persist and send logs.
* @param appSecret app secret for the SDK.
* @param token default transmission target token for this service.
* @param fromApplication indicates whether the service started from an application or not.
*/
- (void)startWithChannelGroup:(id<MSACChannelGroupProtocol>)channelGroup
appSecret:(NSString *)appSecret
transmissionTargetToken:(NSString *)token
fromApplication:(BOOL)fromApplication;
/**
* Update configuration when the service requires to start again. This method should only be called if the service is started from libraries
* and then is being started from an application.
*
* @param appSecret app secret for the SDK.
* @param token default transmission target token for this service.
*/
- (void)updateConfigurationWithAppSecret:(NSString *)appSecret transmissionTargetToken:(NSString *)token;
/**
* The flag indicate whether the service needs the application secret or not.
*/
@property(atomic, readonly) BOOL isAppSecretRequired;
@end
#endif
Loaded 100 of 1999 files, more files were not shown because too many files have changed in this diff. Show more