Évènement in-app

Découvrez comment utiliser avec les événements in-app dans le SDK iOS.

Vue d'ensemble

Ce document vous guide dans l'implémentation des événements in-app dans le SDK iOS. Pour obtenir une introduction aux événements in-app à l'attention des développeurs, consultez les Événements in-app.

Avant de commencer

Vous devez intégrer le SDK.

Logging des événements in-app

Le SDK vous permet de consigner les actions que les utilisateurs effectuent dans le contexte de votre application. Ces événements sont plus connus sous le nom de événements in-app.

The logEvent method

The logEvent method lets you log in-app events and send them to AppsFlyer for processing.

AppsFlyerLib exposes logEvent, predefined event name constants and predefined event parameter constants.

logEvent prend 3 arguments :

- (void)logEventWithEventName:(NSString *)eventName
        eventValues:(NSDictionary<NSString * , id> * _Nullable)eventValues
        completionHandler:(void (^ _Nullable)(NSDictionary<NSString *, id> * _Nullable dictionary, NSError * _Nullable error))completionHandler;
  • The first argument (eventName) is the event name
  • The second argument (eventValues) is the event parameters NSDictionary
  • The third argument (completionHandler) is an optional completion handler (useful for Handling event submission success/failure)

📘

Remarque

eventValues (second argument) must be a valid NSDictionary. For more information, see Foundation JSONSerialization.

Example: Send "add to wishlist" event

Par exemple, pour enregistrer le fait qu'un utilisateur a ajouté un article à sa liste d'envies  :

[[AppsFlyerLib shared]  logEvent: AFEventAddToWishlist withValues: @{
    AFEventParamPrice: @20,
    AFEventParamContentId: @"123456"
}]
AppsFlyerLib.shared().logEvent(AFEventAddToWishlist,
  withValues: [
     AFEventParamPrice: 20,
     AFEventParamContentId: "123456"
]);

In the above logEvent invocation:

Implementing in-app event definitions

D'après l'exemple de définition détaillé dans Comprendre les définitions de structure d'événement, l'événement doit être implémenté comme suit :

[[AppsFlyerLib shared]  logEvent: AFEventContentView withValues: @{
    AFEventParamContentId: <ITEM_SKU>,
    AFEventParamContentType: <ITEM_TYPE>,
    AFEventParamPrice: <ITEM_PRICE>
}]
AppsFlyerLib.shared().logEvent(AFEventAddToCart,
  withValues: [
    AFEventParamContent: <ITEM_NAME>
    AFEventParamContentId: <ITEM_SKU>
    AFEventParamPrice: <ITEM_PRICE>
]);

Handling event submission success and failure

You can pass a completionHandler to logEvent when recording in-app events. The handler allows you to define logic for two scenarios:

  • Événement in-app enregistré avec succès
  • Une erreur s'est produite lors de l'enregistrement de l'événement in-app
[[AppsFlyerLib shared] logEventWithEventName:AFEventPurchase
        eventValues: @{
          AFEventParamRevenue: @200,
          AFEventParamCurrency: @"USD",
          AFEventParamQuantity: @2,
          AFEventParamContentId: @"092",
          AFEventParamReceiptId: @"9277"
        }
        completionHandler:^(NSDictionary<NSString *,id> * _Nullable dictionary, NSError * _Nullable error){
            if(dictionary != nil) {
                NSLog(@"In app callback success:");
                for(id key in dictionary){
                    NSLog(@"Callback response: key=%@ value=%@", key, [dictionary objectForKey:key]);
                }
            }
            if(error != nil) {
                NSLog(@"In app callback error:", error);
            }
    }];
AppsFlyerLib.shared().logEvent(name: AFEventAddToWishlist,
          values: [
             AFEventParamPrice: 20,
             AFEventParamContentId: "123456"
          ],
          completionHandler: { (response: [String : Any]?, error: Error?) in
            if let response = response {
              print("In app event callback Success: ", response)
            }
            if let error = error {
              print("In app event callback ERROR:", error)
            }
          });

En cas d'erreur lors de l'enregistrement de l'événement in-app, un code d'erreur et une description de la chaîne sont fournis, comme indiqué dans le tableau qui suit.

Code d'erreurDescription (NSError)
10"Event timeout. (« Délai de l'événement ») Vérifiez 'minTimeBetweenSessions' param"
11"Skipping event because 'isStopTracking' enabled" (« Sauter l'événement car isStopTracking est activé »)
40Network error: Error description comes from iOS
41"No dev key" (« Pas de clé de développement »)
50« Status code failure » + code correspondant à la réponse du serveur

Recording offline events

Le SDK peut enregistrer les événements in-app qui ont lieu lorsqu'il n'y a pas de connexion Internet. Consultez l'article Événements in-app hors ligne pour plus en savoir plus.

Logging events before calling start

If you initialized the SDK but didn't call start, the SDK will cache in-app events until start is invoked.

S'il y a plusieurs événements dans le cache, ils sont envoyés au serveur les uns après les autres (détachés, une requête réseau par événement).

📘

Remarque

If the SDK is initialized, logEvent invocations will call SKAdNetwork's updateConversionValue even if start wasn't called or isStopped is set to true (in both SDK and S2S modes).

Logging de revenu

af_revenue is the only event parameter that AppsFlyer counts as real revenue in the dashboard and reports.
You can send revenue with any in-app event. Use the AFEventParameterRevenue constant to include revenue in the in-app event. You can populate it with any numeric value, positive or negative.

La valeur de revenu ne doit pas contenir de séparateurs sous forme de virgules, de symbole monétaire ou de texte. Un événement de revenu doit être similaire à 1234.56, par exemple.

Example: Purchase event with revenue

[[AppsFlyerLib shared] logEvent: AFEventPurchase 
withValues:@{
	AFEventParamContentId:@"1234567",
	AFEventParamContentType : @"category_a",
	AFEventParamRevenue: @200,
	AFEventParamCurrency:@"USD"
}];
AppsFlyerLib.shared().logEvent(AFEventPurchase, 
withValues: [
	AFEventParamContentId:"1234567",
	AFEventParamContentType : "category_a",
	AFEventParamRevenue: 200,
	AFEventParamCurrency:"USD"
]);

📘

Remarque

N'inscrivez pas de devise après la valeur du revenu.

Configuring revenue currency

You can set the currency code for an event's revenue by using the af_currency predefined event parameter:

[[AppsFlyerLib shared] logEvent: AFEventPurchase
withValues:@{
	AFEventParamRevenue: @200,
	AFEventParamCurrency:@"USD"
}];
AppsFlyerLib.shared().logEvent(AFEventPurchase, 
withValues: [
	AFEventParamRevenue: 200,
	AFEventParamCurrency:"USD"
]);
  • Le code de devise doit être un code ISO 4217 à 3 caractères.
  • La devise par défaut est USD

Pour en savoir plus sur les paramètres de devise, l'affichage et la conversion de devise, consultez notre guide sur la devise du revenu.

Logging negative revenue

Dans certaines situations, vous voudrez peut-être enregistrer un revenu négatif. Par exemple, si l'utilisateur reçoit un remboursement ou annule un abonnement.

Pour loguer un revenu négatif :

[[AppsFlyerLib shared] logEvent: @"cancel_purchase" 
withValues:@{
	AFEventParamContentId:@"1234567",
	AFEventParamContentType : @"category_a",
	AFEventParamRevenue: @-1.99,
	AFEventParamCurrency:@"USD"
}];
AppsFlyerLib.shared().logEvent("cancel_purchase", 
withValues: [
	AFEventParamContentId:"1234567",
	AFEventParamContentType : "category_a",
	AFEventParamRevenue: -1.99,
	AFEventParamCurrency:"USD"
]);

Dans le code ci-dessus vous remarquerez ceci :

  • La valeur du revenu est précédée du signe moins
  • The event name is a custom event called cancel_purchase - that's how the marketer identifies negative revenue events in the dashboard and raw-data reports

Validation des achats

AppsFlyer provides server verification for in-app purchases. The validateAndLogInAppPurchase method takes care of validating and logging the purchase event.

📘

Remarque

The legacy function validateAndLogInAppPurchase can be replaced by the newer and fully automatic purchase SDK connector. To learn how to integrate the connector, see in Github iOS purchase SDK connector

Purchase validation using validateAndLogInAppPurchase

validateAndLoginInAppPurchase prend ces arguments :

- (void) validateAndLogInAppPurchase:(NSString *) productIdentifier,
                  price:(NSString *) price
                  currency:(NSString *) currency
                  transactionId:(NSString *) tranactionId
                  additionalParameters:(NSDictionary *) params
                  success:(void (^)(NSDictionary *response)) successBlock
                  failure:(void (^)(NSError *error, id reponse)) failedBlock;
validateAndLog(inAppPurchase: String?,
               price: String?,
               currency: String?,
               transactionId: String?,
               additionalParameters: [AnyHashable : Any]?,
               success: ([AnyHashable : Any]) -> Void)?,
               failure: ((Error?, Any?) -> Void)?)

