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 />
[](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>
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.
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>
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.
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
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.
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
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
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
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.
On Apple platforms, we tried to be clever about filtering path updates
from the network connectivity change monitor, because there can be a
flurry of them upon waking from sleep or network roaming.
However, because of this, we had a bug that could occur in certain
situations (such as waking from sleep) where we could effectively "land"
on an empty DNS resolver list. This could happen if:
1. We receive a path update handler that meaningfully changes
connectivity, but its `supportsDNS` property is `false`. This means it
hasn't received any resolvers from DHCP yet. We would then setDns with
an empty resolver list.
2. We then receive a path update handler with the _only_ change being
`supportDNS=true`. Since we didn't count this change as a meaningful
path change, we skipped the `setDns` call, and connlib would be stuck
without DNS resolution.
To fix the above, we stop trying to be clever about connectivity
changes, and just use `oldPath != path`. That will increase reset a bit,
but it will now handle other edge cases such as an IP address changing
on the primary interface, any other interfaces change, and the like.
Fixes#9866
When validating the found system resolvers on macOS and iOS, we would
stop after validating the first found resolver (usually IPv4) because
`break` was used instead of `continue`.
Fixes#9914
---------
Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
This PR replaces the use of Apple Archive with an API that allows us to
zip the log file contents. This API doesn't handle symlinks well so we
move the symlink out of the way before making the zip. The symlink is
then moved back after the process is completed. Any errors in this
process are ignored as the symlink itself is not a critical component of
Firezone.
The zip compression is marginally less efficient than the Apple Archive.
Instead of compressing ~2GB of logs to 11.8 MB we now get an archive of
12.4 MB. Considering how much easier zip files are to handle, this seems
like a fine trade-off.
<img width="774" alt="Screenshot 2025-06-16 at 00 04 52"
src="https://github.com/user-attachments/assets/8fb6bade-5308-40b9-a446-2a2c364cb621"
/>
Resolves: #7475
---------
Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
Rust and Swift disagree about the formatting of these, leading to
constant git file dirtiness when working on Apple code.
These were originally added when we didn't have as much automation to
regeneration these on each build.
As recommended by the Sentry team [0], "App hang" tracking should be
disabled before calling into certain system APIs like showing alerts to
prevent false-positives.
[0]: https://github.com/getsentry/sentry-cocoa/issues/3472
When using alternative editors other than Xcode, Intellisense is usually
provided by `sourcekit-lsp`. The LSP server also uses `swift-format`
under the hood to format the code but appears to default to using 4
spaces for indentation. In order to standardise on how much indentation
is used, we add a `.swift-format` file that specifies is.
It appears that the code generation in our `build.rs` generates the code
with different formatting and this therefore constantly shows up as
untracked changes in my editor.
When working on the Swift codebase, I noticed that running the formatter
produced a massive diff. This PR re-formats the Swift code with `swift
format . --recursive --in-place` and adds a CI check to enforce it going
forward.
Resolves: #9534
---------
Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
Until we implement #3959 for the Apple client, we need to be careful
around how we de-initialise the Rust session. Callback-based designs are
difficult to get right across boundaries because they enable
re-entrances which then lead to runtime errors.
Specifically, freeing the session needs to cleanup the tokio runtime but
that is impossible if the callback is still executed from that exact
runtime. To workaround this, we need to free the session pointer from a
new task.
Moving to #3959 will solve this in a much more intuitive way because we
can ditch the callbacks and instead move to a stream of events that the
host app can consume.
---------
Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
This PR fixes two crashes related to lifetimes on Apple:
- `completionHandler` was being called from within a Task executor
context, which could be different from the one the IPC call was received
on
- The `getLogFolderSize` task could return and attempt to call
`completionHandler` after the PacketTunnelProvider deinit'd
- We were calling the completionHandler from `stopTunnel` manually.
Apple explicitly says not to do this. Instead, we must call
`cancelTunnelWithError(nil)` when we want to stop the tunnel from e.g.
the `onDisconnect`. Apple with then call our `stopTunnel` override. The
downside is that we have no control over the `NEProviderStopReason`
received in this callback, but we don't use it anyway. Instead, we write
the reason to a temporary file and read it from the GUI process when we
detect a status change to `disconnected`. When that occurs, we're able
to show a UI notification (macOS only - iOS can show this notification
from the PacketTunnelProvider itself).
The GUI client already uses the same function to check for
authentication errors. Therefore, this case is already handled there.
For Swift, we can easily expose this getter via the `swift-bridge`
module. For Android, we don't expose it for now. Once we tackle #3959,
this should be easier to do. In the meantime, the UX on Android is not
super terrible. The user gets signed out and we will then receive a 401
when we try to sign-in again the next time.
Resolves: #9289
When pulling IPs from system resolvers, it's possible the IPv6 addresses
may contain scopes which will cause connlib to barf when parsing.
To fix these, we first convert to the Swift-native type `IPv4Address` or
`IPv6Address` and then use the string representation of those types,
which normalizes them to plain addresses.
Fixes#9055
If the tunnel is already down when we try to quit the application, we
were throwing a harmless error because we mistakenly required a
connected status to send the `stopTunnel` command, which is just a no-op
if we're already connected.
On Apple platforms, `UserDefaults` provides a convenient way to store
and fetch simple plist-compatible data for your app. Unbeknownst to the
author at the time of original implementation was the fact this these
keys are already designed for managed configurations to "mask" any
user-configured equivalents.
This means we no longer need to juggle two dicts in UserDefaults, and we
can instead check which keys are forced via a simple method call.
Additionally, the implementation was simplified in the following ways:
- The host app is the "source of truth" for app configuration now. The
tunnel service receives `setConfiguration` which applies the current
configuration, and saves it in order to start up again without the GUI
connected. The obvious caveat here is that if the GUI isn't running,
configuration such as `internetResourceEnabled` applied by the
administrator won't take effect. This is considered an edge case for the
time being since no customers have asked for this. Additionally, admins
can be advised to ensure the Firezone GUI is running on the system at
all times to prevent this.
- Settings and ConfigurationManager are now able to be removed - these
became redundant after consolidating configuration to the containing
app.
In #9169 we applied MDM configuration from MDM upon _any_ change to
UserDefaults. This is unnecessary.
Instead, we can compare new vs old and only apply the new dict if
there's changes.
In this PR we also log the old and new dicts for debugging reasons.
Adds a new settings/configuration item `startOnLogin` which simply adds
a "Login Item" which starts Firezone after signing into the Mac.
This feature is macOS 13 and above only because otherwise we will need
to bundle a helper application to register as a service to start the
app. Given our very small footprint of macOS 12 users, and how
unsupported it is, this is ok.
When it comes time to implement MDM for this feature, note that Apple
provides a means to enforce login items via the
[`ServiceManagementLoginItems`
payload](https://developer.apple.com/documentation/devicemanagement/servicemanagementmanagedloginitems)
which is outside the scope of `com.apple.configuration.managed`. This
enforces the login item in System Settings so that the user is unable to
disable it.
We also add functionality here, but bear in mind that even if we disable
the Toggle switch in our Settings page, the user could still disable the
item in system settings unless it is being set through MDM via the
service management key above.
Another thing to note is that this setting is applied on the GUI side of
the tunnel only, because it is inherently tied to the process it is
running as. We are not able to (nor does it make sense to) enable the
login item for the tunnel service. This should be fine.
Tested to ensure enabling/disabling appropriately adds and removes the
login item (and re-adds it if I manually remove it from system
settings).
Related: #8916
Related: #2306
---------
Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
When the MDM installs a configuration payload to
`dev.firezone.firezone.network-extension`, the tunnel service will now
be notified of a change to its `managedDict`, applying the configuration
and updating `packetTunnelProvider`'s local copy so that it'll be
returned on the next configuration fetch from the UI.
Related: #4505
For App Store installed macOS clients, it doesn't make sense to run an
update checker, because the system is managing the updates, and will
notify the user if there's an update available for Firezone (the user
has configured the system to manage app updates).
Related: #7664
Related: #4505
On macOS, after upgrading the client, the new system extension fails to
respond to IPC commands until it receives a `startTunnel` call. After
that, subsequent IPC calls will succeed across relaunches of the app.
To fix this, we introduce a dummy `startTunnel` call on macOS that
attempts to bring life into the System extension whenever we receive
`nil` configuration.
We also tidy up a few other things to make this easier to follow.
Fixes#9156Fixes#8476
---------
Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
The settings fields are getting tedious to manage individually, so a
helper class `Settings` is added which abstracts all of the view-related
logic applicable to user-defined settings.
When settings are saved, they are first applied to the `store`'s
existing Configuration, and then that configuration is saved via a new
consolidated IPC call `setConfiguration`.
`actorName` has been moved to a GUI-only cached store since it does not
need to live on `Configuration` any longer.
This greatly simplifies both the view logic and the IPC interface.
Notably, this does not handle the edge case where the configuration is
updated while the Settings window is open. That is saved for a later
time.