Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/enhancement #20

Open
wants to merge 2 commits into
base: new_development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 40 additions & 12 deletions example/lib/example.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:io';

import 'package:appsonair_flutter_sdk/apps_on_air_service.dart';
import 'package:flutter/material.dart';

Expand All @@ -22,7 +24,6 @@ class _MyAppState extends State<MyApp> {
}

// Platform messages are asynchronous, so we initialize in an async method.

@override
Widget build(BuildContext context) {
return MaterialApp(
Expand All @@ -46,24 +47,51 @@ class DemoAppp extends StatefulWidget {
class _DemoApppState extends State<DemoAppp> {
@override
void initState() {

AppsOnAir.checkForAppUpdate(
context,
padding: const EdgeInsets.all(15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),

///use customWidget only if you want to use Your custom ui,
///make sure to pass false in param [showNativeUI]
customWidget: (response) {
return Column(children: [
Text("Application Name : ${response["appName"]}"),
Text(
"Application Version : ${response["updateData"]["androidBuildNumber"]}",
///use customWidget only if you want to use Your custom ui,
///make sure to pass false in param [showNativeUI]

customWidget: (response) {
return


Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [

Padding(
padding: const EdgeInsets.only(top: 20),
child: Text("${response.appName } : need an update "),
),
MaterialButton(
onPressed: () {},

Padding(
padding: const EdgeInsets.symmetric(vertical: 15),
child: Text(Platform.isAndroid ?

"To use this app, download the latest version:${response.updateData?.androidBuildNumber}":"To use this app, download the latest version:${response.updateData?.iosBuildNumber}"
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () {}, child: const Text("Update"),
),
],
)
]);
},
);
},
);
super.initState();

}

@override
Expand Down
17 changes: 14 additions & 3 deletions lib/apps_on_air_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import 'flutter_app_update_package_platform_interface.dart';
import 'src/model/app_info_model.dart';

class AppsOnAir {
///
Expand All @@ -25,26 +26,36 @@ class AppsOnAir {
static setAppId(String appId, {bool showNativeUI = false}) {
_appId = appId;
_showNativeUI = showNativeUI;

}

static void checkForAppUpdate(
BuildContext context, {
Widget? Function(Map<String, dynamic>)? customWidget,
Widget? Function(AppInfo)? customWidget,
EdgeInsetsGeometry? padding,
ShapeBorder? shape


}) {
if (_appId.isNotEmpty) {
if (!_showNativeUI && customWidget == null) {
throw Exception(
"set showNativeUI = 'true' in setAppId()"
" or/else return your custom widget in checkForAppUpdate() Method ",
);

} else if (_showNativeUI && customWidget != null) {
_printWarning(
"set showNativeUI = 'false' to show custom ui in setAppId() or/else remove custom widget from checkForAppUpdate() method");
}
FlutterAppUpdatePackagePlatform.instance.initMethod(context,
FlutterAppUpdatePackagePlatform.instance.initMethod(
context,
appId: _appId,
showNativeUI: _showNativeUI,
customWidget: customWidget);
customWidget: customWidget ,
padding: padding,
shape: shape
);
} else {
throw Exception(
"Make sure you initialized AppsOnAir by calling initialize() method");
Expand Down
80 changes: 64 additions & 16 deletions lib/flutter_app_update_package_method_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'flutter_app_update_package_platform_interface.dart';
import 'src/model/app_info_model.dart';

/// An implementation of [FlutterAppUpdatePackagePlatform] that uses method channels.
class MethodChannelFlutterAppUpdatePackage
Expand All @@ -20,33 +20,59 @@ class MethodChannelFlutterAppUpdatePackage
///[isShowNative] is used to show [customWidget]
///[isShowNative] turn it off if you want to show your [customWidget]
/// you can show your [customWidget] ui

@override
Future<void> initMethod(
BuildContext context, {
required String appId,
bool showNativeUI = false,
Widget? Function(Map<String, dynamic> response)? customWidget,
Widget? Function(AppInfo response)? customWidget,
EdgeInsetsGeometry? padding,
ShapeBorder? shape

}) async {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
this.context = context;

final result = await methodChannel.invokeMethod(
'setApplicationID', {"AppId": appId, "showNativeUI": showNativeUI});
if (result) {

_listenToNativeMethod();
final appUpdateResponse = await _check();
if (customWidget != null) {


final widget = customWidget.call(appUpdateResponse);

///custom ui dialog
if (!showNativeUI && widget != null) {
_alertDialog(widget);
}
if(Platform.isAndroid){
if(appUpdateResponse.updateData?.isAndroidForcedUpdate == true || appUpdateResponse.updateData?.isAndroidUpdate == true){
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make variable for "updateData" & check whether it is nullable or not

_alertDialog(widget,
padding: padding, shape: shape);
}
}else{
if(appUpdateResponse.updateData?.isIosForcedUpdate == true || appUpdateResponse.updateData?.isIosUpdate == true){
_alertDialog(widget,
padding: padding, shape: shape);

}
}
}


}
}
});
}





void _listenToNativeMethod() {

if (Platform.isIOS) {
methodChannel.setMethodCallHandler((call) {
switch (call.method) {
Expand All @@ -55,20 +81,25 @@ class MethodChannelFlutterAppUpdatePackage
break;
case "closeDialog":
if (_dialogOpen) {

_dialogOpen = false;
_closeDialog();
}
}
return Future.sync(() => _dialogOpen);
});
},
);
}
}


// while native dialog is open (in IOS), Flutter ui is still accessible
// This dialog is solution for to prevent flutter ui access
void _showIgnorePointerDialog() {

if (!_dialogOpen) {
_dialogOpen = true;

showDialog(
context: context,
barrierDismissible: false,
Expand All @@ -78,12 +109,13 @@ class MethodChannelFlutterAppUpdatePackage
color: Colors.transparent,
),
);
}
}
}

void _closeDialog() => Navigator.pop(context);

void _alertDialog(Widget widget) {
void _alertDialog(Widget widget, {required EdgeInsetsGeometry? padding,required ShapeBorder? shape}) {

showDialog(
context: context,
barrierDismissible: false,
Expand All @@ -92,30 +124,46 @@ class MethodChannelFlutterAppUpdatePackage
onWillPop: () async {
return false;
},
child: AlertDialog(
content: widget,
child:
AlertDialog(


shape: shape ?? RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
contentPadding: padding ?? const EdgeInsets.symmetric(vertical: 5),
content: widget
)

);
},
);
}

Future<Map<String, dynamic>> _check() async {
Future<AppInfo> _check() async {
String updateCheck = '';
try {
final result = await methodChannel.invokeMethod(
'isUpdateAvailable',
);
if (result != null && result is String) {
return Map<String, dynamic>.from(json.decode(result));
if (result != null && result.isNotEmpty ) {

return Platform.isIOS ?

/// jsonData is getting with type Map<Object?, Object?> so while parsing we are getting error of type mismatch
/// so right now now we are using jsonEncode and jsonDecode to solve this

AppInfo.fromJson(json.decode(json.encode( result)) ): AppInfo.fromJson(json.decode(result) );
}
return Map<String, dynamic>.from(((result ?? {}) as Map));

return AppInfo.fromJson(( result ) );
} on PlatformException catch (e) {
updateCheck = "Failed to check for update: '${e.message}'.";
}
if (kDebugMode) {
print(updateCheck);
print(AppInfo(updateData: UpdateData(updateCheck: updateCheck)));
}
return {"exception": updateCheck};
return AppInfo(updateData: UpdateData(updateCheck: updateCheck));

}
}
7 changes: 6 additions & 1 deletion lib/flutter_app_update_package_platform_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

import 'flutter_app_update_package_method_channel.dart';
import 'src/model/app_info_model.dart';

abstract class FlutterAppUpdatePackagePlatform extends PlatformInterface {
/// Constructs a FlutterAppUpdatePackagePlatform.
Expand Down Expand Up @@ -37,7 +38,11 @@ abstract class FlutterAppUpdatePackagePlatform extends PlatformInterface {
BuildContext context, {
required String appId,
bool showNativeUI = true,
Widget? Function(Map<String, dynamic>)? customWidget,
Widget? Function(AppInfo)? customWidget,
EdgeInsetsGeometry? padding,
ShapeBorder? shape


}) {
throw UnimplementedError('platformVersion() has not been implemented.');
}
Expand Down
Loading