Upon successful validation, a NSDictionary is returned with the receipt validation data (provided by Apple servers).

📘

Remarque

Calling validateAndLogInAppPurchase generates an af_purchase in-app event upon successful validation. Sending this event yourself creates duplicate event reporting.

Example: Validate in-app purchase

[[AppsFlyerLib shared] validateAndLogInAppPurchase:@"ProductIdentifier" price:@"price"
    currency:@"USD"
    transactionId:@"transactionID"
    additionalParameters:@{@"test": @"val" , @"test1" : @"val 1"}
    success:^(NSDictionary *result){
      NSLog(@"Purchase succeeded And verified! response: %@", result[@"receipt"]);
    } failure:^(NSError *error, id response) {
      NSLog(@"response = %@", response);
      if([response isKindOfClass:[NSDictionary class]]) {
        if([response[@"status"] isEqualToString:@"in_app_arr_empty"]){
          // retry with 'SKReceiptRefreshRequest' because
          // Apple has returned an empty response
          // <YOUR CODE HERE>
        }

      } else {
        //handle other errors
        return;
      }
  }];
AppsFlyerLib.shared().validateAndLogInAppPurchase (
  inAppPurchase: "productIdentifier",
  price: "price",
  currency: "currency",
  transactionId: "transactionId",
  additionalParameters: [:],
  success: {
      guard let dictionary = $0 as? [String:Any] else { return }
      dump(dictionary)
    }, 
  failure: { error, result in
      guard let emptyInApp = result as? [String:Any],
      let status = emptyInApp["status"] as? String,
      status == "in_app_arr_empty" else {
      // Try to handle other errors
      return
    }     
    })

Tester la validation des achats en mode Sandbox

Pour tester la validation des achats dans un environnement Sandbox, ajoutez le code suivant :

[AppsFlyerLib shared].useReceiptValidationSandbox = YES;
AppsFlyerLib.shared().useReceiptValidationSandbox = true

📘

Remarque

Ce code doit être retiré de vos builds de production.

Validating an in-app purchase automatically generates and sends an in-app purchase event to AppsFlyer. Its eventValues will look something like this:

{
   "some_parameter": "some_value", // from additional_event_values
   "af_currency": "USD", // from currency
   "af_content_id" :"test_id", // from purchase
   "af_revenue": "10", // from revenue
   "af_quantity": "1", // from purchase
   "af_validated": true // flag that AF verified the purchase
}

Constantes d'événement

Predefined event names

Predefined event name constants follow a AFEventEventName naming convention. For example, AFEventAddToCart.

Nom de l'événementNom de constante iOS
"af_level_achieved"
AFEventLevelAchieved
"af_add_payment_info"
AFEventAddPaymentInfo
"af_add_to_cart"
AFEventAddToCart
"af_add_to_wishlist"
AFEventAddToWishlist
"af_complete_registration"
AFEventCompleteRegistration
"af_tutorial_completion"
AFEventTutorial_completion
"af_initiated_checkout"
AFEventInitiatedCheckout
"af_purchase"
AFEventPurchase
"af_rate"
AFEventRate
AFEventSearch
"af_spent_credits"
AFEventSpentCredits
"af_achievement_unlocked"
AFEventAchievementUnlocked
"af_content_view"
AFEventContentView
"af_list_view"
AFEventListView
"af_travel_booking"
AFEventTravelBooking
"af_share"
AFEventShare
"af_invite"
AFEventInvite
"af_login"
AFEventLogin
"af_re_engage"
AFEventReEngage
"af_update"
AFEventUpdate
"af_opened_from_push_notification"
AFEventOpenedFromPushNotification
"af_location_coordinates"
AFEventLocation
"af_customer_segment"
AFEventCustomerSegment
"af_subscribe"
AFEventSubscribe
"af_start_trial"
AFEventStartTrial
"af_ad_click"
AFEventAdClick
"af_ad_view"
AFEventAdView

Predefined event parameters

Predefined event parameter constants follow a AFEventParamParameterName naming convention. For example, AFEventParamRevenue.

