shyun_link 2.2.1 copy "shyun_link: ^2.2.1" to clipboard
shyun_link: ^2.2.1 copied to clipboard

Complete deeplink and short URL management with native platform integration. Ultra-simple ShyunLinkManager API, Android/iOS native setup included, Clean Architecture, and enterprise-grade error handling.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shyun_link/shyun_link.dart';

/**
 * ShyunLink Complete Example App
 * 
 * 이 예제는 ShyunLinkManager의 모든 기능을 보여줍니다:
 * - 울트라 심플 초기화 (5줄로 완성)
 * - 딥링크 자동 처리
 * - 짧은 링크 생성 및 공유
 * - 배치 처리
 * - 네이티브 딥링크 연동
 */
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 🎉 ShyunLinkManager로 5줄 초기화!
  await ShyunLinkManager.initialize(
    appScheme: 'nearound',
    webBaseUrl: 'https://cocl.nearound.co',
    apiServerUrl: 'https://www.nearound.co',
    shortLinkDomain: 'near.ly',
    onDeepLink: (context) {
      print('🔗 딥링크 받음: ${context.pageType}, ID: ${context.pageId}');
      // 실제 앱에서는 Navigator.pushNamed() 또는 Get.toNamed() 사용
      _handleDeepLink(context);
    },
  );
  
  runApp(ShyunLinkExampleApp());
}

// 딥링크 처리 함수
void _handleDeepLink(DeepLinkContext context) {
  print('📱 딥링크 처리: ${context.toString()}');
  
  // 실제 앱에서는 이런 식으로 구현:
  // switch (context.pageType) {
  //   case 'store':
  //     Get.toNamed('/storeDetail', parameters: {'id': context.pageId.toString()});
  //     break;
  //   case 'curation':
  //     Get.toNamed('/curationDetail', parameters: {
  //       'id': context.pageId.toString(),
  //       'type': context.params['type'] ?? 'default',
  //     });
  //     break;
  //   default:
  //     Get.toNamed(context.route);
  //     break;
  // }
}

class ShyunLinkExampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ShyunLink Complete Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final MethodChannel _nativeChannel = MethodChannel('shyun_link_example/deeplink');
  String _lastShortLink = 'None';
  String _systemStatus = 'Loading...';
  List<String> _testResults = [];

  @override
  void initState() {
    super.initState();
    _updateSystemStatus();
    _setupNativeDeepLinkListener();
  }

  // 네이티브 딥링크 리스너 설정
  void _setupNativeDeepLinkListener() {
    _nativeChannel.setMethodCallHandler((call) async {
      if (call.method == 'onDeepLink') {
        final String deepLink = call.arguments;
        print('📱 네이티브에서 딥링크 받음: $deepLink');
        
        // ShyunLinkManager로 처리
        await ShyunLinkManager.processDeepLink(deepLink);
        
        setState(() {
          _testResults.insert(0, '✅ 네이티브 딥링크: $deepLink');
          if (_testResults.length > 10) _testResults.removeLast();
        });
      }
    });
  }
  
  void _updateSystemStatus() {
    final status = ShyunLinkManager.getSystemStatus();
    setState(() {
      _systemStatus = status != null 
          ? 'ShyunLink 활성화됨 (${status['shortLinkRepository']})'
          : 'ShyunLink 비활성화됨';
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ShyunLink Complete Example'),
        elevation: 0,
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            _buildStatusCard(),
            SizedBox(height: 16),
            _buildSimpleApiSection(),
            SizedBox(height: 16),
            _buildConvenienceSection(),
            SizedBox(height: 16),
            _buildBatchSection(),
            SizedBox(height: 16),
            _buildTestingSection(),
            SizedBox(height: 16),
            _buildTestResults(),
          ],
        ),
      ),
    );
  }
  
  Widget _buildStatusCard() {
    return Card(
      color: Colors.blue[50],
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(Icons.info, color: Colors.blue),
                SizedBox(width: 8),
                Text(
                  'ShyunLink v2.2.1',
                  style: Theme.of(context).textTheme.titleLarge,
                ),
              ],
            ),
            SizedBox(height: 8),
            Text('상태: $_systemStatus'),
            SizedBox(height: 4),
            Text('마지막 생성 링크: $_lastShortLink'),
            SizedBox(height: 12),
            Text(
              '✨ v2.2.1: 완전한 네이티브 플랫폼 통합! 📱',
              style: TextStyle(
                fontWeight: FontWeight.bold,
                color: Colors.green[700],
              ),
            ),
          ],
        ),
      ),
    );
  }
  
  Widget _buildSimpleApiSection() {
    return Card(
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '🚀 Ultra-Simple API',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            SizedBox(height: 8),
            Text('ShyunLinkManager로 간단하게 링크 생성'),
            SizedBox(height: 16),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton(
                  onPressed: () => _createSimpleStoreLink(),
                  child: Text('스토어 링크'),
                ),
                ElevatedButton(
                  onPressed: () => _createSimpleCurationLink(),
                  child: Text('큐레이션 링크'),
                ),
                ElevatedButton(
                  onPressed: () => _createSimpleEventLink(),
                  child: Text('이벤트 링크'),
                ),
                ElevatedButton(
                  onPressed: () => _createCustomLink(),
                  child: Text('커스텀 링크'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildConvenienceSection() {
    return Card(
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '📤 편의 공유 기능',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            SizedBox(height: 8),
            Text('링크 생성 + 공유를 한번에'),
            SizedBox(height: 16),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton.icon(
                  onPressed: () => _shareStore(),
                  icon: Icon(Icons.store),
                  label: Text('스토어 공유'),
                ),
                ElevatedButton.icon(
                  onPressed: () => _shareCuration(),
                  icon: Icon(Icons.article),
                  label: Text('큐레이션 공유'),
                ),
                ElevatedButton.icon(
                  onPressed: () => _shareEvent(),
                  icon: Icon(Icons.event),
                  label: Text('이벤트 공유'),
                ),
                ElevatedButton.icon(
                  onPressed: () => _shareApp(),
                  icon: Icon(Icons.mobile_friendly),
                  label: Text('앱 홍보'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildBatchSection() {
    return Card(
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '📦 배치 처리',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            SizedBox(height: 8),
            Text('여러 링크를 한번에 생성'),
            SizedBox(height: 16),
            ElevatedButton.icon(
              onPressed: _createBatchLinks,
              icon: Icon(Icons.list),
              label: Text('배치 링크 생성 (5개)'),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildTestingSection() {
    return Card(
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '🧪 딥링크 테스트',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            SizedBox(height: 8),
            Text('네이티브와 Flutter 딥링크 테스트'),
            SizedBox(height: 16),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton(
                  onPressed: () => _testCustomScheme(),
                  child: Text('nearound:// 테스트'),
                ),
                ElevatedButton(
                  onPressed: () => _testHttpsLink(),
                  child: Text('HTTPS 링크 테스트'),
                ),
                ElevatedButton(
                  onPressed: () => _testShortLink(),
                  child: Text('짧은 링크 테스트'),
                ),
                ElevatedButton(
                  onPressed: () => _checkInitialLink(),
                  child: Text('초기 링크 확인'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildTestResults() {
    if (_testResults.isEmpty) return SizedBox.shrink();
    
    return Card(
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '📋 테스트 결과',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            SizedBox(height: 8),
            Container(
              height: 200,
              child: ListView.builder(
                itemCount: _testResults.length,
                itemBuilder: (context, index) {
                  return Padding(
                    padding: EdgeInsets.symmetric(vertical: 2),
                    child: Text(
                      _testResults[index],
                      style: TextStyle(
                        fontSize: 12,
                        fontFamily: 'monospace',
                      ),
                    ),
                  );
                },
              ),
            ),
            TextButton(
              onPressed: () => setState(() => _testResults.clear()),
              child: Text('결과 지우기'),
            ),
          ],
        ),
      ),
    );
  }
  
  // ================================
  // Simple API Methods
  // ================================
  
  Future<void> _createSimpleStoreLink() async {
    try {
      final link = await ShyunLinkManager.createShortLink(
        type: 'store',
        id: 12345,
        metadata: {'source': 'example_app'},
      );
      
      setState(() {
        _lastShortLink = link ?? 'Failed';
        _testResults.insert(0, '✅ 스토어 링크: $link');
        if (_testResults.length > 10) _testResults.removeLast();
      });
      
      _showSnackBar('스토어 링크 생성: $link', isSuccess: true);
    } catch (e) {
      _showSnackBar('스토어 링크 생성 실패: $e');
    }
  }

  Future<void> _createSimpleCurationLink() async {
    try {
      final link = await ShyunLinkManager.createShortLink(
        type: 'curation',
        id: 456,
        metadata: {
          'curation_type': 'banner',
          'source': 'example_app',
        },
      );
      
      setState(() {
        _lastShortLink = link ?? 'Failed';
        _testResults.insert(0, '✅ 큐레이션 링크: $link');
        if (_testResults.length > 10) _testResults.removeLast();
      });
      
      _showSnackBar('큐레이션 링크 생성: $link', isSuccess: true);
    } catch (e) {
      _showSnackBar('큐레이션 링크 생성 실패: $e');
    }
  }

  Future<void> _createSimpleEventLink() async {
    try {
      final link = await ShyunLinkManager.createShortLink(
        type: 'event',
        id: 789,
        metadata: {'source': 'example_app'},
      );
      
      setState(() {
        _lastShortLink = link ?? 'Failed';
        _testResults.insert(0, '✅ 이벤트 링크: $link');
        if (_testResults.length > 10) _testResults.removeLast();
      });
      
      _showSnackBar('이벤트 링크 생성: $link', isSuccess: true);
    } catch (e) {
      _showSnackBar('이벤트 링크 생성 실패: $e');
    }
  }

  Future<void> _createCustomLink() async {
    try {
      final link = await ShyunLinkManager.createShortLink(
        type: 'giftcode',
        code: 'EXAMPLE2024',
        metadata: {
          'campaign': 'app_example',
          'source': 'example_app',
        },
      );
      
      setState(() {
        _lastShortLink = link ?? 'Failed';
        _testResults.insert(0, '✅ 기프트 링크: $link');
        if (_testResults.length > 10) _testResults.removeLast();
      });
      
      _showSnackBar('기프트 링크 생성: $link', isSuccess: true);
    } catch (e) {
      _showSnackBar('기프트 링크 생성 실패: $e');
    }
  }
  
  // ================================
  // Convenience Share Methods
  // ================================
  
  Future<void> _shareStore() async {
    final success = await ShyunLinkManager.shareStore(
      12345,
      customText: '🏪 맛집 추천! 꼭 가보세요!',
    );
    
    setState(() {
      _testResults.insert(0, success ? '✅ 스토어 공유 성공' : '❌ 스토어 공유 실패');
      if (_testResults.length > 10) _testResults.removeLast();
    });
    
    _showSnackBar(success ? '스토어 공유 완료!' : '스토어 공유 실패', isSuccess: success);
  }

  Future<void> _shareCuration() async {
    final success = await ShyunLinkManager.shareCuration(
      456,
      'banner',
      customText: '📋 이 큐레이션을 확인해보세요!',
    );
    
    setState(() {
      _testResults.insert(0, success ? '✅ 큐레이션 공유 성공' : '❌ 큐레이션 공유 실패');
      if (_testResults.length > 10) _testResults.removeLast();
    });
    
    _showSnackBar(success ? '큐레이션 공유 완료!' : '큐레이션 공유 실패', isSuccess: success);
  }

  Future<void> _shareEvent() async {
    final success = await ShyunLinkManager.shareEvent(
      789,
      customText: '🎉 특별한 이벤트를 놓치지 마세요!',
    );
    
    setState(() {
      _testResults.insert(0, success ? '✅ 이벤트 공유 성공' : '❌ 이벤트 공유 실패');
      if (_testResults.length > 10) _testResults.removeLast();
    });
    
    _showSnackBar(success ? '이벤트 공유 완료!' : '이벤트 공유 실패', isSuccess: success);
  }

  Future<void> _shareApp() async {
    final success = await ShyunLinkManager.shareApp(
      customText: '📱 우리 앱을 다운로드해보세요!',
    );
    
    setState(() {
      _testResults.insert(0, success ? '✅ 앱 홍보 성공' : '❌ 앱 홍보 실패');
      if (_testResults.length > 10) _testResults.removeLast();
    });
    
    _showSnackBar(success ? '앱 홍보 완료!' : '앱 홍보 실패', isSuccess: success);
  }
  
  // ================================
  // Batch Operations
  // ================================
  
  Future<void> _createBatchLinks() async {
    try {
      final requests = [
        LinkRequest.store(1),
        LinkRequest.store(2),
        LinkRequest.curation(100, 'banner'),
        LinkRequest.event(50),
        LinkRequest.giftCode('BATCH123'),
      ];
      
      final links = await ShyunLinkManager.createBatchLinks(requests);
      
      setState(() {
        _testResults.insert(0, '✅ 배치 링크 ${links.length}개 생성');
        for (int i = 0; i < links.length && i < 5; i++) {
          _testResults.insert(0, '  ${i+1}. ${links[i]}');
        }
        while (_testResults.length > 15) _testResults.removeLast();
      });
      
      _showSnackBar('배치 링크 ${links.length}개 생성 완료!', isSuccess: true);
    } catch (e) {
      _showSnackBar('배치 링크 생성 실패: $e');
    }
  }
  
  // ================================
  // Deep Link Testing
  // ================================
  
  Future<void> _testCustomScheme() async {
    final testUrl = 'nearound://store/12345';
    try {
      await _nativeChannel.invokeMethod('testDeepLink', {'url': testUrl});
      
      setState(() {
        _testResults.insert(0, '✅ Custom Scheme 테스트: $testUrl');
        if (_testResults.length > 10) _testResults.removeLast();
      });
      
      _showSnackBar('Custom Scheme 딥링크 테스트 완료', isSuccess: true);
    } catch (e) {
      _showSnackBar('Custom Scheme 테스트 실패: $e');
    }
  }

  Future<void> _testHttpsLink() async {
    final testUrl = 'https://cocl.nearound.co/curationDetail?type=banner&id=456';
    try {
      await _nativeChannel.invokeMethod('testDeepLink', {'url': testUrl});
      
      setState(() {
        _testResults.insert(0, '✅ HTTPS 링크 테스트: $testUrl');
        if (_testResults.length > 10) _testResults.removeLast();
      });
      
      _showSnackBar('HTTPS 딥링크 테스트 완료', isSuccess: true);
    } catch (e) {
      _showSnackBar('HTTPS 링크 테스트 실패: $e');
    }
  }

  Future<void> _testShortLink() async {
    final testUrl = 'https://near.ly/abc123';
    try {
      await _nativeChannel.invokeMethod('testDeepLink', {'url': testUrl});
      
      setState(() {
        _testResults.insert(0, '✅ 짧은 링크 테스트: $testUrl');
        if (_testResults.length > 10) _testResults.removeLast();
      });
      
      _showSnackBar('짧은 링크 테스트 완료', isSuccess: true);
    } catch (e) {
      _showSnackBar('짧은 링크 테스트 실패: $e');
    }
  }

  Future<void> _checkInitialLink() async {
    try {
      final initialLink = await _nativeChannel.invokeMethod('getInitialLink');
      
      setState(() {
        _testResults.insert(0, '✅ 초기 링크: ${initialLink ?? "없음"}');
        if (_testResults.length > 10) _testResults.removeLast();
      });
      
      _showSnackBar(
        initialLink != null 
            ? '초기 링크: $initialLink' 
            : '초기 링크 없음',
        isSuccess: true,
      );
    } catch (e) {
      _showSnackBar('초기 링크 확인 실패: $e');
    }
  }

  void _showSnackBar(String message, {bool isSuccess = false}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        backgroundColor: isSuccess ? Colors.green : Colors.red,
        duration: Duration(seconds: 3),
      ),
    );
  }
}
3
likes
0
points
129
downloads

Publisher

unverified uploader

Weekly Downloads

Complete deeplink and short URL management with native platform integration. Ultra-simple ShyunLinkManager API, Android/iOS native setup included, Clean Architecture, and enterprise-grade error handling.

Repository (GitHub)
View/report issues

Topics

#deeplink #url #shortlink #navigation

License

unknown (license)

Dependencies

dio, flutter, logger, share_plus, url_launcher

More

Packages that depend on shyun_link