dfinery_plugin 1.0.0-rc.0 copy "dfinery_plugin: ^1.0.0-rc.0" to clipboard
dfinery_plugin: ^1.0.0-rc.0 copied to clipboard

Dfinery plugin for Flutter

example/lib/main.dart

import 'dart:io';

import 'package:app_links/app_links.dart';
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:dfinery_plugin/dfinery_plugin.dart';
import 'package:go_router/go_router.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  // Dfinery SDK 초기화
  _initializeDfinerySDK();

  runApp(MyApp(state: ApplicationState()));
}

/// Dfinery SDK 초기화 함수
void _initializeDfinerySDK() {
  Map<String, dynamic> config = {
    DFConfig.iosLogEnable: true,
    DFConfig.androidLogEnable: true,
    DFConfig.androidLogLevel: DFAndroidLogLevel.verbose,
    DFConfig.androidNotificationIconName: 'ic_dfinery',
    DFConfig.androidNotificationChannelId: 'dfinery',
  };
  Dfinery.initWithConfig(serviceId: "YOUR_SERVICE_ID", config: config);
}

// =============================================================================
// 🔥 DFINERY EVENT FUNCTIONS
// =============================================================================

/// 공통 아이템 데이터 생성
Map<String, dynamic> _createSampleItem({DateTime? customDate}) {
  final item = {
    DFEventProperty.itemId: '상품번호',
    DFEventProperty.itemName: '상품이름',
    DFEventProperty.itemCategory1: '식품',
    DFEventProperty.itemCategory2: '과자',
    DFEventProperty.itemPrice: 5000.0,
    DFEventProperty.itemDiscount: 500.0,
    DFEventProperty.itemQuantity: 5
  };

  if (customDate != null) {
    item['custom_item_property'] = customDate;
  }

  return item;
}

/// 공통 아이템 리스트 생성
List<Map<String, dynamic>> _createSampleItems({DateTime? customDate}) {
  return [_createSampleItem(customDate: customDate)];
}

// -----------------------------------------------------------------------------
// 👤 User Analytics Functions
// -----------------------------------------------------------------------------

void onLoginPressed() {
  Dfinery.logEvent(eventName: DFEvent.login);
  print('Login 함수가 호출되었습니다.');
}

void onLogoutPressed() {
  Dfinery.logEvent(eventName: DFEvent.logout);
  print('Logout 함수가 호출되었습니다.');
}

// -----------------------------------------------------------------------------
// 🔄 Common Functions
// -----------------------------------------------------------------------------

void onSignUpPressed() {
  final param = {
    DFEventProperty.signChannel: 'Kakao',
  };
  Dfinery.logEvent(eventName: DFEvent.signUp, properties: param);
  print('Sign Up 함수가 호출되었습니다.');
}

void onPurchasePressed() {
  final param = {
    DFEventProperty.items: _createSampleItems(),
    DFEventProperty.orderId: '상품번호',
    DFEventProperty.paymentMethod: 'BankTransfer',
    DFEventProperty.totalPurchaseAmount: 25500.0,
    DFEventProperty.deliveryCharge: 3000.0,
    DFEventProperty.itemDiscount: 0
  };
  Dfinery.logEvent(eventName: DFEvent.purchase, properties: param);
  print('Purchase 함수가 호출되었습니다.');
}

// -----------------------------------------------------------------------------
// 🛒 Commerce Functions
// -----------------------------------------------------------------------------

void onViewHomePressed() {
  Dfinery.logEvent(eventName: DFEvent.viewHome);
  print('View Home 함수가 호출되었습니다.');
}

void onViewProductDetailPressed() {
  final param = {DFEventProperty.items: _createSampleItems()};
  Dfinery.logEvent(eventName: DFEvent.viewProductDetail, properties: param);
  print('View Product Details 함수가 호출되었습니다.');
}

void onAddToCartPressed() {
  final param = {DFEventProperty.items: _createSampleItems()};
  Dfinery.logEvent(eventName: DFEvent.addToCart, properties: param);
  print('Add to Cart 함수가 호출되었습니다.');
}

void onAddToWishListPressed() {
  final param = {DFEventProperty.items: _createSampleItems()};
  Dfinery.logEvent(eventName: DFEvent.addToWishList, properties: param);
  print('Add to Wishlist 함수가 호출되었습니다.');
}

void onRefundPressed() {
  final param = {
    DFEventProperty.items: _createSampleItems(),
    DFEventProperty.totalRefundAmount: 22500.0
  };
  Dfinery.logEvent(eventName: DFEvent.refund, properties: param);
  print('Refund 함수가 호출되었습니다.');
}

void onViewSearchResultPressed() {
  final param = {
    DFEventProperty.items: _createSampleItems(),
    DFEventProperty.keyword: '삼겹살'
  };
  Dfinery.logEvent(eventName: DFEvent.viewSearchResult, properties: param);
  print('View Search Result 함수가 호출되었습니다.');
}

void onViewListPressed() {
  final param = {DFEventProperty.items: _createSampleItems()};
  Dfinery.logEvent(eventName: DFEvent.viewList, properties: param);
  print('View List 함수가 호출되었습니다.');
}

void onViewCartPressed() {
  final param = {DFEventProperty.items: _createSampleItems()};
  Dfinery.logEvent(eventName: DFEvent.viewCart, properties: param);
  print('View Cart 함수가 호출되었습니다.');
}

void onRemoveCartPressed() {
  final param = {DFEventProperty.items: _createSampleItems()};
  Dfinery.logEvent(eventName: DFEvent.removeCart, properties: param);
  print('Remove Cart 함수가 호출되었습니다.');
}

void onShareProductPressed() {
  final param = {
    DFEventProperty.items: _createSampleItems(customDate: DateTime(2022, 4, 3)),
    DFEventProperty.sharingChannel: 'Facebook',
    'custom_property': DateTime(2022, 5, 6)
  };
  Dfinery.logEvent(eventName: DFEvent.shareProduct, properties: param);
  print('Share Product 함수가 호출되었습니다.');
}

void onAddPaymentInfoPressed() {
  Dfinery.logEvent(eventName: DFEvent.addPaymentInfo);
  print('Add Payment Info 함수가 호출되었습니다.');
}

// -----------------------------------------------------------------------------
// 🎯 Custom Event Functions
// -----------------------------------------------------------------------------

void onCustomEventPressed() {
  final param = {
    'is_logined': true,
    'username': 'hello',
    'visit_count': 1000,
    'custom_list': [
      {
        'custom_map_1_date': DateTime(2022, 4, 3),
        'custom_map_1_string': 'string',
        'custom_map_1_int': 1,
        'custom_map_1_double': 1000.0,
        'custom_map_1_bool': true,
      },
      {
        'custom_map_2_date': DateTime.now(),
        'custom_map_2_string': 'string',
        'custom_map_2_int': 0,
        'custom_map_2_double': 1000.0,
        'custom_map_2_bool': false
      }
    ]
  };
  Dfinery.logEvent(eventName: 'custom_event_1', properties: param);
  print('Custom Event 함수가 호출되었습니다.');
}

// -----------------------------------------------------------------------------
// ⚙️ SDK Management Functions
// -----------------------------------------------------------------------------

void onEnableSDKPressed() {
  Dfinery.enableSDK();
  print('enableSDK 함수가 호출되었습니다.');
}

void onDisableSDKPressed() {
  Dfinery.disableSDK();
  print('disableSDK 함수가 호출되었습니다.');
}

// -----------------------------------------------------------------------------
// 👥 User Properties Functions
// -----------------------------------------------------------------------------

void onSetUserProfilePressed() {
  Dfinery.setUserProfile(
      key: 'custom_user_profile_1',
      value: DateTime(2022, 4, 3, 0, 13, 1, 123, 12));
  print('setUserProfile 함수가 호출되었습니다.');
}

void onSetUserProfilesPressed() {
  final arr = ['a', 'b', 'c', 'd', 'e'];
  final now = DateTime.now();
  final param = {
    DFUserProfile.name: 'william',
    DFUserProfile.gender: DFGender.male,
    "custom_user_profile_1": now,
    "custom_user_profile_2": arr
  };
  Dfinery.setUserProfiles(values: param);
  print('setUserProfiles 함수가 호출되었습니다.');
}

// DFIdentity를 사용자 친화적인 이름으로 변환
String _identityToDisplayName(DFIdentity identity) {
  switch (identity) {
    case DFIdentity.externalId:
      return 'External ID';
    case DFIdentity.email:
      return 'Email';
    case DFIdentity.phoneNo:
      return 'Phone Number';
    case DFIdentity.kakaoUserId:
      return 'Kakao User ID';
    case DFIdentity.lineUserId:
      return 'Line User ID';
  }
}

// DFIdentity 선택 다이얼로그
Future<DFIdentity?> _showIdentitySelectionDialog(
    BuildContext context, Map<DFIdentity, String> identityOptions) async {
  return showDialog<DFIdentity>(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        title: const Text('Identity 선택'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: identityOptions.entries.map((entry) {
            return ListTile(
              title: Text(_identityToDisplayName(entry.key)),
              subtitle: Text('값: ${entry.value}'),
              onTap: () => Navigator.of(context).pop(entry.key),
            );
          }).toList(),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('취소'),
          ),
        ],
      );
    },
  );
}

Future<void> onSetIdentityPressed(BuildContext context) async {
  // DFIdentity 옵션과 샘플 값 매핑
  final identityOptions = {
    DFIdentity.externalId: 'user_12345',
    DFIdentity.email: '[email protected]',
    DFIdentity.phoneNo: '01000000000',
    DFIdentity.kakaoUserId: 'kakao_user_123',
    DFIdentity.lineUserId: 'line_user_456',
  };

  // 사용자에게 DFIdentity 선택 다이얼로그 표시
  final selectedIdentity =
      await _showIdentitySelectionDialog(context, identityOptions);

  if (selectedIdentity != null) {
    final value = identityOptions[selectedIdentity]!;
    Dfinery.setIdentity(key: selectedIdentity, value: value);
    print(
        'setIdentity 함수가 호출되었습니다: ${_identityToDisplayName(selectedIdentity)} = $value');
  }
}

void onSetIdentitiesPressed() {
  final param = {
    DFIdentity.externalId: 'user_example',
    DFIdentity.email: '[email protected]',
    DFIdentity.phoneNo: '01012345678'
  };
  Dfinery.setIdentities(values: param);
  print('setIdentities 함수가 호출되었습니다.');
}

void onResetIdentityPressed() {
  Dfinery.resetIdentity();
  print('resetIdentity 함수가 호출되었습니다.');
}

// -----------------------------------------------------------------------------
// 🔔 Push Notification Functions
// -----------------------------------------------------------------------------

Future<void> onRequestNotificationPermissionPressed() async {
  final status = await Permission.notification.request();
  if (status.isGranted) {
    print("알림 권한이 허용되었습니다.");
  } else if (status.isDenied) {
    print("알림 권한이 거부되었습니다.");
  } else if (status.isPermanentlyDenied) {
    print("알림 권한이 영구적으로 거부되었습니다. 설정에서 허용해주세요.");
    await openAppSettings();
  } else if (status.isRestricted) {
    print("알림 권한이 제한되었습니다.");
  }
  print('requestMessagingPermission 함수가 호출되었습니다.');
}

void onGetPushTokenPressed() {
  Dfinery.getPushToken().then((value) {
    print('getPushToken: $value');
  });
}

void onSetPushTokenPressed() {
  Dfinery.getPushToken().then((value) {
    if (value != null) {
      Dfinery.setPushToken(pushToken: value);
      print('setPushToken 함수가 호출되었습니다: $value.');
    }
  });
}

// =============================================================================
// 🏗️ UI COMPONENTS
// =============================================================================

// GoRouter 인스턴스 생성
final GoRouter _router = GoRouter(
  initialLocation: '/',
  routes: <RouteBase>[
    GoRoute(
      path: '/',
      builder: (BuildContext context, GoRouterState state) {
        return MyHomePage(title: 'Dfinery Flutter Example', state: state);
      },
      routes: <RouteBase>[],
    ),
  ],
  errorBuilder: (BuildContext context, GoRouterState state) {
    return Scaffold(
      appBar: AppBar(title: const Text('Error')),
      body: Center(
        child: Text('페이지를 찾을 수 없습니다: ${state.error}'),
      ),
    );
  },
);

class MyApp extends StatelessWidget {
  const MyApp({super.key, required this.state});
  final ApplicationState state;

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Dfinery Flutter Example',
      theme: ThemeData(primarySwatch: Colors.deepPurple),
      routerConfig: _router,
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title, required this.state});
  final String title;
  final GoRouterState state;

  @override
  MyHomeState createState() => MyHomeState();
}

