Skip to content

Instantly share code, notes, and snippets.

@GursheeshSingh
Last active November 23, 2020 10:00
Show Gist options
  • Save GursheeshSingh/18655fff3f768cd4ea259040f1aee029 to your computer and use it in GitHub Desktop.
Save GursheeshSingh/18655fff3f768cd4ea259040f1aee029 to your computer and use it in GitHub Desktop.
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:package_info/package_info.dart';
import 'package:parse_server_sdk/parse_server_sdk.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:talkfootball/constants.dart';
import 'package:talkfootball/dialogs/do_not_ask_again_dialog.dart';
import 'package:talkfootball/models/app_version.dart';
class UpdateApp extends StatefulWidget {
final Widget child;
UpdateApp({this.child});
@override
_UpdateAppState createState() => _UpdateAppState();
}
class _UpdateAppState extends State<UpdateApp> {
@override
void initState() {
super.initState();
checkLatestVersion(context);
}
checkLatestVersion(context) async {
await Future.delayed(Duration(seconds: 5));
//Add query here to get the minimum and latest app version
//Change
//Here is a sample query to ParseServer(open-source NodeJs server with MongoDB database)
var queryBuilder = QueryBuilder<AppVersion>(AppVersion())
..orderByDescending("publishDate")
..setLimit(1);
var response = await queryBuilder.query();
if (response.success) {
//Change
//Parse the result here to get the info
AppVersion appVersion = response.results[0] as AppVersion;
Version minAppVersion = Version.parse(appVersion.minAppVersion);
Version latestAppVersion = Version.parse(appVersion.version);
PackageInfo packageInfo = await PackageInfo.fromPlatform();
Version currentVersion = Version.parse(packageInfo.version);
if (minAppVersion > currentVersion) {
_showCompulsoryUpdateDialog(
context,
"Please update the app to continue\n${appVersion.about ?? ""}",
);
} else if (latestAppVersion > currentVersion) {
SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
bool showUpdates = false;
showUpdates = sharedPreferences.getBool(kUpdateDialogKeyName);
if (showUpdates != null && showUpdates == false) {
return;
}
_showOptionalUpdateDialog(
context,
"A newer version of the app is available\n${appVersion.about ?? ""}",
);
print('Update available');
} else {
print('App is up to date');
}
}
}
_showOptionalUpdateDialog(context, String message) async {
await showDialog<String>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
String title = "App Update Available";
String btnLabel = "Update Now";
String btnLabelCancel = "Later";
String btnLabelDontAskAgain = "Don't ask me again";
return DoNotAskAgainDialog(
kUpdateDialogKeyName,
title,
message,
btnLabel,
btnLabelCancel,
_onUpdateNowClicked,
doNotAskAgainText:
Platform.isIOS ? btnLabelDontAskAgain : 'Never ask again',
);
},
);
}
_onUpdateNowClicked() {
print('On update app clicked');
}
_showCompulsoryUpdateDialog(context, String message) async {
await showDialog<String>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
String title = "App Update Available";
String btnLabel = "Update Now";
return Platform.isIOS
? new CupertinoAlertDialog(
title: Text(title),
content: Text(message),
actions: <Widget>[
CupertinoDialogAction(
child: Text(
btnLabel,
),
isDefaultAction: true,
onPressed: _onUpdateNowClicked,
),
],
)
: new AlertDialog(
title: Text(
title,
style: TextStyle(fontSize: 22),
),
content: Text(message),
actions: <Widget>[
FlatButton(
child: Text(btnLabel),
onPressed: _onUpdateNowClicked,
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}
@GursheeshSingh
Copy link
Author

Is it working with using home instead of initalRoute?

What causes the error? Is it shown on loading or after clicking a button?

@boscharnau
Copy link

Hi!

I have created a get call to the API for getting the version of the APP.
Thats my checkLatestVersion modified:

checkLatestVersion(context) async {
    await Future.delayed(Duration(seconds: 5));
    print("checkLatestVersion");

    final AppVersionModel appVersion = await _provider.find();
    
    print("afterCallProvider");
    if (appVersion != null) {

      PackageInfo packageInfo = await PackageInfo.fromPlatform();
      Version currentVersion = Version.parse(packageInfo.version);

      if (appVersion.minVersion > currentVersion) {
        _showCompulsoryUpdateDialog(
          context,
          "Siusplau, actualitza l'app per continuar.",
        );
      } else if (appVersion.latestVersion > currentVersion) {
        SharedPreferences sharedPreferences =
          await SharedPreferences.getInstance();

        bool showUpdates = false;
        showUpdates = sharedPreferences.getBool(kUpdateDialogKeyName);
        if (showUpdates != null && showUpdates == false) {
          return;
        }

        _showOptionalUpdateDialog(
          context,
          "Hi ha una nova versió de l'app disponible. Vols actualitzar-la?",
        );
        print('Update available');
      } else {
        print('App is up to date');
      }
    }
  }

AppVersionApiProvider class

import 'package:dio/dio.dart';
import 'package:kliik_app/dio/interceptor.dart';
import 'package:kliik_app/models/app_version.dart';

import '../conf.dart';

class AppVersionApiProvider {
  final String _endpoint = conf.api;
  final Dio _dio = addInterceptors(Dio());

  Future<AppVersionModel> find() async {
     var res = await _dio.get(_endpoint+"/app-version");
    
    if(res.statusCode == 200) {
      return AppVersionModel.fromJson(res.data);
    }
    return null;
  }
}

API Controller:

import { Controller, Get } from '@nestjs/common';
import { AppVersionService } from './app-version.service';

@Controller('app-version')
export class AppVersionController {

  constructor(
    private appVersionService: AppVersionService
  ) { }

  @Get('/')
  async appVersion() {
    console.log("app-versiooooon");
    return this.appVersionService.get();
  }
}

API Server

import { Injectable } from '@nestjs/common';
import { AppVersion } from './app-version.entity';

@Injectable()
export class AppVersionService {
  async get(): Promise<AppVersion> {
    return {
      latestVersion: "1.0.2",
      minVersion: "1.0.1"
    };
  }
}

I don't understand, why I am getting this error:

[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: DioError [DioErrorType.DEFAULT]: NoSuchMethodError: The getter 'statusCode' was called on null.
E/flutter (20447): Receiver: null
E/flutter (20447): Tried calling: statusCode
E/flutter (20447): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
E/flutter (20447): #1 errorInterceptor (package:kliik_app/dio/interceptor.dart:23:25)
E/flutter (20447): #2 addInterceptors. (package:kliik_app/dio/interceptor.dart:19:39)
E/flutter (20447): #3 InterceptorsWrapper.onError (package:dio/src/interceptor.dart:125:22)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment