iws_version_manager 1.1.0 copy "iws_version_manager: ^1.1.0" to clipboard
iws_version_manager: ^1.1.0 copied to clipboard

unlisted

IWS Version Manager makes it easy to notify new app versions and block versions that are no longer supported.

IWS Version Manager #

IWS Version Manager makes it easy to notify users about new app versions, manage version compatibility, and block versions that are no longer supported. This package provides comprehensive version management with automatic notifications, device tracking, and flexible UI components.

Features #

  • Automatic Version Checking: Automatically check for new versions on app startup
  • Multiple Notification Types: Support for mandatory and optional updates
  • Rich UI Components: Pre-built widgets for different notification styles
  • Release Notes: Display formatted release notes with markdown support
  • Device Tracking: Track device usage and user analytics
  • Platform Support: Cross-platform support with web-specific features
  • Custom Release Note Rendering: Customizable release note display
  • Connection Error Handling: Graceful handling of network issues
  • BLoC State Management: Built-in state management for version status

Getting Started #

1. Environment Setup #

Add the IWS API key and Version Code as DART variables at compile time:

flutter run --dart-define=IWS_API_KEY=your_api_key_here --dart-define=APP_VERSION_CODE=1

Or add them to your launch.json for VS Code:

{
  "configurations": [
    {
      "name": "Flutter",
      "type": "dart",
      "request": "launch",
      "program": "lib/main.dart",
      "args": [
        "--dart-define=IWS_API_KEY=your_api_key_here",
        "--dart-define=APP_VERSION_CODE=1"
      ]
    }
  ]
}

2. Initialize Version Manager #

Initialize the version checking in your app startup:

void main() {
  runApp(MyApp());
  
  // Initialize version manager
  if (!IwsVersionManager().widgetsInitialized()) {
    IwsVersionManager(
      deviceId: 'unique-device-id',
      userIdentifier: 'user-identifier'
    ).initializeWidgets();
  }
}

Usage Examples #

1. Automatic Scaffold Messages #

The easiest way to show version notifications is using IwsVersionScaffoldMessage:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return IwsVersionScaffoldMessage(
      showConnectionErrors: true, // Show connection error notifications
      messageHeight: 120.0, // Customize notification height
      child: Scaffold(
        appBar: AppBar(title: Text('My App')),
        body: YourContent(),
      ),
    );
  }
}

2. Version Icon Button #

Add a version status icon to your app bar:

class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
  @override
  Widget build(BuildContext context) {
    return AppBar(
      title: Text('My App'),
      actions: [
        IwsVersionIconButton(
          showConnectionError: true, // Show icon for connection errors
        ),
      ],
    );
  }
  
  @override
  Size get preferredSize => Size.fromHeight(kToolbarHeight);
}

3. Custom Version Listener #

Handle version events with custom logic:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return IwsVersionListener(
      onUpdateAvailable: (lastVersion, downloadLink) {
        // Handle optional update
        print('Update available: ${lastVersion?.versionName}');
        // Show custom UI or trigger custom logic
      },
      onMandatoryUpdate: (lastVersion, downloadLink) {
        // Handle mandatory update
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (context) => AlertDialog(
            title: Text('Update Required'),
            content: Text('You must update to continue using the app.'),
            actions: [
              TextButton(
                onPressed: () => _launchUpdate(downloadLink),
                child: Text('Update Now'),
              ),
            ],
          ),
        );
      },
      onConnectionError: () {
        // Handle connection errors
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Connection error')),
        );
      },
      onPlatformNotSupported: () {
        // Handle unsupported platform
        print('Platform not supported');
      },
      child: YourAppContent(),
    );
  }
  
  void _launchUpdate(String? downloadLink) {
    if (downloadLink != null) {
      // Launch download URL
    }
  }
}

4. Custom Version Builder #

Build different UI based on version status:

class VersionAwareWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return IwsVersionBuilder(
      updateAvailable: (lastVersion) {
        return Card(
          color: Colors.green.shade100,
          child: Padding(
            padding: EdgeInsets.all(16.0),
            child: Column(
              children: [
                Icon(Icons.new_releases, color: Colors.green),
                Text('Version ${lastVersion?.versionName} available!'),
                ElevatedButton(
                  onPressed: () => _downloadUpdate(),
                  child: Text('Download'),
                ),
              ],
            ),
          ),
        );
      },
      mandatoryUpdate: (lastVersion) {
        return Container(
          color: Colors.orange.shade100,
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Icon(Icons.warning, size: 64, color: Colors.orange),
                Text('Mandatory Update Required'),
                Text('Version: ${lastVersion?.versionName}'),
                ElevatedButton(
                  onPressed: () => _downloadUpdate(),
                  child: Text('Update Now'),
                ),
              ],
            ),
          ),
        );
      },
      connectionError: () {
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(Icons.wifi_off, size: 64, color: Colors.red),
              Text('Connection Error'),
              ElevatedButton(
                onPressed: () => _retryConnection(),
                child: Text('Retry'),
              ),
            ],
          ),
        );
      },
      platformNotSupported: () {
        return Center(
          child: Text('Platform not supported'),
        );
      },
      child: YourNormalContent(),
    );
  }
  
  void _downloadUpdate() {
    // Handle download logic
  }
  
  void _retryConnection() {
    IwsVersionManager().versionBloc.add(CheckAppVersion());
  }
}

5. Manual Version Checking #

Check for versions programmatically:

class VersionService {
  static Future<void> checkForUpdates() async {
    try {
      final versionStatus = await IwsVersionManager(
        deviceId: 'device-id',
        userIdentifier: 'user-id',
      ).checkPlatformVersion();
      
      if (versionStatus.newVersionAvailable) {
        print('New version available: ${versionStatus.lastVersion?.versionName}');
        
        if (versionStatus.mandatoryUpdate) {
          print('This is a mandatory update!');
          // Force user to update
        } else {
          print('Optional update available');
          // Show optional update notification
        }
        
        // Access version details
        final version = versionStatus.lastVersion;
        if (version != null) {
          print('Version Code: ${version.versionCode}');
          print('Version Name: ${version.versionName}');
          print('Download Link: ${version.downloadLink}');
          print('Release Notes: ${version.rawReleaseNotes}');
          print('Published At: ${version.publishedAt}');
          print('Minimal Version: ${version.minimalVersion}');
        }
      }
      
      if (!versionStatus.supportedPlatform) {
        print('Current platform is not supported');
      }
      
    } catch (e) {
      if (e is SdkNotConfigureException) {
        print('SDK not configured: ${e.message}');
      } else {
        print('Error checking version: $e');
      }
    }
  }
}

6. Custom Release Note Rendering #

Customize how release notes are displayed:

void setupCustomReleaseNotes() {
  IwsVersionManager().releaseNoteBuilder = (String plainText, dynamic richText) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          'What\'s New',
          style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
        ),
        SizedBox(height: 8),
        Container(
          padding: EdgeInsets.all(12),
          decoration: BoxDecoration(
            color: Colors.blue.shade50,
            borderRadius: BorderRadius.circular(8),
          ),
          child: MarkdownBody(data: plainText),
        ),
      ],
    );
  };
}

7. BLoC Integration #

Access the version BLoC directly for advanced use cases:

class CustomVersionWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<VersionBloc, VersionState>(
      bloc: IwsVersionManager().versionBloc,
      builder: (context, state) {
        switch (state.status) {
          case VersionStatus.starting:
            return CircularProgressIndicator();
          case VersionStatus.updated:
            return Text('App is up to date');
          case VersionStatus.updateAvailable:
            return _buildUpdateAvailable(state);
          case VersionStatus.mandatoryUpdate:
            return _buildMandatoryUpdate(state);
          case VersionStatus.connectionError:
            return _buildConnectionError();
          case VersionStatus.platformNotSupported:
            return _buildPlatformNotSupported();
        }
      },
    );
  }
  
  Widget _buildUpdateAvailable(VersionState state) {
    return Card(
      child: ListTile(
        leading: Icon(Icons.new_releases, color: Colors.green),
        title: Text('Update Available'),
        subtitle: Text('Version ${state.lastVersion?.versionName}'),
        trailing: TextButton(
          onPressed: () => _downloadUpdate(state.downloadLink),
          child: Text('Download'),
        ),
      ),
    );
  }
  
  Widget _buildMandatoryUpdate(VersionState state) {
    return Card(
      color: Colors.orange.shade100,
      child: ListTile(
        leading: Icon(Icons.warning, color: Colors.orange),
        title: Text('Mandatory Update'),
        subtitle: Text('Update required to continue'),
        trailing: ElevatedButton(
          onPressed: () => _downloadUpdate(state.downloadLink),
          child: Text('Update'),
        ),
      ),
    );
  }
  
  Widget _buildConnectionError() {
    return Card(
      child: ListTile(
        leading: Icon(Icons.error, color: Colors.red),
        title: Text('Connection Error'),
        trailing: IconButton(
          onPressed: () => _retryCheck(),
          icon: Icon(Icons.refresh),
        ),
      ),
    );
  }
  
  Widget _buildPlatformNotSupported() {
    return Card(
      child: ListTile(
        leading: Icon(Icons.block, color: Colors.grey),
        title: Text('Platform Not Supported'),
        subtitle: Text('This platform is not supported'),
      ),
    );
  }
  
  void _downloadUpdate(String? downloadLink) {
    // Implementation
  }
  
  void _retryCheck() {
    IwsVersionManager().versionBloc.add(CheckAppVersion());
  }
}

