diff --git a/src/content/docs/developer-tools/sdks/native/ios-sdk.mdx b/src/content/docs/developer-tools/sdks/native/ios-sdk.mdx
index 730277240..7e5a54789 100644
--- a/src/content/docs/developer-tools/sdks/native/ios-sdk.mdx
+++ b/src/content/docs/developer-tools/sdks/native/ios-sdk.mdx
@@ -81,6 +81,46 @@ If you would like to use our Environments feature as part of your development pr
## Configuring your app
+### Custom URL Scheme
+
+Register a custom URL scheme using one of these methods:
+
+
+
+
+
+1. Open your project in Xcode and select the project in the navigator.
+2. Under **Targets**, select your app target.
+3. Open the **Info** tab, expand **URL Types**, and select **+** to add a URL type.
+4. Set **Role** to **Editor**.
+5. Add `` to **URL Schemes**.
+
+
+
+
+
+Open your app target's `Info.plist` and add the following inside the top-level ``:
+
+```xml title="Info.plist"
+CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLSchemes
+
+ YOUR_URL_SCHEME
+
+
+
+```
+
+
+
+
+
+For more information, see Apple's [Defining a custom URL scheme for your app](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app).
+
### **Environment variables**
The Kinde `Auth` service is configured with an instance of the `Config` class. The example uses the bundled `kinde-auth.json` for configuration.
@@ -116,24 +156,47 @@ Replace the values in \ with your own values. For example:
## Integrate with your app
-Before `KindeSDKAPI.auth` can be used, a call to `KindeSDKAPI.configure()` must be made, typically in `AppDelegate` as part of `application(launchOptions)` for a UIKit app, or the `@main` initialization logic for a SwiftUI app.
+Before using `KindeSDKAPI.auth` or other Kinde SDK APIs, call `KindeSDKAPI.configure()` during app initialization.
-`AppDelegate.swift`
+### SwiftUI
-```swift
-...
-import KindeSDK
-...
+Initialize Kinde in the `init()` of your `@main` app.
+
+```diff lang="swift" title="MyApp.swift"
+import SwiftUI
++import KindeSDK
+
+@main
+struct MyApp: App {
+ init() {
++ KindeSDKAPI.configure()
+ }
+
+ var body: some Scene {
+ WindowGroup {
+ ContentView()
+ }
+ }
+}
+```
+
+### UIKit
+
+For UIKit apps both with and without a scene delegate, you can initialize Kinde in your app delegate's `application(_:didFinishLaunchingWithOptions:)` method.
+
+```diff lang="swift" title="AppDelegate.swift"
+import UIKit
++import KindeSDK
class AppDelegate: UIResponder, UIApplicationDelegate {
- ...
- func application(...) {
- ...
- // The Kinde authentication service must be configured before use
- KindeSDKAPI.configure(Logger())
- ...
- }
- ...
+ func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions:
+ [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
++ KindeSDKAPI.configure()
+ return true
+ }
}
```
@@ -192,29 +255,38 @@ To switch to a different environment, simply change the configuration file name
## Custom Logger (Optional)
-You can use your own Custom Logger as well by extending `LoggerProtocol`.
+Calling `KindeSDKAPI.configure()` without a logger uses the SDK's `DefaultLogger`.
-`CustomLogger.swift`
+To customize logging, create a type that conforms to `LoggerProtocol`:
-```swift
-...
-import os.log
+```swift title="CustomLogger.swift"
import KindeSDK
-...
+
struct CustomLogger: LoggerProtocol {
-.....
-.....
+ func debug(message: String) {
+ print("[DEBUG]: \(message)")
+ }
- func log(_ message: String) {
- print("[INFO]: \(message)")
- }
+ func info(message: String) {
+ print("[INFO]: \(message)")
+ }
- func log(error: Error) {
- print("[ERROR]: \(error.localizedDescription)")
- }
+ func error(message: String) {
+ print("[ERROR]: \(message)")
+ }
+
+ func fault(message: String) {
+ print("[FAULT]: \(message)")
+ }
}
```
+During [app initialization](#integrate-with-your-app), pass your custom logger to `KindeSDKAPI.configure()`:
+
+```swift
+KindeSDKAPI.configure(CustomLogger())
+```
+
## Login and register
The Kinde client provides methods for an easy to implement login / register flow.
@@ -526,6 +598,183 @@ KindeSDKAPI.auth.getUserOrganizations();
For more information about how organizations work in Kinde, see [Kinde organizations for developers](/build/organizations/orgs-for-developers/).
+## Invitation
+
+The SDK can start the invitation sign-up flow when your app is opened via a URL containing an `invitation_code` query parameter.
+
+For example, `com.example.App://login?invitation_code=abc123` for an [Application login URI](/build/applications/default-login-routes/#to-set-default-login-routes) of `com.example.App://login` and an invitation code of `abc123`.
+
+To support the invitation sign-up flow in your iOS app, use one of the following methods:
+
+
+
+
+
+ To make the SDK automatically intercept your invitation code URLs, set `KindeURLInterceptorEnabled` to `true` in your app's `Info.plist`.
+
+ ```xml title="Info.plist"
+ KindeURLInterceptorEnabled
+
+ ```
+
+ The SDK then uses [method swizzling](https://nshipster.com/method-swizzling/) to intercept incoming invitation URLs in your app delegate and scene delegate callbacks.
+
+
+ Delegate methods swizzled for URL interception
+
+ **App delegate**
+
+ - `application(_:open:options:)`
+ - `application(_:continue:restorationHandler:)`
+
+ **Scene delegate**
+
+ - `scene(_:willConnectTo:options:)`
+ - `scene(_:openURLContexts:)`
+ - `scene(_:continue:)`
+
+
+
+ This is disabled by default and is only used when you set the `KindeURLInterceptorEnabled` flag to `true`.
+
+
+
+
+
+ To manually handle incoming URLs:
+
+ - Ensure `KindeURLInterceptorEnabled` is unset or set to `false` in your app's `Info.plist`.
+
+ ```xml title="Info.plist"
+ KindeURLInterceptorEnabled
+
+ ```
+
+ - Forward your app's incoming URLs to `KindeSDKAPI.handle(url:)` from your app's URL-handling callbacks.
+
+ Choose the approach that matches your app's setup.
+
+
+
+
+
+ Handle incoming custom-scheme URLs and universal links using `.onOpenURL`, forwarding them to `KindeSDKAPI.handle(url:)`.
+
+ ```diff lang="swift" title="MyApp.swift"
+ import SwiftUI
+ import KindeSDK
+
+ @main
+ struct MyApp: App {
+ var body: some Scene {
+ WindowGroup {
+ ContentView()
+ + .onOpenURL { url in
+ + KindeSDKAPI.handle(url: url)
+ + }
+ }
+ }
+ }
+ ```
+
+
+
+
+
+ Handle custom-scheme URLs in `application(_:open:options:)` and universal links in `application(_:continue:restorationHandler:)`.
+
+ ```diff lang="swift" title="AppDelegate.swift"
+ import UIKit
+ import KindeSDK
+
+ class AppDelegate: UIResponder, UIApplicationDelegate {
+ func application(
+ _ application: UIApplication,
+ open url: URL,
+ options: [UIApplication.OpenURLOptionsKey: Any] = [:]
+ ) -> Bool {
+ + return KindeSDKAPI.handle(url: url)
+ }
+
+ func application(
+ _ application: UIApplication,
+ continue userActivity: NSUserActivity,
+ restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
+ ) -> Bool {
+ + guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
+ + let url = userActivity.webpageURL else {
+ + return false
+ + }
+ +
+ + return KindeSDKAPI.handle(url: url)
+ }
+ }
+ ```
+
+
+
+
+
+ In the scene delegate, handle incoming URLs when a scene connects in `scene(_:willConnectTo:options:)`, and subsequent URLs in `scene(_:openURLContexts:)` for custom schemes and `scene(_:continue:)` for universal links.
+
+ ```diff lang="swift" title="SceneDelegate.swift"
+ import UIKit
+ +import KindeSDK
+
+ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
+ var window: UIWindow?
+
+ func scene(
+ _ scene: UIScene,
+ willConnectTo session: UISceneSession,
+ options connectionOptions: UIScene.ConnectionOptions
+ ) {
+ guard let _ = (scene as? UIWindowScene) else { return }
+
+ + if let context = connectionOptions.urlContexts.first {
+ + KindeSDKAPI.handle(url: context.url)
+ + }
+ +
+ + if let activity = connectionOptions.userActivities.first(where: {
+ + $0.activityType == NSUserActivityTypeBrowsingWeb
+ + }), let url = activity.webpageURL {
+ + KindeSDKAPI.handle(url: url)
+ + }
+ }
+
+ func scene(
+ _ scene: UIScene,
+ openURLContexts URLContexts: Set
+ ) {
+ + guard let url = URLContexts.first?.url else {
+ + return
+ + }
+ +
+ + KindeSDKAPI.handle(url: url)
+ }
+
+ func scene(
+ _ scene: UIScene,
+ continue userActivity: NSUserActivity
+ ) {
+ + guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
+ + let url = userActivity.webpageURL else {
+ + return
+ + }
+ +
+ + KindeSDKAPI.handle(url: url)
+ }
+ }
+ ```
+
+
+
+
+
+
+
+
+
## Feature flags
We have provided a helper to return any features flag from the access token: