version_check_updater 0.0.1
version_check_updater: ^0.0.1 copied to clipboard
A simple and customizable Flutter package to handle version update notifications by comparing with App Store and Google Play Store.
Version Check Updater #
A simple and customizable Flutter package to handle version update notifications by comparing directly with App Store and Google Play Store.
Features #
- β Automatic detection of new versions in stores
- π± Customizable native UI for iOS and Android
- π Smart cache system to avoid excessive checks
- π¨ Fully customizable (texts, styles, behavior)
- π Easy implementation with just a few lines of code
- π§ Custom checker support for reliable Android updates
Important Notice for Android #
β οΈ Android version checking is prone to failure due to the nature of web scraping from Google Play Store. Google frequently changes their HTML structure and serves different content based on various factors. To address this limitation, we've added supplementary alternatives:
- Custom Checker (Recommended) - Implement your own backend for 100% reliability
- Test Mode - For development and testing
- Multiple Fallback Strategies - APKMirror and other sources as backup
Installation #
Add this to your pubspec.yaml
file:
dependencies:
version_check_updater: ^0.0.1
Platform Support #
Platform | Reliability | Method |
---|---|---|
iOS | β Excellent | Official iTunes API |
Android | β οΈ Unreliable | Web scraping (see alternatives) |
Basic Usage #
1. Initial Setup #
import 'package:version_check_updater/version_check_updater.dart';
// Create instance with configuration
final versionChecker = VersionCheckUpdater(
config: UpdateConfig(
androidId: 'com.yourapp.android', // Your Android package ID
iosId: 'com.yourapp.ios', // Your iOS bundle ID
showReleaseNotes: true,
forceUpdate: false,
checkInterval: const Duration(hours: 24),
),
);
2. Check for Updates Manually #
// Check if updates are available
final versionInfo = await versionChecker.checkForUpdate();
if (versionInfo?.isUpdateAvailable ?? false) {
print('New version available: ${versionInfo!.storeVersion}');
}
3. Show Update Dialog Automatically #
// In your main widget
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
versionChecker.showUpdateDialog(
context,
onLater: () {
// Callback when user chooses "Later"
print('User postponed the update');
},
);
});
}
Customization #
Dialog Configuration #
UpdateConfig(
dialogConfig: UpdateDialogConfig(
title: 'New version available π',
updateButtonText: 'Update now',
laterButtonText: 'Remind me later',
showAppIcon: true,
titleStyle: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
updateButtonStyle: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
),
),
)
Advanced Configuration #
UpdateConfig(
// Store IDs
androidId: 'com.example.app',
iosId: 'com.example.app',
// Country for search (affects regional availability)
countryCode: 'US',
// Show version release notes
showReleaseNotes: true,
// Force update (doesn't allow closing the dialog)
forceUpdate: false,
// Interval between automatic checks
checkInterval: const Duration(hours: 24),
// Dialog visual configuration
dialogConfig: UpdateDialogConfig(
// ... custom configuration
),
)
Complete Example #
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final VersionCheckUpdater _versionChecker;
@override
void initState() {
super.initState();
_versionChecker = VersionCheckUpdater(
config: UpdateConfig(
androidId: 'com.myapp.android',
iosId: 'com.myapp.ios',
showReleaseNotes: true,
dialogConfig: UpdateDialogConfig(
title: 'New version available!',
updateButtonText: 'Update',
laterButtonText: 'Later',
),
),
);
// Check on startup
WidgetsBinding.instance.addPostFrameCallback((_) {
_versionChecker.showUpdateDialog(context);
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
_versionChecker.checkAndShowUpdateDialog(context);
},
child: Text('Check for updates'),
),
),
),
);
}
}
Models #
VersionInfo #
class VersionInfo {
final String currentVersion;
final String storeVersion;
final String? releaseNotes;
final String? storeUrl;
final bool isUpdateAvailable;
final bool isForceUpdate;
}
UpdateConfig #
class UpdateConfig {
final String? androidId;
final String? iosId;
final String? countryCode;
final bool showReleaseNotes;
final bool forceUpdate;
final Duration checkInterval;
final UpdateDialogConfig? dialogConfig;
}
Platform Behavior #
iOS (App Store) β #
- Highly reliable - Uses official iTunes Search API
- Gets version information directly from Apple
- Includes release notes
- Direct URL to App Store
Android (Google Play Store) β οΈ #
- Prone to failure - No official API available
- Uses web scraping which is fragile and unreliable
- Google frequently changes HTML structure
- May serve different content based on region/device
- We provide multiple alternatives to mitigate this issue
Important Considerations #
General #
- Requires internet connection to check versions
- Checks are cached according to the configured
checkInterval
- Make sure to use the correct app identifiers (Bundle ID for iOS, Package Name for Android)
Android Limitations β οΈ #
Since Google Play Store doesn't provide an official API for version checking, Android version detection is inherently unreliable. We've implemented several strategies to improve reliability:
- Primary Method: APKMirror scraping
- Fallback Method: Play Store HTML parsing
- Alternative Solutions: Custom checkers, test mode
Strong Recommendation: For production apps, implement a custom checker with your own backend for Android. This is the only way to guarantee reliable version checking.
Android Solutions #
Due to the unreliable nature of Android version checking, we provide these supplementary alternatives:
1. Custom Version Checker (Recommended for Production) #
Create your own backend-based checker for 100% reliability:
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:version_check_updater/version_check_updater.dart';
class MyCustomVersionChecker implements StoreVersionChecker {
final String apiUrl;
MyCustomVersionChecker({required this.apiUrl});
@override
Future<VersionInfo?> checkForUpdate({
required String currentVersion,
required String packageId,
String? countryCode,
}) async {
try {
// Call your backend API
final response = await http.get(
Uri.parse('$apiUrl/version?packageId=$packageId&platform=${Platform.operatingSystem}'),
);
if (response.statusCode == 200) {
final data = json.decode(response.body);
return VersionInfo(
currentVersion: currentVersion,
storeVersion: data['version'],
releaseNotes: data['releaseNotes'],
storeUrl: data['storeUrl'],
isUpdateAvailable: _isVersionGreater(data['version'], currentVersion),
isForceUpdate: data['forceUpdate'] ?? false,
);
}
} catch (e) {
debugPrint('Custom version check error: $e');
}
return null;
}
bool _isVersionGreater(String storeVersion, String currentVersion) {
// Version comparison logic
try {
final storeParts = storeVersion.split('.').map(int.parse).toList();
final currentParts = currentVersion.split('.').map(int.parse).toList();
for (int i = 0; i < storeParts.length || i < currentParts.length; i++) {
final storePart = i < storeParts.length ? storeParts[i] : 0;
final currentPart = i < currentParts.length ? currentParts[i] : 0;
if (storePart > currentPart) return true;
if (storePart < currentPart) return false;
}
return false;
} catch (e) {
return false;
}
}
}
Use the custom checker:
void main() {
// Set custom checker for Android only
if (Platform.isAndroid) {
VersionCheckUpdater.setCustomChecker(
MyCustomVersionChecker(
apiUrl: 'https://your-api.com',
),
);
}
runApp(MyApp());
}
Backend Examples: GitHub JSON, Firebase Functions, Supabase, or any REST API. See the BACKEND_SOLUTION.md file for detailed examples.
2. Test Mode (For Development) #
Enable test mode to simulate updates during development:
// Enable test mode with mock version
VersionCheckUpdater.enableTestMode(mockStoreVersion: '2.0.0');
// Disable test mode
VersionCheckUpdater.disableTestMode();
3. Default Fallback Strategies #
If you don't implement a custom checker, the package will attempt these methods in order:
- APKMirror scraping (more reliable than Play Store)
- Play Store HTML parsing (prone to failure)
- Alternative endpoints
Note: These methods are unreliable and should not be used in production apps.
License #
This project is licensed under the MIT License - see the LICENSE file for details.