# Quick start

> Install and configure the Grovs iOS SDK in your app.

Source: https://docs.grovs.io/docs/sdk/ios/quick-start

Install the SDK, configure it at launch and open your first link on a device. Takes about ten minutes.

**Using an AI coding agent?**

Copy one prompt into Claude Code, Cursor or Copilot and it does these steps in your project.

```text
Add Grovs deep linking to this iOS app (example app: Medly).

1. Add the Swift package https://github.com/grovs-io/grovs-iOS.git (Up to Next Major Version from 3.1.0) and link the Grovs library to the app target. With CocoaPods, add pod 'Grovs', '~> 3.1' instead.
2. In application(_:didFinishLaunchingWithOptions:), call Grovs.configure(APIKey:useTestEnvironment:delegate:) with the key in GROVS_API_KEY. Set useTestEnvironment: true only in debug builds.
3. Forward incoming links with Grovs.handleSceneDelegate(...) from the SceneDelegate. Without a SceneDelegate, use Grovs.handleAppDelegate(...) from the AppDelegate.
4. Add the Associated Domains capability with applinks: entries for the production and test link domains (for example applinks:medly.sqd.link). Add the URL scheme set in the Grovs dashboard under SDK Setup → iOS.
5. Adopt GrovsDelegate and route grovsReceivedPayloadFromDeeplink(link:payload:tracking:) to the existing router.
6. Build, then list what you changed.

Docs: https://docs.grovs.io/docs/sdk/ios/quick-start.md
```

