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

Adding error handling for iOS #1334

Merged
merged 8 commits into from
Jul 11, 2023
Merged
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
3 changes: 3 additions & 0 deletions mobile/lib/constants/api.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'config.dart';

class AirQoUrls {
static String get termsUrl =>
'https://docs.airqo.net/#/mobile_app/privacy_policy';

static String get firebaseLookup =>
'${Config.airqoApi}/v1/users/firebase/lookup';

Expand Down
19 changes: 6 additions & 13 deletions mobile/lib/constants/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ import 'package:geolocator/geolocator.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

class Config {
static String get airqoApiToken => dotenv.env['AIRQO_API_TOKEN'] ?? '';
static String get airqoJWTToken => dotenv.env['AIRQO_API_TOKEN'] ?? '';

static String get airqoApiV2Token => dotenv.env['AIRQO_API_V2_TOKEN'] ?? '';

static String get searchApiKey => dotenv.env['SEARCH_API_KEY'] ?? '';

static String get slackWebhookUrl => dotenv.env['SLACK_WEBHOOK_URL'] ?? '';

static double get minimumTextScaleFactor => 1.0;

static double get maximumTextScaleFactor => 1.1;

static String get airqoApi => 'https://platform.airqo.net/api';
Expand Down Expand Up @@ -59,12 +64,6 @@ class Config {
static String get airqoSecondaryLogo =>
'https://storage.cloud.google.com/airqo-app/public-images/airqo_logo.png';

static String get placesSearchUrl =>
'https://maps.googleapis.com/maps/api/place/';

static String get appStoreUrl =>
'https://apps.apple.com/ug/app/airqo-monitoring-air-quality/id1337573091';
Comment on lines -62 to -66
Copy link
Contributor Author

Choose a reason for hiding this comment

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

cleanup


static String get iosStoreId => '1337573091';

static String get iosBundleId => 'com.airqo.net';
Expand All @@ -79,18 +78,12 @@ class Config {

static int get locationChangeRadiusInMetres => 100;

static String get playStoreUrl =>
'https://play.google.com/store/apps/details?id=com.airqo.app';

static int get searchRadius => 4;

static int get surroundingsSitesMaxRadiusInKilometres => 20;

static int get shareLinkMaxLength => 56;

static String get termsUrl =>
'https://docs.airqo.net/#/mobile_app/privacy_policy';

static double get refreshTriggerPullDistance => 40;

static double get refreshIndicatorExtent => 30;
Expand Down
9 changes: 6 additions & 3 deletions mobile/lib/main_common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,17 @@ Future<void> initializeMainMethod() async {
);

PlatformDispatcher.instance.onError = (error, stack) {
logException(error, stack);
logException(error, stack, fatal: true);

return true;
};

FlutterError.onError = (details) {
FlutterError.presentError(details);
logException(details, null);
if (kDebugMode) {
FlutterError.dumpErrorToConsole(details);
} else {
logException(details, null, fatal: true);
}
};

ErrorWidget.builder = (FlutterErrorDetails details) {
Expand Down
9 changes: 8 additions & 1 deletion mobile/lib/models/app_store_version.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ class AppStoreVersion {
final String version;
final Uri url;

AppStoreVersion({required this.version, required this.url});
@JsonKey(name: 'is_updated', defaultValue: true)
final bool isUpdated;

AppStoreVersion({
required this.version,
required this.url,
required this.isUpdated,
});

factory AppStoreVersion.fromJson(Map<String, dynamic> json) =>
_$AppStoreVersionFromJson(json);
Expand Down
1 change: 1 addition & 0 deletions mobile/lib/models/app_store_version.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions mobile/lib/screens/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ class _HomePageState extends State<HomePage> {
await SharedPreferencesHelper.updateOnBoardingPage(OnBoardingPage.home);
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (context.read<DashboardBloc>().state.checkForUpdates) {
await AppService().latestVersion().then((version) async {
if (version != null && mounted) {
await AirqoApiClient().getAppVersion().then((version) async {
if (version != null && mounted && !version.isUpdated) {
await canLaunchUrl(version.url).then((bool result) async {
await openUpdateScreen(context, version);
});
Expand Down
6 changes: 6 additions & 0 deletions mobile/lib/screens/insights/insights_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:flutter_svg/svg.dart';

class InsightAirQualityWidget extends StatelessWidget {
const InsightAirQualityWidget(this.insight, {super.key, required this.name});

final Insight insight;
final String name;

Expand Down Expand Up @@ -112,6 +113,7 @@ class InsightAirQualityWidget extends StatelessWidget {

class InsightAirQualityMessageWidget extends StatelessWidget {
InsightAirQualityMessageWidget(this.insight, {super.key});

final Insight insight;
final ScrollController _scrollController = ScrollController();

Expand Down Expand Up @@ -298,6 +300,7 @@ class InsightsDayReading extends StatelessWidget {
super.key,
required this.isActive,
});

final Insight insight;
final bool isActive;

Expand Down Expand Up @@ -351,6 +354,7 @@ class InsightsDayReading extends StatelessWidget {

class InsightsCalendar extends StatelessWidget {
const InsightsCalendar(this.airQualityReading, {super.key});

final AirQualityReading airQualityReading;

@override
Expand Down Expand Up @@ -440,6 +444,7 @@ class InsightsCalendar extends StatelessWidget {

class ForecastContainer extends StatelessWidget {
const ForecastContainer(this.insight, {super.key});

final Insight insight;

@override
Expand Down Expand Up @@ -503,6 +508,7 @@ class ForecastContainer extends StatelessWidget {

class HealthTipsWidget extends StatefulWidget {
const HealthTipsWidget(this.insight, {super.key});

final Insight insight;

@override
Expand Down
4 changes: 2 additions & 2 deletions mobile/lib/screens/on_boarding/introduction_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ class IntroductionScreenState extends State<IntroductionScreen> {
updateOnBoardingPage();
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (context.read<DashboardBloc>().state.checkForUpdates) {
await AppService().latestVersion().then((version) async {
if (version != null && mounted) {
await AirqoApiClient().getAppVersion().then((version) async {
if (version != null && mounted && !version.isUpdated) {
await canLaunchUrl(version.url).then((bool result) async {
await openUpdateScreen(context, version);
});
Expand Down
4 changes: 2 additions & 2 deletions mobile/lib/screens/settings/about_page.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:app/constants/config.dart';
import 'package:app/constants/constants.dart';
import 'package:app/screens/web_view_page.dart';
import 'package:app/themes/theme.dart';
import 'package:app/widgets/widgets.dart';
Expand Down Expand Up @@ -61,7 +61,7 @@ class _AboutAirQoState extends State<AboutAirQo> {
MaterialPageRoute(
builder: (context) {
return WebViewScreen(
url: Config.termsUrl,
url: AirQoUrls.termsUrl,
title: 'Terms & Privacy Policy',
);
},
Expand Down
13 changes: 7 additions & 6 deletions mobile/lib/screens/settings/settings_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,10 @@ class DeleteAccountButton extends StatelessWidget {
loadingScreen(context);
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: profile.phoneNumber,
// ignore: no-empty-block not used
verificationCompleted: (PhoneAuthCredential
_) {}, // ignore: no-empty-block not used
verificationCompleted:
(PhoneAuthCredential phoneAuthCredential) {
debugPrint(phoneAuthCredential.smsCode);
},
verificationFailed: (FirebaseAuthException exception) async {
Navigator.pop(context);
final firebaseAuthError =
Expand Down Expand Up @@ -396,9 +397,9 @@ class DeleteAccountButton extends StatelessWidget {
phoneAuthModel: phoneAuthModel,
);
},
// ignore: no-empty-block not used
codeAutoRetrievalTimeout:
(String _) {}, // ignore: no-empty-block not used
codeAutoRetrievalTimeout: (String code) {
debugPrint(code);
},
timeout: const Duration(seconds: 15),
);
}
Expand Down
36 changes: 1 addition & 35 deletions mobile/lib/services/app_service.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import 'dart:io';

import 'package:app/blocs/blocs.dart';
import 'package:app/constants/constants.dart';
import 'package:app/models/models.dart';
import 'package:app/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'firebase_service.dart';
Expand Down Expand Up @@ -75,7 +72,7 @@ class AppService {

return true;
} catch (exception, stackTrace) {
logException(exception, stackTrace);
await logException(exception, stackTrace);

return false;
}
Expand Down Expand Up @@ -109,35 +106,4 @@ class AppService {
),
);
}

Future<AppStoreVersion?> latestVersion() async {
AppStoreVersion? appStoreVersion;

try {
final PackageInfo packageInfo = await PackageInfo.fromPlatform();

if (Platform.isAndroid) {
Comment on lines -113 to -118
Copy link
Contributor Author

Choose a reason for hiding this comment

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

logic transferred to API

appStoreVersion = await AirqoApiClient()
.getAppVersion(packageName: packageInfo.packageName);
} else if (Platform.isIOS) {
appStoreVersion = await AirqoApiClient()
.getAppVersion(bundleId: packageInfo.packageName);
} else {
return appStoreVersion;
}

if (appStoreVersion == null) return null;

return appStoreVersion.compareVersion(packageInfo.version) >= 1
? appStoreVersion
: null;
} catch (exception, stackTrace) {
await logException(
exception,
stackTrace,
);
}

return appStoreVersion;
}
}
2 changes: 0 additions & 2 deletions mobile/lib/services/firebase_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,6 @@ class CloudStore {
return null;
}



static Future<bool> updateProfile(Profile profile) async {
final User? currentUser = CustomAuth.getUser();
if (!profile.isSignedIn || currentUser == null) {
Expand Down
6 changes: 1 addition & 5 deletions mobile/lib/services/notification_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,7 @@ class NotificationService {
);
FirebaseMessaging.instance.onTokenRefresh.listen((fcmToken) {
// TODO update cloud store
}).onError(
(exception) {
logException(exception, null);
},
);
});
} catch (exception, stackTrace) {
await logException(exception, stackTrace);
}
Expand Down
Loading
Loading