Quick start
Install and configure the Grovs iOS SDK in your app.
Install the SDK, configure it at launch and open your first link on a device. Takes about ten minutes.
Copy one prompt into Claude Code, Cursor or Copilot and it does these steps in your project.
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
Upgrading? See 3.0 to 3.1 or 2.x to 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.
Installation
Swift Package Manager
- In Xcode, open File → Add Package Dependencies…
- Enter
https://github.com/grovs-io/grovs-iOS.git. - Choose Up to Next Major Version from
3.1.0. - Add the Grovs library to your app target.
With a Package.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:
pod 'Grovs', '~> 3.1'pod installConfiguration
Configure the SDK in application(_:didFinishLaunchingWithOptions:):
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
}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.
Configuration options
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, for example "https://sdk.example.com". The SDK appends the API path. |
autoTrackScreenViews | true | Track screen views automatically. See Events & Screen Tracking. |
clipboardDomains | none | Extra link hosts accepted by 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. |
delegate | Required | Receives deep link payloads and SDK errors. Held weakly. See Deep Linking. |
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:
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:
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 →
- Generate smart links →
- Receive push campaigns →
- Show in-app messages →
- Gate collection on user consent →
- Explore the iOS example app →
See also
- How to Get the Apple App Prefix: the Team ID the Grovs dashboard asks for
- How to Get the Bundle Identifier: find it in Xcode
- How to Add an Associated Domain: Universal Links setup in Xcode
- How to Add a New URL Scheme: custom URL schemes for deep linking
- iOS setup checklist: verify the integration and test every deep link flow
- Deep link not opening the app: links open the browser instead of the app
- SDK configuration issues: common setup and initialization problems