Configuration Options #

Version Status Types #

The package provides several version status types:

  • VersionStatus.starting: Initial state, checking in progress
  • VersionStatus.updated: App is up to date
  • VersionStatus.updateAvailable: Optional update available
  • VersionStatus.mandatoryUpdate: Required update available
  • VersionStatus.connectionError: Network connection error
  • VersionStatus.platformNotSupported: Platform not supported

Widget Configuration #

Each widget supports various configuration options:

IwsVersionScaffoldMessage

  • showConnectionErrors: Show notifications for connection errors
  • messageHeight: Height of notification messages

IwsVersionIconButton

  • showConnectionError: Show icon for connection errors

Error Handling #

The package includes built-in error handling:

try {
  final status = await IwsVersionManager().checkPlatformVersion();
  // Handle status
} on SdkNotConfigureException catch (e) {
  // Handle configuration errors
  print('Configuration error: ${e.message}');
} on FetchDataException catch (e) {
  // Handle network errors
  print('Network error: ${e.httpCode}');
} catch (e) {
  // Handle other errors
  print('Unknown error: $e');
}

Data Models #

ApplicationVersion #

class ApplicationVersion {
  int versionCode;           // Numeric version code
  String versionName;        // Human-readable version name
  dynamic releaseNotes;      // Rich text release notes
  String? rawReleaseNotes;   // Plain text release notes
  String? downloadLink;      // Direct download URL
  DateTime? publishedAt;     // Publication date
  int minimalVersion;        // Minimum supported version
  String? platformDownloadLink; // Platform-specific download URL
}

AppVersionStatus #

class AppVersionStatus {
  bool newVersionAvailable;  // New version is available
  bool mandatoryUpdate;      // Update is mandatory
  bool supportedPlatform;    // Platform is supported
  ApplicationVersion? lastVersion; // Latest version information
}

Web Support #

The package includes web-specific features:

  • Cache Clearing: Automatically clears browser cache on web updates
  • Page Reload: Forces page reload for web applications
  • Conditional Rendering: Shows reload button only on web platform

Best Practices #

  1. Initialize Early: Call initializeWidgets() as early as possible in your app lifecycle
  2. Handle Errors: Always implement error handling for network issues
  3. Test Updates: Use the dry-run publish option to test your update flow
  4. User Experience: Provide clear messaging about update requirements
  5. Graceful Degradation: Ensure your app works even when version checking fails

Advanced Usage #

Custom BLoC Events #

Trigger version checks manually:

// Trigger a version check
IwsVersionManager().versionBloc.add(CheckAppVersion());

State Monitoring #

Monitor version state changes:

IwsVersionManager().versionBloc.stream.listen((state) {
  print('Version status changed: ${state.status}');
});
0
likes
0
points
178
downloads

Publisher

unverified uploader

Weekly Downloads

IWS Version Manager makes it easy to notify new app versions and block versions that are no longer supported.

Homepage

License

unknown (license)

Dependencies

bloc, elegant_notification, flutter, flutter_bloc, flutter_markdown, iws_device_info, iws_http, url_launcher

More

Packages that depend on iws_version_manager