- vừa được xem lúc

GetX - Flutter - Using GetService (Part 5)

0 0 884

Người đăng: Nguyen Minh Duong

Theo Viblo Asia

Giới thiệu

Ở phần trước mình giới thiệu về GetConnect, và hướng dẫn cách sử dụng GetConnect để handle các api request. Ở phần này mình sẽ giới thiệu component mới trong Getx là GetService

Để có thể hiểu nội dung của bài viết này bắt buộc các bạn phả đọc thêm về GetX ở các bài dưới đây:

GetService

Về cơ bản GetService cũng hoạt động tương tự như GetController (Controller chịu trách nhiệm handle logic cũng như chứa các Observe field phục vụ cho việc update UI).

Future<void> main() async { await initServices(); /// AWAIT SERVICES INITIALIZATION. runApp(SomeApp());
} /// Is a smart move to make your Services intiialize before you run the Flutter app.
/// as you can control the execution flow (maybe you need to load some Theme configuration,
/// apiKey, language defined by the User... so load SettingService before running ApiService.
/// so GetMaterialApp() doesnt have to rebuild, and takes the values directly.
void initServices() async { print('starting services ...'); /// Here is where you put get_storage, hive, shared_pref initialization. /// or moor connection, or whatever that's async. await Get.putAsync(() => DbService().init()); await Get.putAsync(SettingsService()).init(); print('All services started...');
} class DbService extends GetxService { Future<DbService> init() async { print('$runtimeType delays 2 sec'); await 2.delay(); print('$runtimeType ready!'); return this; }
} class SettingsService extends GetxService { void init() async { print('$runtimeType delays 1 sec'); await 1.delay(); print('$runtimeType ready!'); }
}

GetService cũng có lifecycle tươn tự như GetController (onInit(), onReady(), onClose()) tuy nhiên sẽ không có các 'logic' riêng biệt cho từng màn hình. Nó đơn giản chỉ là thông báo cho GetX Dependency Injection system biết rằng service này không thể bị xoá khỏi bộ nhớ một cách thông thường.

Cách duy nhất để xoá một GetService khỏi memory là gọi function Get.reset()

Vì những đặt tính như trên mà GetService rất thích hợp để khởi tạo các service sẽ được dùng trong xuyên xuốt vòng đời app : ApiService, StorageService, AuthenService....

Ở bài học hôm nay mình sẻ sử dụng GetService trong việc handle Authen và lắng nghe kết nối mạng trong app

1. Handle Authen

class AuthService extends GetxService { StorageProvider _storageProvider = Get.find(); TokenModel tokenModel; @override void onInit() { super.onInit(); tokenModel = _storageProvider.getToken(); _storageProvider.addTokenListener((TokenModel token) { if (token == null) { Get.offAllNamed(AppRoute.routeLoginScreen()); } tokenModel = token; }); } bool hasLogin() => tokenModel != null;
} 

Ở đây mình tạo ra một class AuthService extends từ GetxService class này sẽ chịu trách nhiệm keep token references của user hiện tại. Và sẽ tự động redirect đến màn hình Login (Get.offAllNamed(AppRoute.routeLoginScreen());) nếu quá trình refreshToken bị thất bại (TokenModel bị xoá khỏi Storage : ở đây mình sử dụng GetStorage thay cho SharedPreferences mọi người có thể tìm hiểu thêm về component này nhé)

Việc refreshToken sẽ được thực hiện như bên dưới, ở đây mình tiếp tục sử dụng GetXConnect để thao tác với api

class BengKeiApiProvider extends BaseProvider { @override void onInit() { httpClient.baseUrl = "http://bengkelrobot.net:8002"; httpClient.timeout = Duration(seconds: 15); httpClient.maxAuthRetries = 3; httpClient.addAuthenticator((request) async { var newToken; try { newToken = await Get.find<UserRepositoryImpl>().refreshToken(); } catch (_) { newToken = Get.find<AuthService>().tokenModel; } request.headers['Authorization'] = 'Bearer ${newToken.accessToken}'; return request; }); httpClient.addRequestModifier((request) async { var authService = Get.find<AuthService>(); if (authService.tokenModel != null) { request.headers['Authorization'] = 'Bearer ${authService.tokenModel.accessToken}'; } else { request.headers['Authorization'] = 'Basic ' + base64Encode( utf8.encode('bengkel-robot-client:bengkel-robot-secret')); } return request; }); } Future<TokenModel> refreshToken(RefreshTokenRequest request) { return postDeserialize<TokenModel>( '/oauth/token', FormData( JsonMapper.toMap(request), ), ); } }

