Listen for favorite/unfavorite events
The super app can listen for the favorite and unfavorite events to trigger custom logic when a user adds or removes a mini program from their favorites. These events are tied to a favorite/unfavorite button, which can appear in the following locations:
- The title bar
- The more menu
For a visual reference, refer to the following image:

To listen for these events and customize the handling logic, the super app must implement the GRVCollectEventDelegate protocol. This guide covers the default user experience, implementation steps, and protocol details.
Before you begin
To listen for the favorite and unfavorite events, ensure that the integrated iOS IAPMiniProgram SDK is version 2.65.3 or later. For more information, see SDK release notes.
Default user experience
By default, a toast message appears to confirm the user's action when they click a favorite/unfavorite button. Refer to the following table for UI examples:
Favorite a mini program | Unfavorite a mini program | Error |
|
|
|
Procedure
To listen for favorite and unfavorite events, take the following two steps:
Step 1: Implement the GRVCollectEventDelegate protocol
Define a class that implements the GRVCollectEventDelegate protocol. Within the class, optionally implement its defined methods to customize event handling. Refer to the following code for a sample implementation. For more information about the protocol and the methods, refer to GRVCollectEventDelegate.
class DemoCollectEventDelegate: NSObject, GRVCollectEventDelegate {
func statusWillChange(_ scene: GRVCollectScene, isCollected: Bool, continueCallback: @escaping GRVCollectEventDispositionBlock, cancelCallback: @escaping GRVCollectEventDispositionBlock) {
// Customize logic to approve or block the favorite/unfavorite action
// Call continueCallback() to proceed or cancelCallback() to block
}
func statusDidChanged(_ scene: GRVCollectScene, isCollected: Bool) {
// Customize logic to handle successful favorite/unfavorite actions
// Example: Show a custom confirmation message
}
func statusChangedError(_ scene: GRVCollectScene, error: any Error) {
// Customize logic to handle errors
// Example: Display an error alert
}
}Step 2: Configure the collectEventDelegate property
After initializing the SDK, create an instance of GRVExtensionDelegate and assign the implementation (for example, DemoCollectEventDelegate in the sample) to the delegate's collectEventDelegate property. Refer to the following sample configuration code:
let extensionDelegate = GRVExtensionDelegate()
extensionDelegate.collectEventDelegate = DemoCollectEventDelegate();Structures
GRVCollectEventDelegate protocol
The GRVCollectEventDelegate protocol defines methods to handle favorite and unfavorite events in different UI contexts. It allows custom logic execution both before and after the action. Refer to the following code for the protocol definition:
typedef NS_ENUM(NSUInteger, GRVCollectScene) {
GRVCollectSceneTitleBar,
GRVCollectSceneMoreMenu,
};
typedef NS_ENUM(NSUInteger, GRVCollectErrorCode) {
GRVErrorCodeCollectReachedLimit = -1
};
FOUNDATION_EXPORT NSErrorDomain const NSErrorDomainCollectReachedLimit;
typedef void(^GRVCollectEventDispositionBlock)(void);
@protocol GRVCollectEventDelegate<NSObject>
@optional
- (void)statusWillChange:(GRVCollectScene)scene
isCollected:(bool)isCollected
continueCallback:(GRVCollectEventDispositionBlock)continueCallback
cancelCallback:(GRVCollectEventDispositionBlock)cancelCallback;
- (void)statusDidChanged:(GRVCollectScene)scene isCollected:(bool)isCollected;
- (void)statusChangedError:(GRVCollectScene)scene error:(NSError *)error;
@endThe following table lists the details of the defined methods:
Method | Description |
statusWillChange:isCollected:continueCallback:cancelCallback: | Called by the SDK when the user taps the favorite/unfavorite button. Implement this method if you need to conditionally allow or block the operation (e.g., ask for user confirmation before execution). For more information, refer to |
statusDidChanged:isCollected: | Called by the SDK after a successful favorite/unfavorite action. Implement this method if you need to customize the logic to handle success. For more information, refer to |
statusChangedError:error: | Called by the SDK when the favorite/unfavorite action fails. Implement this method if you need to customize the logic to handle errors. For more information, refer to |
statusWillChange:isCollected:continueCallback:cancelCallback: method
Parameters
This method has the following input parameters:
Parameter | Data type | Required | Description |
scene | GRVCollectScene | Yes | The UI context where the event occurs. Valid values are:
|
isCollected | BOOL | Yes | The user's intended action. Valid values are:
|
continueCallback | Function | Yes | A callback to execute if you need to proceed with the user's intended action. |
cancelCallback | Function | Yes | A callback to execute if you need to cancel the user's intended action. |
statusDidChanged:isCollected: method
Parameters
This method has the following input parameters:
Parameter | Data type | Required | Description |
scene | GRVCollectScene | Yes | The UI context where the event occurs. Valid values are:
|
isCollected | BOOL | Yes | The current favoriting status of the mini program. Valid values are:
|
statusChangedError:error: method
Parameters
This method has the following input parameters:
Parameter | Data type | Required | Description |
scene | GRVCollectScene | Yes | The UI context where the event occurs. Valid values are:
|
error | NSError | Yes | The error details. For more information, refer to Error codes. |
Error codes
Error code | Code name | Error message | Further action |
-1 | GRVErrorCodeCollectReachedLimit | operation.message.favorityMax | The error occurs because the user has favorited too many mini programs. A possible solution is to prompt users to remove some favorites. |