Nom du paramètre d'événementNom de constante iOSType
"af_content"
AFEventParamContentString
"af_achievement_id"
AFEventParamAchievementIdString
"af_level"
AFEventParamLevelString
"af_score"
AFEventParamScoreString
"af_success"
AFEventParamSuccessString
"af_price"
AFEventParamPricefloat
"af_content_type"
AFEventParamContentTypeString
"af_content_id"
AFEventParamContentIdString
"af_content_list"
AFEventParamContentListString[]
"af_currency"
AFEventParamCurrencyString
"af_quantity"
AFEventParamQuantityint
"af_registration_method"
AFEventParamRegistrationMethodString
"af_payment_info_available"
AFEventParamPaymentInfoAvailableString
"af_max_rating_value"
AFEventParamMaxRatingValueString
"af_rating_value"
AFEventParamRatingValueString
"af_search_string"
AFEventParamSearchStringString
"af_date_a"
AFEventParamDateAString
"af_date_b"
AFEventParamDateBString
"af_destination_a"
AFEventParamDestinationAString
"af_destination_b"
AFEventParamDestinationBString
"af_description"
AFEventParamDescriptionString
"af_class"
AFEventParamClassString
"af_event_start"
AFEventParamEventStartString
"af_event_end"
AFEventParamEventEndString
"af_lat"
AFEventParamLatString
"af_long"
AFEventParamLongString
"af_customer_user_id"
AFEventParamCustomerUserIdString
"af_validated"
AFEventParamValidatedboolean
"af_revenue"
AFEventParamRevenuefloat
"af_projected_revenue"
AFEventProjectedParamRevenuefloat
"af_receipt_id"
AFEventParamReceiptIdString
"af_tutorial_id"
AFEventParamTutorialIdString
"af_virtual_currency_name"
AFEventParamVirtualCurrencyName
AFEventParamDeepLinkString
"af_old_version"
AFEventParamOldVersionString
"af_new_version"
AFEventParamNewVersionString
"af_review_text"
AFEventParamReviewTextString
"af_coupon_code"
AFEventParamCouponCodeString
"af_order_id"
AFEventParamOrderIdString
"af_param_1"
AFEventParam1String
"af_param_2"
AFEventParam2String
"af_param_3"
AFEventParam3String
"af_param_4"
AFEventParam4String
"af_param_5"
AFEventParam5String
"af_param_6"
AFEventParam6String
"af_param_7"
AFEventParam7String
"af_param_8"
AFEventParam8String
"af_param_9"
AFEventParam9String
"af_param_10"
AFEventParam10String
"af_departing_departure_date"
AFEventParamDepartingDepartureDateString
"af_returning_departure_date"
AFEventParamReturningDepartureDateString
"af_destination_list"
AFEventParamDestinationListString[]
"af_city"
AFEventParamCityString
"af_region"
AFEventParamRegionString
"af_country"
AFEventParamCountryString
"af_departing_arrival_date"
AFEventParamDepartingArrivalDateString
"af_returning_arrival_date"
AFEventParamReturningArrivalDateString
"af_suggested_destinations"
AFEventParamSuggestedDestinationsString[]
"af_travel_start"
AFEventParamTravelStartString
"af_travel_end"
AFEventParamTravelEndString
"af_num_adults"
AFEventParamNumAdultsString
"af_num_children"
AFEventParamNumChildrenString
"af_num_infants"
AFEventParamNumInfantsString
"af_suggested_hotels"
AFEventParamSuggestedHotelsString[]
"af_user_score"
AFEventParamUserScoreString
"af_hotel_score"
AFEventParamHotelScoreString
"af_purchase_currency"
AFEventParamPurchaseCurrencyString
"af_preferred_neighborhoods"
AFEventParamPreferredNeighborhoods //array of stringString[]
"af_preferred_num_stops"
AFEventParamPreferredNumStopsString
"af_adrev_ad_type"
AFEventParamAdRevenueAdTypeString
"af_adrev_network_name"
AFEventParamAdRevenueNetworkNameString
"af_adrev_placement_id"
AFEventParamAdRevenuePlacementIdString
"af_adrev_ad_size"
AFEventParamAdRevenueAdSizeString
"af_adrev_mediated_network_name"
AFEventParamAdRevenueMediatedNetworkNameString
"af_preferred_price_range"
AFEventParamPreferredPriceRangeint[] - basically a tuple(min,max) but we'll use array of int and use two values
"af_preferred_star_ratings"
AFEventParamPreferredStarRatingsint[] - basically a tuple(min,max) but we'll use array of int and use two values