Để hiểu hơn về GetConnect các bạn đọc thêm về bài trước của mình nhé. (Ở đây mình có sử dụng JsonMapper được provide từ plugin dart_json_mapper để thuận tiện cho việc conver json to modal và ngược lại)

Đừng bên inject AuthenService class vào AppBinding nhé (Đọc thêm ở bài Dependencies with GetX)

class AppBinding extends Bindings { @override void dependencies() { injectService(); } void injectService() { Get.put(AuthService()); Get.put(ConnectivityService()); }
} class MyApp extends StatelessWidget { const MyApp({ this.appConfig, }); final AppConfig appConfig; @override Widget build(BuildContext context) { return GetMaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), locale: LocalizationService.locale, fallbackLocale: LocalizationService.fallbackLocale, translations: LocalizationService(), initialRoute: AppRoute.routeHomeScreen(), initialBinding: AppBinding(appConfig: appConfig), getPages: AppRoute.generateGetPages(), );
} 

2. Hanlde Connectitvity

Để các bạn hiểu rõ hơn mình sẽ tạo thêm một Service nữa tạm gọi là ConnectitvityService

class ConnectivityService extends GetxService { bool isShowingDialog = false; @override void onInit() async { super.onInit(); var result = await Connectivity().checkConnectivity(); if (result == ConnectivityResult.none) { isShowingDialog = true; showDialog(); } Connectivity().onConnectivityChanged.listen((event) { if (event == ConnectivityResult.none) { isShowingDialog = true; showDialog(); } else { if (isShowingDialog) { Get.back(); isShowingDialog = false; } } }); } void showDialog() { Get.dialog( CupertinoAlertDialog( title: Text( 'Please turn on network connection to continue using this app'), ), barrierDismissible: false, ); }
} 

Service này chịu trách nhiệm lắng nghe sự thay đổi của network connection: nếu trong trường hợp không có kết nối internet nó sẽ show một Dialog bất người dùng phải turn on network connection, service này sẽ rất cần thiết cho các app yêu cầu phải có kết nối mạng liên tục ở mọi màn hình

Trên đây là hai case sử dụng cơ bản của GetService, ngoài ra còn rất nhiều cách sử dụng khác nữa. Đọc thêm bài này bạn đã sẵn sàng để sử dụng GetX chưa. Một Plugin tuyệt vời cho dev Flutter phải không nào, Cảm ơn các bạn. Ở bài tiếp theo mình sẽ đi sâu vào giải thích cách hoạt động của refresh token trong GetX và hướng dẫn các bạn tạo một demo hoàn chỉnh nhé. Cảm ơn mọi người đã theo dõi

Bình luận

Bài viết tương tự

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 1: Làm quen cô nàng Flutter

Lời mở đầu. Gần đây, Flutter nổi lên và được Google PR như một xu thế của lập trình di động vậy.

0 0 254

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 3: Lột trần cô nàng Flutter, BuildContext là gì?

Lời mở đầu. Màn làm quen cô nàng FLutter ở Phần 1 đã gieo rắc vào đầu chúng ta quá nhiều điều bí ẩn về nàng Flutter.

0 0 189

- vừa được xem lúc

Flutter Animation: Creating medium’s clap animation in flutte Part II

Trong phần 1 mình đã giới thiệu với các bạn cơ bản về Animation trong Flutter. Score Widget Size Animation.

0 0 53

- vừa được xem lúc

Flutter - GetX - Using GetConnect to handle API request (Part 4)

Giới thiệu. Xin chào các bạn, lại là mình với series về GetX và Flutter.

0 0 322

- vừa được xem lúc

StatefulWidget và StatelessWidget trong Flutter

I. Mở đầu. Khi các bạn build một ứng dụng với Flutter thì Widgets là thứ không thể thiếu đúng không ạ. Và 2 loại Widget không thể thiếu đó là StatefullWidget và StatelessWidget.

0 0 130

- vừa được xem lúc

Tìm hiểu về Riverpod - Provider nhưng không hắn :v

Trong Flutter có rất nhiều các quản lý state: Provider, Bloc, GetX, Redux,... khó mà nói cái nào tốt hơn cái nào. Tuy nhiên nếu bạn đã làm quen với Provider thì không ngại để tìm hiểu thêm về Riverpod. Một bản nâng cấp của Provider. Nếu bạn để ý thì cái tên "Riverpod" là các chữ cái của "Provider" đ

0 0 50