> **Note:** Upgrading? See [3.0 to 3.1](https://docs.grovs.io/docs/upgrade-guides/ios-3-1) or [2.x to 3.0](https://docs.grovs.io/docs/upgrade-guides/ios-3-0).

## Requirements

- iOS 13.0+
- Swift 5.9 (Xcode 15+)
- An app target. App extensions aren't supported.
- Your bundle ID and Apple App Prefix registered in the Grovs dashboard. See [How to Get the Apple App Prefix](https://docs.grovs.io/docs/how-to-guides/ios/apple-app-prefix).

## Installation

### Swift Package Manager

1. In Xcode, open **File → Add Package Dependencies…**
2. Enter `https://github.com/grovs-io/grovs-iOS.git`.
3. Choose **Up to Next Major Version** from `3.1.0`.
4. Add the **Grovs** library to your app target.

With a `Package.swift`:

```swift
dependencies: [
    .package(url: "https://github.com/grovs-io/grovs-iOS.git", from: "3.1.0")
],
targets: [
    .target(
        name: "YourApp",
        dependencies: [.product(name: "Grovs", package: "grovs-iOS")]
    )
]
```

### CocoaPods

Add to your `Podfile`:

```ruby
pod 'Grovs', '~> 3.1'
```

```bash
pod install
```

## Configuration

Configure the SDK in `application(_:didFinishLaunchingWithOptions:)`:

```swift
import Grovs

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Optional: verbose logging while integrating
    Grovs.setDebug(level: .info)

    Grovs.configure(APIKey: "your-api-key", useTestEnvironment: false, delegate: self) { success in
        if success {
            print("Grovs SDK is ready")
        }
    }

    // Optional: identify the user (after configure)
    Grovs.userIdentifier = "user_id_from_your_app"
    Grovs.userAttributes = ["name": "John Doe", "plan": "premium"]

    return true
}
```

> **Warning:** Set `userIdentifier` and `userAttributes` after `configure`. Earlier values are ignored and the SDK logs an error. A push token set earlier is held until `configure` runs. See [Push Notifications](https://docs.grovs.io/docs/sdk/ios/push-notifications).

### Configuration options

```swift
Grovs.configure(
    APIKey: String,
    useTestEnvironment: Bool,
    baseURL: String? = nil,
    autoTrackScreenViews: Bool = true,
    clipboardDomains: [String]? = nil,
    enabled: Bool = true,
    delegate: GrovsDelegate?,
    completion: GrovsBoolCompletion? = nil
)
```

| Parameter              | Default     | Description                                                                                                                                                                                               |
| ---------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `APIKey`               | Required    | Project API key from the Grovs dashboard.                                                                                                                                                                 |
| `useTestEnvironment`   | Required    | `true` targets the test environment (its own domain, links and data). `false` targets production. Use `true` only in development builds.                                                                  |
| `baseURL`              | Grovs cloud | Domain of a [self-hosted backend](https://docs.grovs.io/docs/self-hosting/configure/sdk-configuration), for example `"https://sdk.example.com"`. The SDK appends the API path.                            |
| `autoTrackScreenViews` | `true`      | Track screen views automatically. See [Events & Screen Tracking](https://docs.grovs.io/docs/sdk/ios/analytics#automatic-screen-tracking).                                                                 |
| `clipboardDomains`     | none        | Extra link hosts accepted by [clipboard-assisted deferred deep linking](https://docs.grovs.io/docs/sdk/ios/deep-linking#clipboard-assisted-deferred-deep-linking). Grovs-owned hosts are always accepted. |
| `enabled`              | `true`      | Whether the SDK may collect and send anything this launch. Pass your stored consent value; it isn't persisted. See [Privacy & Consent](https://docs.grovs.io/docs/sdk/ios/privacy).                       |
| `delegate`             | Required    | Receives deep link payloads and SDK errors. Held weakly. See [Deep Linking](https://docs.grovs.io/docs/sdk/ios/deep-linking#receiving-deep-link-events).                                                  |
| `completion`           | `nil`       | Called on the main thread with whether authentication succeeded. Returns `false` without authenticating when `enabled` is `false`.                                                                        |

Configure once per launch, on the main thread. Calling `configure` again replaces the previous configuration.

## Delegate setup

### Apps using SceneDelegate

Forward these calls to the SDK:

```swift
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    Grovs.handleSceneDelegate(openURLContexts: URLContexts)
}

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    Grovs.handleSceneDelegate(continue: userActivity)
}

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    Grovs.handleSceneDelegate(options: connectionOptions)
}
```

### Apps using AppDelegate only

Without a `SceneDelegate`, forward these calls instead:

```swift
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    return Grovs.handleAppDelegate(continue: userActivity, restorationHandler: restorationHandler)
}

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    return Grovs.handleAppDelegate(open: url, options: options)
}
```

Call `handleAppDelegate` methods on the main thread, where UIKit delivers these callbacks. `handleSceneDelegate` methods work from any thread.

## Next steps

- [Handle incoming deep links →](https://docs.grovs.io/docs/sdk/ios/deep-linking)
- [Generate smart links →](https://docs.grovs.io/docs/sdk/ios/link-creation)
- [Receive push campaigns →](https://docs.grovs.io/docs/sdk/ios/push-notifications)
- [Show in-app messages →](https://docs.grovs.io/docs/sdk/ios/in-app-messages)
- [Gate collection on user consent →](https://docs.grovs.io/docs/sdk/ios/privacy)
- [Explore the iOS example app →](https://github.com/grovs-io/grovs-ios-example-app)

## See also

- [How to Get the Apple App Prefix](https://docs.grovs.io/docs/how-to-guides/ios/apple-app-prefix): the Team ID the Grovs dashboard asks for
- [How to Get the Bundle Identifier](https://docs.grovs.io/docs/how-to-guides/ios/bundle-identifier): find it in Xcode
- [How to Add an Associated Domain](https://docs.grovs.io/docs/how-to-guides/ios/associated-domain): Universal Links setup in Xcode
- [How to Add a New URL Scheme](https://docs.grovs.io/docs/how-to-guides/ios/url-scheme): custom URL schemes for deep linking
- [iOS setup checklist](https://docs.grovs.io/docs/troubleshooting/ios-setup-checklist): verify the integration and test every deep link flow
- [Deep link not opening the app](https://docs.grovs.io/docs/troubleshooting/deep-link-not-opening-app): links open the browser instead of the app
- [SDK configuration issues](https://docs.grovs.io/docs/troubleshooting/sdk-configuration-issues): common setup and initialization problems
