413 Commits

Author SHA1 Message Date
Mariusz Klochowicz
05efcfe31a fix(apple): Use a single keychain label (#10986)
Previous attempt to split the Keychain item between between Debug and
Release versions caused issues - we could not save things in the
keychain in Debug.

Revert the problematic change. No changelog entry as it only affected
unreleased debug versions.
2025-11-27 00:14:58 +00:00
Mariusz Klochowicz
994de0fe2a refactor(swift): replace @unchecked Sendable (#10970)
VPNConfigurationManager now uses `@MainActor` isolation instead of
`@unchecked Sendable`. This aligns with Apple's documented behaviour
where NEVPNManager callbacks arrive on the main thread.

- Made `VPNConfigurationManager` final and `@MainActor`
- Added `@MainActor` to `LogExporter.export(to:session:)` on macOS
- Marked `legacyConfiguration()` as `nonisolated` (pure function, called
from network extension)
- Removed redundant `@MainActor` from `maybeMigrateConfiguration()`
2025-11-26 03:41:17 +00:00
Mariusz Klochowicz
4e26f9943b refactor(apple): remove unsafe code instance (#10967)
Use the Combine pattern to avoid unsafe code.
2025-11-25 05:47:06 +00:00
Mariusz Klochowicz
5db7eebbb2 refactor(apple): remove unsafe from Token (#10968)
Convert static query dictionary to a computed property, eliminating the
need for nonisolated(unsafe).

Also fixes a bug where kSecAttrLabel used a hardcoded string instead of
the label property (which differs between debug and release builds).
2025-11-25 05:05:07 +00:00
Mariusz Klochowicz
528db7d9c5 fix(apple): Prevent Swift6 crash on iPadOS (#10916)
UserDefaults change notifications should always be handled on the main
thread.

This wasn't the case when PencilKit posted UserDefaults notifications
from a background thread during its initialization on iPadOS, causing a
Swift 6 MainActor violation crash.

Ultimately, the root cause of this issue was not abiding to strict
Swift6 concurrency checks by using unsafe code: even when the
UserDefaults themselves were `nonisolated(unsafe)` and bypassed the
checks, it was not the case for Apple PencilKit framework ultimately
initialised in wrong context.

Note: There are a few ways to fix, we're settling on Combine pattern as
it's used elsewhere in the codebase (e.g. in Store).

For other solutions, see:

https://stackoverflow.com/questions/74729010/swift-concurrency-notification-callbacks-on-mainactor-objects
2025-11-20 19:21:04 +00:00
Mariusz Klochowicz
f735855344 fix(apple): Restore favorites UI updates on iOS (#10908)
Recent refactors uncovered a latent bug where we never properly
subscribed to favorites updates.

The underlying data was being saved correctly to UserDefaults, but the
view wouldn't redraw to reflect the change.

The fix forwards Favourites.objectWillChange to Store.objectWillChange,
matching the existing pattern for configuration changes and the pattern
used by MenuBar on macOS.

Relevant information:
- Favourites is a nested ObservableObject inside Store
- SwiftUI views observe Store via @EnvironmentObject
- Nested ObservableObject changes don't automatically propagate through
@Published properties

Fixes #10906
2025-11-18 15:03:57 +00:00
Jamil
164f1976c7 fix(apple): queue path updates onto workQueue (#10896)
Path updates are received on a queue which can be (and is typically) on
a different thread from the one the workQueue runs on. Since we are
sharing instance properties across these two threads, we need to make
sure reads and writes to all properties ideally happen on the same
queue.

Moving `Adapter` to an actor class could solve these issues, but that is
a much larger refactor to be done in #10895 and we'd like to ship this
fix in the next release to verify it fixes our issue.
2025-11-17 16:09:47 +00:00
Jamil
91962acb83 chore(apple): ignore benign keychain errors (#10899)
* macOS 13 and below has a known bug that prevents us from saving the
token on the system keychain. To avoid Sentry noise, we ignore this
specific error and continue to log other errors that aren't an exact
match.
* Relatedly, if we try to start the tunnel and a token is not found,
it's not necessarily an error. This happens when the user signs out and
then tries to activate the VPN from system settings, for example.

---------

Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-17 16:09:09 +00:00
Mariusz Klochowicz
bdffa3a697 fix(apple): prevent utun increments from IPC calls (#10855)
On macOS, IPC calls to the network extension can wake it whilst not
connected, causing the system to create a utun device.
If startTunnel() is not subsequently called, these devices
persist and accumulate over time.

The existing dryStartStopCycle() mechanism was introduced to wake the
extension after upgrades, but other IPC operations (log management
functions) could also wake the extension without proper cleanup.

Solution
--------

Add wrapper functions in IPCClient that automatically handle wake-up
and cleanup lifecycle for IPC calls made whilst disconnected:

- Check VPN connection status
- If connected: execute IPC operation directly (utun already exists)
- If disconnected: wake extension → wait 500ms → execute IPC → cleanup

Implementation
--------------

For async IPC operations (clearLogs, getLogFolderSize):
  Created free functions in IPCClient that wrap low-level IPC calls
  with wrapIPCCallIfNeeded():
  - clearLogsWithCleanup(store:session:)
  - getLogFolderSizeWithCleanup(store:session:)

For callback-based exportLogs:
  We cannot use wrapper because exportLogs returns immediately and uses
  callbacks for streaming chunks. Wrapper would call stop() before
  export finishes, killing the extension mid-stream.

  Solution: Manual wake-up/cleanup in LogExporter where we already have
  continuation that waits for chunk.done signal:
  1. Check if extension needs waking (vpnStatus != .connected)
  2. If yes: wake extension, wait 500ms
  3. Start export with callbacks
  4. When chunk.done=true: cleanup utun device, then resume continuation
  5. On error: cleanup utun device, then resume with error
  
  
  Fixes #10580

---------

Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
2025-11-13 22:01:22 +00:00
Jamil
bd2abbaae3 feat(apple): config to hide resource list (#10824)
Adds a configuration variable `hideResourceList` accessible by
provisioning profile only to hide or show the Resource list. This is
helpful when end-users need not be concerned with the resources
available to their account.

Also updates the associated ProfileManifests, docs, and a little bit of
housekeeping around `configuration`, making it public for direct access.

<img width="292" height="228" alt="Screenshot 2025-11-09 at 9 12 47 PM"
src="https://github.com/user-attachments/assets/a4ce5586-bf92-4ebc-bc0d-51215e1efd61"
/>


Related: https://github.com/ProfileManifests/ProfileManifests/pull/839
Fixes: #10808

---------

Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-10 19:55:27 +00:00
Mariusz Klochowicz
470680cb1f chore(apple): Migrate to latest Xcode recommended settings (#10766)
Prompted by Xcode warning at project startup.

Most of the changes are simple migrations from entitlements files
to build settings, which is the recommended approach, and were done
automatically by Xcode.

new settings:
- REGISTER_APP_GROUPS - Automatically registers app groups with
provisioning
profile (I had to set this manually when setting up, so it's a welcome
change)
- STRING_CATALOG_GENERATE_SYMBOLS - type-safe localization (no
  regression, we're not doing any localization currently)
- ENABLE_USER_SCRIPT_SANDBOXING - sandboxing all the build scripts

Note: I had to turn off the recommended `ENABLE_USER_SCRIPT_SANDBOXING`
as it
would interfere with our building of connlib during the build.

Also: make Makefile more ergonomic to use (setup LSP config during first
build)
2025-11-06 22:45:56 +00:00
Mariusz Klochowicz
b5048ad779 refactor(apple): Convert IPCClient from actor to stateless enum (#10797)
Refactors IPCClient from an actor to a stateless enum with static
methods, removing unnecessary actor isolation and instance management.

- IPCClient: Actor → enum with static methods taking session parameter
- Store: Removed IPCClient instance caching, added resource list caching
- Store: Moved resource fetching logic from IPCClient into Store
- All call sites: Updated to pass session directly to static methods

Store now directly manages resource list hashing and caching via
fetchResources() method, using SHA256 hash optimisation to avoid
redundant updates when resource lists haven't changed.
2025-11-05 21:58:20 +00:00
Mariusz Klochowicz
936b095391 chore(apple): Enable Swift 6.2 Approachable Concurrency features (#10799)
Enables SWIFT_APPROACHABLE_CONCURRENCY build setting which activates
a few key Swift 6.2 concurrency features, including:

1. NonisolatedNonsendingByDefault - Makes nonisolated async functions
run
   on the caller's executor instead of the global executor, providing
   more predictable performance and behaviour

2. InferIsolatedConformances - Protocol conformances automatically
   inherit global actor isolation, reducing annotation burden

Read more:
https://www.donnywals.com/what-is-approachable-concurrency-in-xcode-26/

Also bumps swift-tools-version from 6.0 to 6.2 in Package.swift to
enable newer Package Manager manifest APIs.

As a result of better type inference, removes 1 redundant @Sendable
annotation in Store.swift:
- vpnStatusChangeHandler: @MainActor closures are implicitly Sendable
2025-11-05 21:56:24 +00:00
Mariusz Klochowicz
bf95dc45a3 refactor(apple): Upgrade to Swift 6.2 with concurrency checks (#10682)
This PR upgrades the Swift client from Swift 5 to Swift 6.2, addressing
all
concurrency-related warnings and runtime crashes that come with Swift
6's
strict concurrency checking.

## Swift 6 Concurrency Primer

**`actor`** - A new reference type that provides thread-safe, serialised
access to mutable state. Unlike classes, actors ensure that only one
piece of
code can access their mutable properties at a time. Access to actor
methods/properties requires await and automatically hops to the actor's
isolated executor.

**`@MainActor`** - An attribute that marks code to run on the main
thread.
Essential for UI updates and anything that touches UIKit/AppKit. When a
class/function is marked @MainActor, all its methods and properties
inherit
this isolation.

**`@Sendable`** - A protocol indicating that a type can be safely passed
across concurrency domains (between actors, tasks, etc.). Value types
(structs, enums) with Sendable stored properties are automatically
Sendable.
Reference types (classes) need explicit @unchecked Sendable if they
manage
thread-safety manually.

**`nonisolated`** - Opts out of the containing type's actor isolation.
For
example, a nonisolated method in a @MainActor class can be called from
any
thread without await. Useful for static methods or thread-safe
operations.

**`@concurrent`** - Used on closure parameters in delegate methods.
Indicates
the closure may be called from any thread, preventing the closure from
inheriting the surrounding context's actor isolation. Critical for
callbacks
from system frameworks that call from background threads.

**Data Races** - Swift 6 enforces at compile-time (and optionally at
runtime)
that mutable state cannot be accessed concurrently from multiple
threads. This
eliminates entire classes of bugs that were previously only caught
through
testing or production crashes.

## Swift Language Upgrade

- **Bump Swift 5 → 6.2**: Enabled strict concurrency checking throughout
the
  codebase
- **Enable ExistentialAny (SE-0335)**: Adds compile-time safety by
making
  protocol type erasure explicit (e.g., any Protocol instead of implicit
  Protocol)
- **Runtime safety configuration**: Added environment variables to log
concurrency violations during development instead of crashing, allowing
  gradual migration

## Concurrency Fixes

### Actor Isolation

- **TelemetryState actor** (Telemetry.swift:10): Extracted mutable
telemetry
state into a dedicated actor to eliminate data races from concurrent
access
- **SessionNotification @MainActor isolation**
(SessionNotification.swift:25):
  Properly isolated the class to MainActor since it manages UI-related
  callbacks
- **IPCClient caching** (IPCClient.swift): Fixed actor re-entrance
issues and
resource hash-based optimisation by caching the client instance in Store

### Thread-Safe Callbacks

- **WebAuthSession @concurrent delegate** (WebAuthSession.swift:46): The
  authentication callback is invoked from a background thread by
ASWebAuthenticationSession. Marked the wrapper function as @concurrent
to
  prevent MainActor inference on the completion handler closure, then
  explicitly hopped back to MainActor for the session.start() call. This
  fixes EXC_BAD_INSTRUCTION crashes at _dispatch_assert_queue_fail.
- **SessionNotification @concurrent delegate**
(SessionNotification.swift:131): Similarly marked the notification
delegate
method as @concurrent and used Task { @MainActor in } to safely invoke
the
  MainActor-isolated signInHandler

### Sendable Conformances

- Added Sendable to Resource, Site, Token, Configuration, and other
model
  types that are passed between actors and tasks
- **LogWriter immutability** (Log.swift): Made jsonData immutable to
prevent
  capturing mutable variables in @Sendable closures

### Nonisolated Methods

- **Static notification display** (SessionNotification.swift:73): Marked
showSignedOutNotificationiOS() as nonisolated since it's called from the
  Network Extension (different process) and only uses thread-safe APIs

Fixes #10674
Fixes #10675
2025-11-05 04:24:49 +00:00
seer-by-sentry[bot]
ac7aaf820c fix(apple): move reset command to work queue (#10707)
Fixes
[APPLE-CLIENT-7S](https://sentry.io/organizations/firezone-inc/issues/6812982801/).
The issue was that: Synchronous access to
`Adapter.systemConfigurationResolvers` during concurrent deallocation
causes an EXC_BAD_ACCESS crash.

- Moves the `reset` command execution to the `workQueue` to prevent
potential deadlocks or race conditions when accessing shared resources
or interacting with the network extension's internal state.


This fix was generated by Seer in Sentry, triggered by
jamil@firezone.dev. 👁️ Run ID: 2183818

Not quite right? [Click here to continue debugging with
Seer.](https://sentry.io/organizations/firezone-inc/issues/6812982801/?seerDrawer=true)


Fixes #10195

---------

Co-authored-by: seer-by-sentry[bot] <157164994+seer-by-sentry[bot]@users.noreply.github.com>
Co-authored-by: Mariusz Klochowicz <mariusz@klochowicz.com>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
2025-10-30 07:41:45 +00:00
Jamil
39b2f61cfd fix(ci): ensure version markers are replaced across all files (#10752)
Upon moving the version string from PKG_VERSION and Cargo.toml, we lost
the bump version automation. To avoid more bugs here in the future, we
now check for the version marker across all Git-tracked files,
regardless of their extension.

Fixes #10748

---------

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2025-10-29 02:10:50 +00:00
Mariusz Klochowicz
ac6b3922be fix(apple): don't call setConfiguration when not connected (#10747)
Skip `setConfiguration()` IPC call when not in connected state; this was
observed as the root cause of the utun interface increments which we've
seen
recently.

Note: `utun` increments can still happen during other IPC calls when not
signed in,
notably during log export when signed out of Firezone. This is not a
major issue though,
as other IPC calls happen only as a result of user interaction between
network extension sleeps.
To fully get rid of the problem, we should address #10754.

To ensure we still are able to pass on configuration before sign in, we
are now
passing configuration directly in the startTunnel() options dictionary.

Fixes #10603
2025-10-28 23:51:50 +00:00
dependabot[bot]
6105f6fc6a build(deps): bump github.com/getsentry/sentry-cocoa from 8.56.0 to 8.56.2 in /swift/apple/FirezoneKit (#10726)
Bumps
[github.com/getsentry/sentry-cocoa](https://github.com/getsentry/sentry-cocoa)
from 8.56.0 to 8.56.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-cocoa/releases">github.com/getsentry/sentry-cocoa's
releases</a>.</em></p>
<blockquote>
<h2>8.56.2</h2>
<blockquote>
<p>[!Warning]
Session Replay in this version does not correctly mask views when built
with Xcode 26 and running on iOS 26 with Liquid Glass, which may lead to
PII leaks. Please upgrade to 8.57.0 or later, which automatically
<strong>disables session replay</strong> in such environments.</p>
</blockquote>
<h3>Fixes</h3>
<ul>
<li>Fix crash from null UIApplication in SwiftUI apps (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6264">#6264</a>)</li>
</ul>
<h2>8.56.1</h2>
<blockquote>
<p>[!Warning]
This version can cause runtime crashes because the
<code>UIApplication.sharedApplication</code>/<code>NSApplication.sharedApplication</code>
is not yet available during SDK initialization, due to the changes in
[PR <a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5900">#5900</a>](<a
href="https://redirect.github.com/getsentry/sentry-cocoa/pull/5900">getsentry/sentry-cocoa#5900</a>),
released in <a
href="https://github.com/getsentry/sentry-cocoa/releases/tag/8.56.0">8.56.0</a>.</p>
</blockquote>
<blockquote>
<p>[!Warning]
Session Replay in this version does not correctly mask views when built
with Xcode 26 and running on iOS 26 with Liquid Glass, which may lead to
PII leaks. Please upgrade to 8.57.0 or later, which automatically
<strong>disables session replay</strong> in such environments.</p>
</blockquote>
<h3>Fixes</h3>
<ul>
<li>Fix potential app launch hang caused by the SentrySDK (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6181">#6181</a>)
Fixed by removing the call to <code>_dyld_get_image_header</code> on the
main thread.</li>
<li>Fix dynamic selector crash in SentryReplayRecording (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6211">#6211</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9e193ac0b7"><code>9e193ac</code></a>
release: 8.56.2</li>
<li><a
href="d1c491625f"><code>d1c4916</code></a>
test: Skip flaky user feedback UITests (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6289">#6289</a>)</li>
<li><a
href="9a32d525be"><code>9a32d52</code></a>
fix: Lazily access UIApplication.shared (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6264">#6264</a>)</li>
<li><a
href="2ec27000f0"><code>2ec2700</code></a>
chore(ci): Set iOS version for running Test Server unit tests (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6287">#6287</a>)</li>
<li><a
href="4be5cd8ec9"><code>4be5cd8</code></a>
ci: Extra test plan for test server unit tests (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6177">#6177</a>)</li>
<li><a
href="449d185f00"><code>449d185</code></a>
chore(deps): Update clang-format version (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6276">#6276</a>)</li>
<li><a
href="649265b71b"><code>649265b</code></a>
test: Skip AppHangTracking when debugger attached (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6242">#6242</a>)</li>
<li><a
href="7dabfb9176"><code>7dabfb9</code></a>
docs: Add warning to releases v8.56.0 and v8.56.1 (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6266">#6266</a>)</li>
<li><a
href="d8ceea3a0c"><code>d8ceea3</code></a>
Merge branch 'release/8.56.1'</li>
<li><a
href="a82041aad9"><code>a82041a</code></a>
release: 8.56.1</li>
<li>Additional commits viewable in <a
href="https://github.com/getsentry/sentry-cocoa/compare/8.56.0...8.56.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/getsentry/sentry-cocoa&package-manager=swift&previous-version=8.56.0&new-version=8.56.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-28 01:55:52 +00:00
Firezone Bot
76d86545a6 chore: publish apple-client 1.5.9 (#10654) 2025-10-20 14:04:08 +00:00
dependabot[bot]
6e1fb01286 build(deps): bump github.com/getsentry/sentry-cocoa from 8.55.1 to 8.56.0 in /swift/apple/FirezoneKit (#10629)
Bumps
[github.com/getsentry/sentry-cocoa](https://github.com/getsentry/sentry-cocoa)
from 8.55.1 to 8.56.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-cocoa/releases">github.com/getsentry/sentry-cocoa's
releases</a>.</em></p>
<blockquote>
<h2>8.56.0</h2>
<blockquote>
<p>[!Warning]
This version can cause runtime crashes because the
<code>UIApplication.sharedApplication</code>/<code>NSApplication.sharedApplication</code>
is not yet available during SDK initialization, due to the changes in
[PR <a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5900">#5900</a>](<a
href="https://redirect.github.com/getsentry/sentry-cocoa/pull/5900">getsentry/sentry-cocoa#5900</a>),
released in <a
href="https://github.com/getsentry/sentry-cocoa/releases/tag/8.56.0">8.56.0</a>.</p>
</blockquote>
<blockquote>
<p>[!Warning]
Session Replay in this version does not correctly mask views when built
with Xcode 26 and running on iOS 26 with Liquid Glass, which may lead to
PII leaks. Please upgrade to 8.57.0 or later, which automatically
<strong>disables session replay</strong> in such environments.</p>
</blockquote>
<h3>Features</h3>
<ul>
<li>Structured Logs: Flush logs on SDK flush/close (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5834">#5834</a>)</li>
<li>Add masking options for screenshots (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5401">#5401</a>)</li>
<li>Add significant time change breadcrumb (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6112">#6112</a>)</li>
<li>Add support for iOS 26, macOS 26, visionOS 26, watchOS 26, and tvOS
26 in device tests (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6063">#6063</a>)</li>
</ul>
<h3>Improvements</h3>
<ul>
<li>Lazily CharacterSet only once in SentryBaggageSerialization (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5871">#5871</a>)</li>
<li>Structured Logging: Log <code>SentrySDK.logger</code> calls to
<code>SentrySDKLog</code> (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5991">#5991</a>)</li>
<li>The build type in the app context now differentiates between
<code>enterprise</code> and <code>adhoc</code> (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6044">#6044</a>)</li>
<li>visionOS no longer needs swift's interoperability mode (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6077">#6077</a>)</li>
<li>Ensure IP address is only inferred by Relay if sendDefaultPii is
true (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5877">#5877</a>)</li>
<li>Sentry without UIKit / AppKit is available to install with SPM (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6160">#6160</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li>Don't capture replays for events dropped in <code>beforeSend</code>
(<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5916">#5916</a>)</li>
<li>Fix linking with SentrySwiftUI on Xcode 26 for visionOS (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5823">#5823</a>)</li>
<li>Structured Logging: Logger called before
<code>SentrySDK.start</code> becomes unusable (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5984">#5984</a>)</li>
<li>Add masking for AVPlayerView (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5910">#5910</a>)</li>
<li>Fix missing view hierachy when enabling
<code>attachScreenshot</code> too (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5989">#5989</a>)</li>
<li>Fix macOS's frameworks not following the versioned framework
structure (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6049">#6049</a>)</li>
<li>Add warning to addBreadcrumb when used before SDK init (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6083">#6083</a>)</li>
<li>Add null-handling for parsed DSN in SentryHTTPTransport (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5800">#5800</a>)</li>
<li>Fix crash in Session Replay when opening the camera UI on iOS 26+ by
skipping redaction of internal views.
This may result in more of the camera screen being redacted. (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6045">#6045</a>)</li>
<li>Fix crash in SentryDependencyContainer init when using the SDK as a
static framework (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6125">#6125</a>)</li>
<li>Fixes a React Native legacy build failure by adding the missing self
references for explicit capture semantics (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6156">#6156</a>)</li>
</ul>
<h2>8.56.0-alpha.3</h2>
<h3>Features</h3>
<ul>
<li>Structured Logs: Flush logs on SDK flush/close (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5834">#5834</a>)</li>
<li>Add masking options for screenshots (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5401">#5401</a>)</li>
<li>Add significant time change breadcrumb (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6112">#6112</a>)</li>
<li>Add support for iOS 26, macOS 26, visionOS 26, watchOS 26, and tvOS
26 in device tests (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6063">#6063</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li>Don't capture replays for events dropped in <code>beforeSend</code>
(<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5916">#5916</a>)</li>
<li>Fix linking with SentrySwiftUI on Xcode 26 for visionOS (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5823">#5823</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3365d74b0a"><code>3365d74</code></a>
chore: Add changes from alpha releases to v8.56.0 changelog (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6166">#6166</a>)</li>
<li><a
href="5542c69989"><code>5542c69</code></a>
release: 8.56.0</li>
<li><a
href="c30e40105c"><code>c30e401</code></a>
feat: Make Sentry-WithoutUIKitOrAppKit available with SPM (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6160">#6160</a>)</li>
<li><a
href="5ae9ff1e4f"><code>5ae9ff1</code></a>
ref: Remove unused memory pressure typdef (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6152">#6152</a>)</li>
<li><a
href="8745cc0ff5"><code>8745cc0</code></a>
ref: Convert <code>SentryCrashWrapper</code> to Swift (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6047">#6047</a>)</li>
<li><a
href="c1f202e16b"><code>c1f202e</code></a>
Merge branch 'release/8.56.0-alpha.3'</li>
<li><a
href="fad8f23d7a"><code>fad8f23</code></a>
release: 8.56.0-alpha.3</li>
<li><a
href="5cbd333fee"><code>5cbd333</code></a>
chore(ci): React-Native: Adds missing self to make capture semantics
explicit...</li>
<li><a
href="89e74bc125"><code>89e74bc</code></a>
Merge branch 'release/8.56.0-alpha.2'</li>
<li><a
href="36b80343ab"><code>36b8034</code></a>
chore: Fix changelog (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6154">#6154</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/getsentry/sentry-cocoa/compare/8.55.1...8.56.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/getsentry/sentry-cocoa&package-manager=swift&previous-version=8.55.1&new-version=8.56.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-20 14:02:21 +00:00
Thomas Eizinger
0e48d27b5a feat(ffi): make all calls infallible (#10621)
In the spirit of making Firezone as robust as possible, we make the FFI
calls infallible and complete as much of the task as possible. For
example, we don't fail `setDns` entirely just because we cannot parse a
single DNS server's IP.

Resolves: #10611
2025-10-20 01:03:26 +00:00
Thomas Eizinger
0dd7792428 refactor(swift): revise event-loop (#10573)
This is a follow-up from #10368 where we revise the forwarding logic in
`runSessionEventLoop`. Redundant logs are removed and the only exit
conditions from the event-loop are now the closing of either the event
or the command stream. The event-stream will only close once `connlib`
has successfully shut down and the command stream will only close of the
adapter shuts down (and thus drops the sender-side of the channel).
2025-10-17 19:39:46 +00:00
Jamil
97895c499a fix(apple): call completionHandler only after initialized (#10606)
Apple's [docs
state](https://developer.apple.com/documentation/networkextension/nepackettunnelprovider/starttunnel(options:completionhandler:)#Discussion)
that we should only call the PacketTunnelProvider's `completionHandler`
once the tunnel is ready to route packets. Calling it prematurely, while
shouldn't cause packets to get routed to us (we haven't added the routes
yet), will however cause the system to think our VPN is "online", which
disconnects other VPNs and communicates to the user Firezone is
"connected".

If the portal is then slow to send us the init, we will be stuck in this
quasi-connected state for more than a brief moment of time.

To fix this, we thread `completionHandler` through to `Adapter` and call
this if we are configuring the tun interface for the first time. This
way, we remain in the `connecting` state until the tunnel is fully
configured.
2025-10-17 15:53:26 +00:00
Jamil
fbade40e66 fix(apple): don't return Data() to fetchResources (#10605)
When the tunnel first comes up, the first call to `fetchResources` was
returning an empty `Data()` instance that the receiver would fail to
decode properly because it assumes if a `Data` is non-nil, it is a list
of Resources.

This resulted in a decode error each time the tunnel was started.

Related:
https://github.com/firezone/firezone/pull/10603#discussion_r2438472011

---------

Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-17 08:50:44 -07:00
Jamil
73576922ff fix(apple/macos): clean up utun on quit (#10603)
On macOS, because it uses the System Extension packaging type, the
lifecycle of the tunnel provider process is not tied directly to
connlib's session start and end, but rather managed by the system. The
process is likely running at all times, even when the GUI is not open or
signed in.

The system will start the provider process upon the first IPC call to
it, which allocates a `utun` interface. The tricky part is ensuring this
interface gets removed when the GUI app quits. Otherwise, it's likely
that upon the next launch of the GUI app, the system will allocate a
_new_ utun interface, and the old one will linger until the next system
reboot.

Here's where things get strange. The system will only remove the `utun`
interface when stopping the tunnel under the following conditions:

- The provider is currently not in a `disconnected` state (so it needs
to be in `reasserting`, `connecting`, or `connected`
- The GUI side has called `stopTunnel`, thereby invoking the provider's
`stopTunnel` override function, or
- The provider side has called `cancelTunnelWithError`, or
- The `startTunnel`'s completionHandler is called with an `Error`

The problem we had is that we make various IPC calls throughout the
lifecycle of the GUI app, for example, to gather logs, set tunnel
configuration, and the like. If the GUI app was _not_ in a connected
state when the user quit, the `utun` would linger, even though we were
issuing a final `stopTunnel` upon quit in all circumstances.

To fix the issue, we update the dry run `startTunnel` code path we added
previously in two ways:

1. We add a `dryRun` error type to the `startTunnel`'s completionHandler
2. We implement the GUI app `applicationShouldTerminate` handler in
order to trigger one final dryRun which briefly moves the provider to a
connected state so the system will clean us up when its
completionHandler is invoked.


Tested under the following conditions:

- Launch app in a signed-out state -> quit
- Launch app in a signed-out state -> sign in -> quit
- Launch app in a signed-out state -> sign in -> sign out -> quit
- Launch app in a signed-in state -> quit
- Launch app in a signed-in state -> sign out -> quit

Notably, if the GUI app is killed with `SIGKILL`, our terminate hook is
_not_ called, and the utun lingers. We'll have to accept this edge case
for now.

Along with the above, the janky `consumeStopReason` mechanism has been
removed in favor of NE's `cancelTunnelWithError` to pass the error back
to the GUI we can then use to show the signed out alert.


Fixes #10580
2025-10-17 15:12:29 +00:00
Thomas Eizinger
fba904d570 chore(apple): always build client-ffi on debug (#10601)
Incorporating feedback from Copilot in #10600.
2025-10-17 02:43:05 +00:00
Thomas Eizinger
b70865564d chore(apple): allow generating UniFFI bindings on Linux (#10600)
To generate the UniFFI bindings, we don't actually need to be on an
Apple device. To make cross-platform development a bit easier, we
extract the binding generation step into the Makefile.
2025-10-17 01:49:33 +00:00
Mariusz Klochowicz
e76daaaab3 refactor: remove JSON serialization from FFI boundary (#10575)
This PR eliminates JSON-based communication across the FFI boundary,
replacing it with proper
uniffi-generated types for improved type safety, performance, and
reliability. We replace JSON string parameters with native uniffi types
for:
 - Resources (DNS, CIDR, Internet)
 - Device information
 - DNS server lists
 - Network routes (CIDR representation)
 
Also, get rid of JSON serialisation in Swift client IPC in favour of
PropertyList based serialisation.
 
 Fixes: https://github.com/firezone/firezone/issues/9548

---------

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2025-10-16 05:15:31 +00:00
Mariusz Klochowicz
97f3979fa6 fix(apple): Explicitly hide network extension from the UI (#10581)
Apparently if we set the CFBundleDisplayName we hint by default that
we *do* want to show it on newer macOS versions.

This seems to have been uncovered by Xcode 26 build recently.

Fixes #10579
2025-10-16 03:42:10 +00:00
Mariusz Klochowicz
8378819621 fix(apple): Ensure fetching resource state if already connected (#10567)
Fixes an issue where the Resources menu would not populate when
launching
the app while already connected by ensuring the initial VPN status
triggers the resource loading handler.


Fixes #9837
2025-10-14 23:55:02 +00:00
Mariusz Klochowicz
cb50800d52 refactor(apple): Migrate iOS/macOS clients to UniFFI (#10368)
Replace callback-based Adapter with event polling-based AdapterUniFfi

This change improves reliability by eliminating callback lifetime
issues.
2025-10-13 23:13:52 +00:00
Thomas Eizinger
8fc2ef8ad1 fix(clients): set Internet Resource state on startup (#10509)
Building on top of #10507, setting the initial Internet Resource state
is a piece of cake. All we need to do is thread a boolean variable
through to all call-sites of `Session::connect`. Without the need for
the Internet Resource's ID, we can simply pass in the boolean that is
saved in the configuration of each client.

Resolves: #10255
2025-10-07 07:13:52 +00:00
Thomas Eizinger
36dfee2c42 refactor(connlib): explicitly enable/disable Internet Resource (#10507)
Instead of the generic "disable any kind of resource"-functionality that
connlib currently exposes, we now provide an API to only enable /
disable the Internet Resource. This is a lot simpler to deal with and
reason about than the previous system, especially when it comes to the
proptests. Those need to model connlib's behaviour correctly across its
entire API surface which makes them unnecessarily complex if we only
ever use the `set_disabled_resources` API with a single resource.

In preparation for #4789, I want to extend the proptests to cover
traffic filters (#7126). This will make them a fair bit more
complicated, so any prior removal of complexity is appreciated.

Simplifying the implementation here is also a good starting point to fix
#10255. Not implicitly enabling the Internet Resource when it gets added
should be quite simple after this change.

Finally, resolving #8885 should also be quite easy. We just need to
store the state of the Internet Resource once per API URL instead of
globally.

Resolves: #8404

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-07 00:26:07 +00:00
dependabot[bot]
900186cd63 build(deps): bump github.com/getsentry/sentry-cocoa from 8.55.0 to 8.55.1 in /swift/apple/FirezoneKit (#10518)
Bumps
[github.com/getsentry/sentry-cocoa](https://github.com/getsentry/sentry-cocoa)
from 8.55.0 to 8.55.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-cocoa/releases">github.com/getsentry/sentry-cocoa's
releases</a>.</em></p>
<blockquote>
<h2>8.55.1</h2>
<h3>Features</h3>
<h3>Fixes</h3>
<ul>
<li>Fix macOS's frameworks not following the versioned framework
structure (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6049">#6049</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2c70925b98"><code>2c70925</code></a>
release: 8.55.1</li>
<li><a
href="4aa237de0d"><code>4aa237d</code></a>
chore: Update changelog</li>
<li><a
href="e8f2418539"><code>e8f2418</code></a>
fix(ci): Resolve symlink path before removing architectures (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/6049">#6049</a>)</li>
<li>See full diff in <a
href="https://github.com/getsentry/sentry-cocoa/compare/8.55.0...8.55.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/getsentry/sentry-cocoa&package-manager=swift&previous-version=8.55.0&new-version=8.55.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-06 17:28:43 +00:00
dependabot[bot]
f825995fc3 build(deps): bump github.com/getsentry/sentry-cocoa from 8.49.0 to 8.55.0 in /swift/apple/FirezoneKit (#10496)
Bumps
[github.com/getsentry/sentry-cocoa](https://github.com/getsentry/sentry-cocoa)
from 8.49.0 to 8.55.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-cocoa/releases">github.com/getsentry/sentry-cocoa's
releases</a>.</em></p>
<blockquote>
<h2>8.55.0</h2>
<blockquote>
<p>[!Important]
Xcode 26 no longer allows individual frameworks to contain arm64e slices
anymore if the main binary doesn't contain them.
We have decided to split the Dynamic variant and
Sentry-WithoutUIKitOrAppKit of Sentry into two variants:</p>
<ul>
<li><code>Sentry-Dynamic</code>: Without ARM64e</li>
<li><code>Sentry-Dynamic-WithARM64e</code>: <em>With</em> ARM64e
slice</li>
<li><code>Sentry-WithoutUIKitOrAppKit</code>: Without ARM64e</li>
<li><code>Sentry-WithoutUIKitOrAppKit-WithARM64e</code>: <em>With</em>
ARM64e slice</li>
</ul>
<p>If your app does not need arm64e, you don't need to make any changes.
But if your app <em>needs arm64e</em> please use
<code>Sentry-Dynamic-WithARM64e</code> or
<code>Sentry-WithoutUIKitOrAppKit-WithARM64e</code> from 8.55.0 so you
don't have issues uploading to the App Store.</p>
</blockquote>
<h3>Features</h3>
<ul>
<li>Add a new prebuilt framework with arm64e and remove it from the
regular one (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5788">#5788</a>)</li>
<li>Add <code>beforeSendLog</code> callback to
<code>SentryOptions</code> (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5678">#5678</a>)</li>
<li>Structured Logs: Flush logs on SDK flush/close (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5834">#5834</a>)</li>
<li>Add a new prebuilt framework with ARM64e for WithoutUIKitOrAppKit
(<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5897">#5897</a>)</li>
<li>Add source context and vars fields to SentryFrame (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5853">#5853</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li>Add support for PDFKit views in session replay (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5750">#5750</a>)</li>
<li>Fix Infinite Session Replay Processing Loop (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5765">#5765</a>)</li>
<li>Fix memory leak in SessionReplayIntegration (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5770">#5770</a>)</li>
<li>Fix reporting of energy used while profiling (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5768">#5768</a>)</li>
<li>Fixed a build error in <code>SentryFeedback.swift</code> when
building with cocoapods on Xcode 14.2 (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5917">#5917</a>)</li>
<li>Fix linking against Sentry on an app extension (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5813">#5813</a>)</li>
</ul>
<h2>8.54.1-alpha.2</h2>
<blockquote>
<p>[!Important]
Xcode 26 no longer allows individual frameworks to contain arm64e slices
anymore if the main binary doesn't contain them.
We have decided to split the Dynamic variant and
Sentry-WithoutUIKitOrAppKit of Sentry into two variants:</p>
<ul>
<li><code>Sentry-Dynamic</code>: Without ARM64e</li>
<li><code>Sentry-Dynamic-WithARM64e</code>: <em>With</em> ARM64e
slice</li>
<li><code>Sentry-WithoutUIKitOrAppKit</code>: Without ARM64e</li>
<li><code>Sentry-WithoutUIKitOrAppKit-WithARM64e</code>: <em>With</em>
ARM64e slice</li>
</ul>
<p>If your app does not need arm64e, you don't need to make any changes.
But if your app <em>needs arm64e</em> please use
<code>Sentry-Dynamic-WithARM64e</code> or
<code>Sentry-WithoutUIKitOrAppKit-WithARM64e</code> from 8.55.0 so you
don't have issues uploading to the App Store.</p>
</blockquote>
<h3>Features</h3>
<ul>
<li>Structured Logs: Flush logs on SDK flush/close (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5834">#5834</a>)</li>
<li>Add a new prebuilt framework with ARM64e for WithoutUIKitOrAppKit
(<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5897">#5897</a>)</li>
<li>Add source context and vars fields to SentryFrame (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5853">#5853</a>)</li>
</ul>
<h3>Fixes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3c2eee7773"><code>3c2eee7</code></a>
release: 8.55.0</li>
<li><a
href="3ec47ae715"><code>3ec47ae</code></a>
ci: Use iOS18.5 since 18.6 seems to be unavailable sometimes (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5944">#5944</a>)</li>
<li><a
href="1a34ddc00f"><code>1a34ddc</code></a>
ci: Bump iOS and tvOS versions to 18.6 (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5942">#5942</a>)</li>
<li><a
href="67e8e3ecf0"><code>67e8e3e</code></a>
Merge branch 'release/8.54.1-alpha.2'</li>
<li><a
href="45482a6a1b"><code>45482a6</code></a>
fix: Build error on Xcode 14.2 (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5917">#5917</a>)</li>
<li><a
href="9174496cdc"><code>9174496</code></a>
release: 8.54.1-alpha.2</li>
<li><a
href="891fd1d420"><code>891fd1d</code></a>
ref: Make SentryEventDecodable internal in V9 (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5808">#5808</a>)</li>
<li><a
href="dba4ee8975"><code>dba4ee8</code></a>
Refactor SentryFeedback serialization to have 2 declarations depending
if SDK...</li>
<li><a
href="669f02ce7d"><code>669f02c</code></a>
Add changelog</li>
<li><a
href="4506bdb8b3"><code>4506bdb</code></a>
fix: Build error on Xcode 14.2</li>
<li>Additional commits viewable in <a
href="https://github.com/getsentry/sentry-cocoa/compare/8.49.0...8.55.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/getsentry/sentry-cocoa&package-manager=swift&previous-version=8.49.0&new-version=8.55.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 03:26:38 +00:00
Mariusz Klochowicz
4d2b592d65 chore: Clean up Xcode config (#10461)
- declary sentry as FirezoneKit dependency
- add config for non-Xcode LSP config 
- add some more info in README
2025-10-01 02:08:18 +00:00
Jamil
378586b057 fix(apple): sentry hang tracking for singleton (#10382)
Trying to knock out some low-hanging Sentry alert fruit.

Fixes #10381
2025-09-19 05:13:34 +00:00
Mariusz Klochowicz
b1ed2f8a5e chore: improve macos dev experience (#10363)
Quality of life improvements for macOS devs, mostly relevant when not
using Xcode as daily driver - although some convenience functions &
explicit sentry dependency should make it better there too.
2025-09-17 02:17:36 +00:00
Firezone Bot
d8079c869f chore: publish apple-client 1.5.8 (#10323) 2025-09-10 17:06:40 +00:00
Mariusz Klochowicz
963cc8ede0 fix(apple): Enforce single Firezone instance (#10313)
show an alert to the user and ask to quit previous Firezone instance
manually before starting a new one.

Resolves: #10295

---------

Signed-off-by: Mariusz Klochowicz <mariusz@klochowicz.com>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
2025-09-10 01:54:58 +00:00
Jamil
9696d00cc3 fix(apple): flush dns cache on resource updates (#10224)
In the following sequence of events, a user will be unable to connect to
the DNS resource for a few seconds because macOS is caching the queries,
preventing connlib from seeing them.

1. User signs in
2. User has _no_ access to DNS Resource A
3. User queries for DNS Resource A - NXDOMAIN -> macOS caches this
4. Admin grants access to DNS Resource A
5. User tries query again -> connlib never sees the query -> cache hit
-> NXDOMAIN

To fix this, we call `networkSettings.apply()` whenever the resource
list has changed. This has been tested to trigger a DNS cache flush on
macOS.
2025-08-19 13:08:23 +00:00
Firezone Bot
95ee111e62 chore: publish apple-client 1.5.7 (#10159) 2025-08-07 04:38:03 +00:00
Jamil
b96ee526c1 fix(apple/ios): don't require hard link to __res_9_state (#10143)
In Xcode 16, how the compiler determines the size of C structs changed.

In Xcode 15 and below, when the compiler saw `__res_9_state()`, it
thought, "This is a C struct. I know its size and layout from the
system's header files. I will generate code to allocate that much memory
and zero it out." This was a type-based operation; it only needed the
"blueprint" for the struct.

In Xcode 16 and later, the compiler sees `__res_9_state()` and thinks,
"This is a C struct. To initialize it, I need to link to the actual
symbol named `___res_9_state` inside the libresolv library." This became
a symbol-based operation, creating a direct dependency that didn't exist
before.

To fix this, we initialize a raw pointer with a manual type
specification to the zeroed-out struct, which reverts to the prior
behavior.

Has been tested on iPhone 12, iOS 17.

Fixes #10108
2025-08-05 20:08:56 +00:00
Firezone Bot
acf52ccf1e chore: publish apple-client 1.5.6 (#10106) 2025-08-02 19:43:35 +00:00
Jamil
290b0c298f fix(apple/ios): less aggressive setDns to avoid update loops (#10075)
In
https://github.com/firezone/firezone/pull/10022/files#diff-a84e8f62a17ac67f781019e6ac0456567fd18ffa7c13b3248609d78debb6480eL342
we removed the path connectivity filter that prevented path update loops
on iOS. This was done to try and respond more aggressively to path
updates in order to set system DNS resolvers, because we can't glean
from the path's instance properties that any DNS configuration has
changed - we simply have to assume so.

Unfortunately, that caused an issue where we now enter a path update
loop and effectively never fully bring the tunnel up.

I've spent lots of time looking for a reliable work around that would
allow us to both, (1) respond to path updates for DNS configuration
changes on the system (we have to blindly react to these), and (2) avoid
path update loops, but alas, without a significant time investment,
there doesn't seem to be a way.

So, we only set system resolvers on iOS in the path update handler if
there was _also_ a detectable connectivity change, and settle on the
assumption that **most** DNS configuration changes will be accompanied
by a network connectivity change as well.
2025-08-01 06:20:24 +00:00
Jamil
442a85ac15 fix(apple): reset network on wake from sleep (#10059)
When a mac device goes to sleep, it typically does not turn off the WiFi
radio. If the mac never leaves the network it was on upon sleep, then
upon wake it will never receive a path update, and we would not have
performed a connlib network reset.

To fix this, we now properly detect a wake from sleep event and issue a
network reset.

Fixes #10056
2025-07-31 00:19:37 +00:00
Firezone Bot
e6fc7e62da chore: publish apple-client 1.5.5 (#10035) 2025-07-28 20:14:12 +00:00
Jamil
42de3ad144 fix(apple): save networkSettings var (#10022)
In 45466e3b78, the `networkSettings`
variable was no longer saved on the `adapter` instance, causing all
calls of the iOS-specific version of getting system resolvers to return
the connlib sentinels after the tunnel first came up.

This PR fixes that logic bug and also cleans this area of the codebase
up just a tiny bit so it's easier to follow.

Lastly, we also fix a bug where if the tunnel came up while Firezone was
already running, `networkSettings` would be `nil`, and we would read the
default system resolvers, which were the connlib sentinels.


Fixes https://github.com/firezone/firezone/issues/10017
2025-07-27 22:42:43 +00:00
Jamil
621028a998 fix(apple): use documents for tempfile (#10019)
On iOS, we were using the tempfile directory to stage the log export,
and then moving this into place from the share sheet presented to the
user.

For some reason, this has stopped working in iOS 18.5.0, and we need to
stage the file in the standard documents directory instead.


Fixes #10014
2025-07-26 22:05:10 +00:00
Jamil
13de2d303e fix(apple): reset network on path status changes (#9997)
Fixes an edge case where a WiFi interface could go offline, then come
back online with the same connectivity, preventing the path update
handler from reset connlib state.

This would cause an issue especially if the WiFi was disabled for more
than 30 seconds / 2 minutes.
2025-07-25 04:53:41 +00:00