class MyHomeState extends State<MyHomePage> with WidgetsBindingObserver {
  late AppLinks _appLinks;
  StreamSubscription<Uri>? _appLinksSubscription;
  bool _hasHandledInitialLink = false; // 초기 딥링크 처리 여부 플래그
  String? _initialLinkUri; // 초기 딥링크 URI 저장

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addObserver(this);
    _appLinks = AppLinks();
    _initDeepLinks();
  }

  Future<void> _initDeepLinks() async {
    // 앱이 처음 실행될 때 딥링크 확인
    final Uri? initialUri = await _appLinks.getInitialLink();
    if (initialUri != null) {
      _hasHandledInitialLink = true;
      _initialLinkUri = initialUri.toString();
      debugPrint('Initial deep link detected: $initialUri');
      _showDeepLinkAlert('앱 시작 딥링크', initialUri.toString());

      // 초기 딥링크 처리 후 잠깐 지연하여 중복 방지
      await Future.delayed(const Duration(milliseconds: 500));
    }

    // 앱이 실행 중일 때 딥링크 감지
    _appLinksSubscription = _appLinks.uriLinkStream.listen(
      (Uri uri) {
        // 초기 딥링크가 처리되었고, 같은 URI인 경우 무시
        if (_hasHandledInitialLink && _initialLinkUri == uri.toString()) {
          debugPrint('중복 딥링크 무시: $uri');
          return;
        }
        debugPrint('Deep link received while app running: $uri');
        _showDeepLinkAlert('런타임 딥링크', uri.toString());
      },
      onError: (err) {
        debugPrint('Deep link error: $err');
      },
    );
  }

  void _showDeepLinkAlert(String title, String deepLink) {
    if (mounted) {
      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text(title),
            content: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('딥링크로 앱이 열렸습니다!'),
                const SizedBox(height: 8),
                const Text('URL:',
                    style: TextStyle(fontWeight: FontWeight.bold)),
                SelectableText(
                  deepLink,
                  style: const TextStyle(fontSize: 12, color: Colors.blue),
                ),
              ],
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: const Text('확인'),
              ),
            ],
          );
        },
      );
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    _appLinksSubscription?.cancel();
    super.dispose();
  }

  @override
  void didUpdateWidget(covariant MyHomePage oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.state != oldWidget.state) {
      String newDeepLinkInfo =
          "didUpdateWidget GoRouterState URI: ${widget.state.uri}";
      print('didUpdateWidget (GoRouterState): ' + newDeepLinkInfo);
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dfinery Demo',
      theme: ThemeData(primarySwatch: Colors.deepPurple),
      home: Scaffold(
        appBar: AppBar(title: const Text('Dfinery Demo')),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                Text('LogEvent',
                    style: Theme.of(context).textTheme.headlineLarge),

                // User Analytics Section
                Text('UserAnalytics',
                    style: Theme.of(context).textTheme.headlineMedium),
                const ElevatedButton(
                    onPressed: onLoginPressed, child: Text('Login')),
                const ElevatedButton(
                    onPressed: onLogoutPressed, child: Text('Logout')),

                // Common Section
                Text('Common',
                    style: Theme.of(context).textTheme.headlineMedium),
                const ElevatedButton(
                    onPressed: onSignUpPressed, child: Text('Sign Up')),
                const ElevatedButton(
                    onPressed: onPurchasePressed, child: Text('Purchase')),
                // Commerce Section
                Text('Commerce',
                    style: Theme.of(context).textTheme.headlineMedium),
                const ElevatedButton(
                    onPressed: onViewHomePressed, child: Text('View Home')),
                const ElevatedButton(
                    onPressed: onViewProductDetailPressed,
                    child: Text('View Product Details')),
                const ElevatedButton(
                    onPressed: onAddToCartPressed, child: Text('Add To Cart')),
                const ElevatedButton(
                    onPressed: onAddToWishListPressed,
                    child: Text('Add To Wishlist')),
                const ElevatedButton(
                    onPressed: onRefundPressed, child: Text('Refund')),
                const ElevatedButton(
                    onPressed: onViewSearchResultPressed,
                    child: Text('View Search Result')),
                const ElevatedButton(
                    onPressed: onViewListPressed, child: Text('View List')),
                const ElevatedButton(
                    onPressed: onViewCartPressed, child: Text('View Cart')),
                const ElevatedButton(
                    onPressed: onRemoveCartPressed, child: Text('Remove Cart')),
                const ElevatedButton(
                    onPressed: onShareProductPressed,
                    child: Text('Share Product')),
                const ElevatedButton(
                    onPressed: onAddPaymentInfoPressed,
                    child: Text('Add Payment Info')),

                // Custom Event Section
                Text('CustomEvent',
                    style: Theme.of(context).textTheme.headlineMedium),
                const ElevatedButton(
                    onPressed: onCustomEventPressed,
                    child: Text('Custom Event')),

                // SDK Management Section
                Text('Dfinery',
                    style: Theme.of(context).textTheme.headlineMedium),
                const ElevatedButton(
                    onPressed: onEnableSDKPressed, child: Text('enableSDK')),
                const ElevatedButton(
                    onPressed: onDisableSDKPressed, child: Text('disableSDK')),

                // User Properties Section
                Text('DfineryProperties',
                    style: Theme.of(context).textTheme.headlineLarge),
                const ElevatedButton(
                    onPressed: onSetUserProfilePressed,
                    child: Text('setUserProfile')),
                const ElevatedButton(
                    onPressed: onSetUserProfilesPressed,
                    child: Text('setUserProfiles')),
                ElevatedButton(
                    onPressed: () {
                      onSetIdentityPressed(context);
                    },
                    child: const Text('setIdentity')),
                const ElevatedButton(
                    onPressed: onSetIdentitiesPressed,
                    child: Text('setIdentities')),
                const ElevatedButton(
                    onPressed: onResetIdentityPressed,
                    child: Text('resetIdentity')),

                // Push Notification Section
                Text('Push Notification',
                    style: Theme.of(context).textTheme.headlineLarge),
                const ElevatedButton(
                    onPressed: onRequestNotificationPermissionPressed,
                    child: Text('Request Notification Permission')),
                const ElevatedButton(
                    onPressed: onGetPushTokenPressed,
                    child: Text('Get Push Token')),
                const ElevatedButton(
                    onPressed: onSetPushTokenPressed,
                    child: Text('Set Push Token')),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class ApplicationState extends ChangeNotifier {
  ApplicationState() {
    init();
  }

  Future<void> init() async {
    refreshPushToken();
    refreshGoogleAdvertisingId();
    createNotificationChannel();
  }

  void refreshPushToken() {
    Future<String?> pushToken = Dfinery.getPushToken();
    pushToken.then((value) {
      if (value != null) {
        Dfinery.setPushToken(pushToken: value);
      }
    }).catchError((error) {
      print("error in refreshPushToken. ${error}");
    });
  }

  void refreshGoogleAdvertisingId() {
    Future<DFGetGoogleAdvertisingIdCallback?> advertisingIdInfo =
        Dfinery.getGoogleAdvertisingId();
    advertisingIdInfo.then((value) {
      if (value != null) {
        Dfinery.setGoogleAdvertisingId(
            googleAdvertisingId: value.googleAdvertisingId,
            isLimitAdTrackingEnabled: value.isLimitAdTrackingEnabled);
      }
    }).catchError((error) {
      print("error in refreshGoogleAdvertisingId. ${error}");
    });
  }

  void createNotificationChannel() {
    Map<String, dynamic> properties = {
      DFAndroidNotificationChannelProperty.id: 'dfinery',
      DFAndroidNotificationChannelProperty.name: 'Default Notification Channel',
      DFAndroidNotificationChannelProperty.importance:
          DFAndroidNotificationChannelImportance.high,
      DFAndroidNotificationChannelProperty.badge: true,
      DFAndroidNotificationChannelProperty.sound: true,
      DFAndroidNotificationChannelProperty.visibility:
          DFAndroidNotificationChannelVisibility.public,
      DFAndroidNotificationChannelProperty.vibration: true
    };
    Dfinery.createNotificationChannel(properties: properties);
  }
}
0
likes
0
points
18
downloads

Publisher

verified publisherigaworks.com

Weekly Downloads

Dfinery plugin for Flutter

Homepage

License

unknown (license)

Dependencies

flutter

More

Packages that depend on dfinery_plugin

Packages that implement dfinery_plugin