Repository navigation
Swift Package Manager: .package(url: "https://github.com/grovs-io/grovs-iOS", from: "3.1.0")
CocoaPods: pod 'Grovs', '~> 3.1' (and pod 'GrovsNotificationService', '~> 3.1' in a Notification Service Extension)
Binary: Grovs.xcframework.zip below (device arm64, simulator arm64 + x86_64). SHA-256: 719a8fe13fa8de8a9379c6d7061c6f1ce3aee2d6f9ce06d81c5e465a7e6f177f
Upgrading from 3.0
3.1.0 is a minor release, but check these when upgrading:
GrovsErrorhas a new case,inAppDisplayFailed(5): an exhaustiveswitchover it no longer compiles
until the case is handled.GrovsDelegateis now an@objcprotocol with@objc optionalmethods, and the Swift default
implementation ofgrovsDidEncounterErroris gone. A method whose signature no longer matches compiles
with only a "nearly matches" warning and is never called; check those warnings.- The messages inbox is removed:
displayMessagesViewController(...)andnumberOfUnreadMessages(...)
are deprecated no-ops. - A push carrying only
grovs_notification_idis no longer a Grovs push:isGrovsNotification(userInfo:)
and the notification handlers returnfalsefor it. - Automatic screen tracking now tracks a view controller class named exactly
ViewController(or
Controller) under that name; before, its name was cleaned to nothing and it was never tracked. - More event names are reserved and refused by
track(_:), as the backend refuses them:push_open,
push_delivered,push_held,in_app_held,journey_entered,journey_heldandjourney_path,
besides the in-app names below. - Call
handleNotificationOpen(userInfo:)only for a tap on a notification, never from
didReceiveRemoteNotificationorwillPresent, or each delivery counts as an open.
Added
- In-app messages: campaigns made in the dashboard are synced to the device, decided there and shown
in a window above the app.Grovs.inApppauses, resumes, discards and excludes screens, and
reports shown, clicked and dismissed messages to the host. - In-app questions: a message can ask for a star rating (1 to 5) or one choice from a list. One tap answers; a comment box (up to 500 characters, Send or Skip) and a thanks text may
follow, and a star rating high enough can be followed by the system's review prompt. An answered
campaign is not shown again on the device.GrovsInAppDelegate.grovsDidAnswerInAppMessage(campaignID:value:comment:)
is called in place of the dismissal; like everyGrovsInAppDelegatemethod it is optional. The event names
in_app_answeredandin_app_commentedare reserved and cannot be tracked by the host app. - In-app test messages: a message sent with "Send test" in the dashboard shows at the next sync,
once the screen is free and messages are not paused. It is not counted or reported. GrovsError.inAppDisplayFailed(5): a message could not be drawn. An exhaustiveswitchover
GrovsErrorneeds the new case.- Push campaigns:
Grovs.handleNotificationResponse(_:)/handleNotificationOpen(userInfo:)
report opens (POST /sdk/push_open) and deliver the push through the deep-link delegate:
its data (userInfowithoutaps), merged over its link's payload when it has a link.
Only a tap on the notification counts, not a dismissal or a custom action. Taps before
configureor before authentication succeeds are held (a tap held before
configure(enabled: false)is dropped), and an open that fails to report is retried on
the next foreground, up to 3 attempts.Grovs.isGrovsNotification(userInfo:),
Grovs.setPushToken(deviceToken:). A push token set beforeconfigureis held until then. GrovsNotificationServiceproduct (SPM and pod) for Notification Service Extensions:
attachesgrovs_image(JPEG, PNG or GIF; other formats are skipped), and can add it to
content other code has already changed. The download is cancelled when
the extension's time runs out.
Removed
- The messages inbox screens and the automatic display of dashboard messages. The SDK no longer
calls the inbox endpoints, ships no XIB, and no longer treats a push carrying only
grovs_notification_idas a Grovs push. Use in-app messages instead.
Deprecated
Grovs.displayMessagesViewController(completion:)and
displayMessagesViewController(completion:onFailure:)show nothing: they callcompletion
once on the main thread and never callonFailure.Grovs.numberOfUnreadMessages(completion:)always yields0, on the main thread.
Fixed
- In-app: a message keeps the status bar hidden when the app hides it; the app's window gets the
keyboard back after a comment; on iPad the scene holding the key window is used and the orientation
follows the window's shape; a return to the app syncs at most once a minute (a campaign change still
syncs at once); a message still waiting when the session ends is dropped; what waits is shown after a
link, the store, a rating or push permission prompt when the app is still in front; the state is written at most twice a
second and on going to the background. GrovsNotificationServiceExtensiondelivers each push to its own handler when the system reuses
one extension instance for several pushes.- The privacy manifest declares the file timestamp reason (C617.1) for the SDK's disk cache.
- A push token set before authentication no longer clears the user's identifier and
attributes on the server: the server's values are kept for fields the app hasn't set.
Changed
- A tap on a push that carries a Grovs link counts once, as
push_open: the link is resolved with
source: push, so it no longer counts as a link open, and later events are not attributed to the link. Grovs.podspeccompiles onlySources/Grovs; the extension code ships in its own pod.scripts/run_tests.shruns theGrovs-Packagescheme (a second library product moves
the tests out of theGrovsscheme).GrovsDelegateandGrovsInAppDelegateare@objcprotocols with@objc optionalmethods, so
Objective-C apps can adopt them;GrovsErroris an@objcenum andGrovsanNSObject.
Source-compatible for most apps, but the Swift default implementations are gone: a method whose
signature no longer matches compiles with only a "nearly matches" warning and is never called.
Check those warnings when upgrading.grovsDidDismissInAppMessage(campaignID:reason:)can reportorientation: the device turned to an
orientation the campaign does not allow. It is not counted as a dismissal in the dashboard.- In-app HTML:
grovs.open()(and a link) opens only within 2 seconds of a tap in the message;
later, for example after a slow network call, it is ignored.