πŸ“¦ GravitySDK for Flutter

GravitySDK β€” это ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт для ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ пСрсонализированного ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°, отслСТивания взаимодСйствия ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈ отобраТСния ΠΊΠ°ΠΌΠΏΠ°Π½ΠΈΠΉ Π² ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Ρ… Flutter-прилоТСниях. Он позволяСт ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ ΠΏΠΎ шаблонам, ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ события ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°Ρ… (модальноС ΠΎΠΊΠ½ΠΎ, полноэкранный Ρ€Π΅ΠΆΠΈΠΌ, bottom sheet).

πŸ“š ОглавлСниС

ВозмоТности

  • Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ SDK с ΠΊΠ»ΡŽΡ‡ΠΎΠΌ API ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ сСкции
  • Настройка ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° ΠΈ прокси
  • ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ посСщСний страниц ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… событий
  • ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° ΠΏΠΎ ΡˆΠ°Π±Π»ΠΎΠ½Ρƒ
  • ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° Π²:
    • Модальном ΠΎΠΊΠ½Π΅
    • Bottom sheet
    • ΠŸΠΎΠ»Π½ΠΎΡΠΊΡ€Π°Π½Π½ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅
    • Bottom sheet с рядом Ρ‚ΠΎΠ²Π°Ρ€ΠΎΠ²
  • ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° взаимодСйствий с ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ΠΎΠΌ ΠΈ ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Π°ΠΌΠΈ

Установка

Π”ΠΎΠ±Π°Π²ΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚ Π² Ρ„Π°ΠΉΠ» pubspec.yaml:

dependencies:
  gravity_sdk: ^0.8.0

Π—Π°Ρ‚Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

flutter pub get

И ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚ Π² своём ΠΊΠΎΠ΄Π΅:

import 'package:gravity_sdk/gravity_sdk.dart';

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ SDK Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ провСсти Π±Π°Π·ΠΎΠ²ΡƒΡŽ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ, ΠΏΠ΅Ρ€Π΅Π΄Π°Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ apiKey ΠΈ section. Π˜Ρ… ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² Π»ΠΈΡ‡Π½ΠΎΠΌ ΠΊΠ°Π±ΠΈΠ½Π΅Ρ‚Π΅.

await GravitySDK.instance.initialize(
  apiKey: 'api-key',
  section: 'section',
);

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ initialize

Future<void> initialize({
  required String apiKey,
  required String section,
  ProductWidgetBuilder? productWidgetBuilder,
  GravityEventCallback? gravityEventCallback,
  bool useAdvertisingId = false,
});
  • productWidgetBuilder β€” кастомная отрисовка ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡Π΅ΠΊ ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚ΠΎΠ²
  • gravityEventCallback β€” колбэк, Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΉ ΠΏΡ€ΠΈ Ρ‚Ρ€Π΅ΠΊΠΈΠ½Π³Π΅ событий
  • useAdvertisingId β€” ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅ΠΊΠ»Π°ΠΌΠ½Ρ‹ΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ устройства

ProductWidgetBuilder β€” кастомизация отобраТСния ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚ΠΎΠ²

ProductWidgetBuilder β€” это интСрфСйс, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹ΠΉ для кастомной отрисовки ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡Π΅ΠΊ ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚ΠΎΠ² Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΊΠ°ΠΌΠΏΠ°Π½ΠΈΠΉ. Он прСдоставляСт Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ, позволяя Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ внСшний Π²ΠΈΠ΄ Ρ‚ΠΎΠ²Π°Ρ€ΠΎΠ², ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π² кампанию, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΈ соотвСтствовали ΡΡ‚ΠΈΠ»ΡŽ прилоТСния.

Π—Π°Ρ‡Π΅ΠΌ это Π½ΡƒΠΆΠ½ΠΎ?

