v2 replaces the embedded WebView sign-in flow with
ASWebAuthenticationSession
on iOS. The authentication UI now runs in the system browser context, which enables
WebAuthn/passkey sign-in, follows the native-app OAuth guidance in
RFC 8252, and shares the browser
session by default.
v2 also revamps sign-out to distinguish a complete browser sign-out from a local credential clear, and removes the native social plugin targets that relied on the embedded WebView flow.
In v1, the SDK handled the OAuth redirect inside the embedded WebView. In v2,
ASWebAuthenticationSession matches the callback through the redirect URI, so your
app must be configured to receive the URI you pass to signInWithBrowser.
For a custom scheme such as io.logto.app://callback:
- Register the scheme in your app's
Info.plist. Register only the scheme part, not the full redirect URI. Forio.logto.app://callback, the scheme isio.logto.app. - Add the same URI to your Logto application's Redirect URIs.
- Pass the same URI to
signInWithBrowser.
In Xcode, open your app target, select Info, expand URL Types, and add
one entry with io.logto.app in URL Schemes. If you edit Info.plist
directly, add:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>io.logto.app</string>
<key>CFBundleURLSchemes</key>
<array>
<string>io.logto.app</string>
</array>
</dict>
</array>try await logtoClient.signInWithBrowser(
redirectUri: "io.logto.app://callback"
)For the browser flow in v2, you do not need to call LogtoClient.handle(url:);
that plugin handoff API was removed with the embedded WebView flow.
Custom scheme callbacks can be matched and dismissed automatically on all supported iOS versions.
You can also use an HTTPS redirect URI such as https://example.com/callback:
- Add the Associated Domains capability to your app.
- Configure
webcredentials:example.comsoASWebAuthenticationSessioncan match HTTPS callbacks on iOS 17.4 and newer. - If the same URL should open your app outside the authentication session, also
configure
applinks:example.comand host a validapple-app-site-associationfile. - Add the HTTPS URI to your Logto application's Redirect URIs.
- Pass the same URI to
signInWithBrowser.
On iOS 17.4 and newer, the SDK uses ASWebAuthenticationSession's HTTPS callback
API so HTTPS redirects can automatically complete and dismiss the session. On older
iOS versions, the authorization request can still use the HTTPS redirect URI, but
the session may not close automatically unless your app handles the Universal Link
callback itself. Keep a custom scheme redirect as a compatibility option if you
need automatic completion on older iOS versions.
The signInWithBrowser(redirectUri:) API is still the main sign-in entry point:
try await logtoClient.signInWithBrowser(
redirectUri: "io.logto.app://callback"
)The visible behavior changes because the flow now uses ASWebAuthenticationSession:
- iOS may show a system consent prompt before opening the browser session. The prompt text is controlled by the system.
- Browser cookies are shared by default, so users may get single sign-on behavior across the app and the system browser.
- To request an isolated browser session, set
prefersEphemeralWebBrowserSession: trueinLogtoConfig. - The app can no longer inspect the page, inject JavaScript, or rely on WebView-only behavior during authentication.
ID token verification now tolerates a clock drift of up to 300 seconds between the
device and the Logto server (v1 allowed 60 seconds), and the tolerance also applies to
the exp claim. This matches the default of the Logto JS SDK. Devices whose clock
drifts by more than the tolerance still fail sign-in, with
LogtoErrors.Verification.jwtIssuedTimeIncorrect or LogtoErrors.Verification.jwtExpired.
These errors are now public, so your app can tell the user to check the device clock.
The tolerance is configurable in seconds through the new idTokenVerification option:
let config = try LogtoConfig(
endpoint: "<your-logto-endpoint>",
appId: "<your-app-id>",
idTokenVerification: IdTokenVerificationOptions(clockTolerance: 600)
)LogtoConfig throws LogtoClientErrors.Config.invalidClockTolerance if the tolerance
is not a positive number of seconds.
The native social plugin products and targets are removed:
LogtoSocialPluginLogtoSocialPluginWebLogtoSocialPluginAlipayLogtoSocialPluginWechat
The socialPlugins parameter in LogtoClient initialization and the
LogtoClient.handle(url:) / notification-based plugin handoff are also removed.
Social connectors still work through the browser, like on the web. If you depend on the native WeChat or Alipay SDK handoff, stay on the v1 line.
In v1, signOut() cleared local credentials and tried to revoke the refresh token.
It did not end the Logto session cookie because that cookie lived inside the
embedded WebView flow.
In v2, that local-only behavior is renamed to clearCredentials(), and
signOut(postLogoutRedirectUri:) is a browser-based sign-out that also opens the
Logto end session endpoint.
Use this when you have a Post sign-out redirect URI registered in the Logto console. The URI can be a custom scheme or an HTTPS Universal Link. It must also be configured for your iOS app as described above.
let error = await logtoClient.signOut(
postLogoutRedirectUri: "io.logto.app://signed-out"
)This clears local credentials, tries to revoke the refresh token, opens the Logto
end session endpoint in ASWebAuthenticationSession, and lets Logto navigate back
to the app through the post sign-out redirect URI.
Use this when you want to end the Logto browser session but do not have a Post sign-out redirect URI. The browser session stays on the Logto sign-out page and the user returns by dismissing it manually.
let error = await logtoClient.signOut()Dismissing the browser during sign-out is treated as success. Local credentials have already been cleared before the browser opens, and token revocation has already settled.
Use this when no UI context is available, such as a background error handler, or when you intentionally only want to clear local state.
let error = await logtoClient.clearCredentials()This is v1's signOut() behavior: it clears local credentials and tries to revoke
the refresh token, but it does not open the browser and does not end the Logto
session cookie. The next sign-in may silently re-enter the same account through the
browser session. Prefer browser signOut when the user explicitly taps a sign-out
button.
clearCredentials()and browsersignOutreturnLogtoClientErrors.SignOut?.nilmeans the local sign-out completed successfully.- Token revocation and remote browser sign-out are best effort. If revocation fails, local credentials are still cleared and the revoke error is returned.
- An invalid
postLogoutRedirectUrireturns.invalidRedirectUriwith no side effects. Credentials stay intact so the caller can fix the URI and retry a complete sign-out. - If the browser callback URI does not match the expected post sign-out redirect
URI, the SDK returns
.unexpectedSignOutCallback. - If the browser session cannot start, the SDK returns
.unableToLaunchBrowser.
Browser sign-in and browser sign-out are currently available on iOS. On non-iOS
platforms, use clearCredentials() for local credential clearing.
v2 is released through Git tags. Select 2.0.0 or a later 2.x version when adding
the package in Swift Package Manager or Xcode. The 2.0.0-beta.x prereleases are
superseded by the stable release.