НСкоторыС ΠΊΠ°ΠΌΠΏΠ°Π½ΠΈΠΈ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ SDK, содСрТат ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Ρ‚ΠΎΠ²Π°Ρ€Ρ‹, Π°ΠΊΡ†ΠΈΠΈ, прСдлоТСния). Π§Ρ‚ΠΎΠ±Ρ‹ эти ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΠΈ Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½ΠΎ Π²ΠΏΠΈΡΡ‹Π²Π°Π»ΠΈΡΡŒ Π² интСрфСйс прилоТСния, SDK прСдоставляСт Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ свою Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ProductWidgetBuilder.

Если Π½Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ productWidgetBuilder, Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ рСализация ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: DefaultProductWidgetBuilder.

πŸ“¦ ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования

class MyCustomProductWidgetBuilder extends ProductWidgetBuilder {
  @override
  Widget build(Slot slot) {
    final item = slot.item;

    return Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          if (item.imageUrl != null)
            ClipRRect(
              borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
              child: Image.network(
                item.imageUrl!,
                height: 160,
                width: double.infinity,
                fit: BoxFit.cover,
              ),
            ),
          Padding(
            padding: const EdgeInsets.all(12.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                if (item.isNew == 'true')
                  Padding(
                    padding: const EdgeInsets.only(bottom: 4.0),
                    child: Text(
                      'πŸ”₯ Новинка',
                      style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold),
                    ),
                  ),
                Text(
                  item.name,
                  style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
                ),
                SizedBox(height: 4),
                Text(
                  '${item.price}',
                  style: TextStyle(fontSize: 14, color: Colors.black87),
                ),
                if (item.oldPrice != null)
                  Text(
                    '${item.oldPrice}',
                    style: TextStyle(
                      fontSize: 12,
                      color: Colors.grey,
                      decoration: TextDecoration.lineThrough,
                    ),
                  ),
                SizedBox(height: 8),
                if (item.inStock != null)
                  Text(
                    item.inStock! ? 'Π’ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ' : 'НСт Π² Π½Π°Π»ΠΈΡ‡ΠΈΠΈ',
                    style: TextStyle(
                      fontSize: 12,
                      color: item.inStock! ? Colors.green : Colors.red,
                    ),
                  ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° кастомного builder’а ΠΏΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ SDK:

await GravitySDK.instance.initialize(
  apiKey: 'your-api-key',
  section: 'your-section-id',
  productWidgetBuilder: MyCustomProductWidgetBuilder(),
);

ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΈ настройки

GravitySDK.instance.setUser('user-id', 'session-id');

GravitySDK.instance.setOptions(
  options: Options(...),
  contentSettings: ContentSettings(...),
  proxyUrl: 'https://your-proxy.com',
);

ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ ΠΈ события

await GravitySDK.instance.trackView(
  pageContext: PageContext(...),
);

await GravitySDK.instance.triggerEvent(
  events: [TriggerEvent(...)],
  pageContext: PageContext(...),
);

ВзаимодСйствиС

GravitySDK.instance.sendContentEngagement(ContentImpressionEngagement(...));
GravitySDK.instance.sendProductEngagement(ProductClickEngagement(...));

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°

final content = await GravitySDK.instance.getContent('template-id');

ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°

МодальноС окно

GravitySDK.instance.showModalContent(context, content);

Bottom Sheet

GravitySDK.instance.showBottomSheetContent(context, content);

Bottom Sheet: Ряд Ρ‚ΠΎΠ²Π°Ρ€ΠΎΠ²

GravitySDK.instance.showBottomSheetProductsRow(context, content);

ΠŸΠΎΠ»Π½ΠΎΡΠΊΡ€Π°Π½Π½ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ

GravitySDK.instance.showFullScreenContent(context, content);

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок

ΠŸΠ΅Ρ€Π΅Π΄ Π²Ρ‹Π·ΠΎΠ²Π°ΠΌΠΈ SDK Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π±Ρ€ΠΎΡˆΠ΅Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:

GravitySDK is not initialized. Call initialize() first.

Libraries

gravity_sdk