(+) Data Layer - Network
κ°μμμλ retrofitμ μ¬μ©νκ³ μλλ°, dio κ° λ μΈκΈ° μκ³ λ³΄νΈμ μΈ λΌμ΄λΈλ¬λ¦¬μ΄λ€. λ°λΌμ μ΄ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νκΈ°λ‘ νκ³ μ΄ λΌμ΄λΈλ¬λ¦¬ κΈ°μ€μΌλ‘ μ€μ ν κ²μ μ 리νλ€.
ν¨ν€μ§ κ΅¬μ± κ΄μ μμ λ°λΌλ³Έ Network

νλμ μ±μμ κ°κΈ° λ€λ₯Έ μλ²μ ν΅μ ν μΌμ΄ ννκ³ , μ΄ λ κ° μλ²μμ ν΅μ μ μ± μμ§λ ν΄λΌμ΄μΈνΈλ ꡬλΆμ ν΄λλ κ²μ΄ μ½λ νμ₯μ±μ΄λ μ μ§λ³΄μ μΈ‘λ©΄μμ μ 리νλ€.
κ·Έλ μ§λ§ ννΈμΌλ‘λ κ°κΈ° λ€λ₯Έ μλ²μ ν΅μ νλ€κ³ ν΄λ 곡ν΅μ μΌλ‘ κ°μ ΈμΌν μν λ° ννκ° μμ μ λ°μ μλ€. κ·Έλμ μ΄λ¬ν λΆλΆμ κ³ λ €ν΄μ base_http_client μ λΆλ¦¬ν΄λμκ³ κ° ν΄λΌμ΄μΈνΈκ° μ΄λ₯Ό μμν΄μ ꡬννλλ‘ μ²λ¦¬νλ€.
interceptor λ μ©λλ³λ‘ μ΅λν λΆλ¦¬ν΄μ λ°λ‘ ꡬνμ νμ¬ νμν ν΄λΌμ΄μΈνΈκ° μμμ κ°μ Έκ°μ μ¬μ©νλλ‘ μ²λ¦¬νλ€.
Network ꡬν
import 'package:dio/dio.dart';
abstract class BaseHttpClient with DioMixin implements Dio {
final String clientBaseUrl;
final List<Interceptor> customInterceptors;
BaseOptions? customOptions;
BaseHttpClient({
required this.clientBaseUrl,
required this.customInterceptors,
this.customOptions,
}) {
if (customOptions != null) {
options = customOptions!;
}
options.baseUrl = clientBaseUrl;
// options.connectTimeout = Duration(seconds: 5);
// options.receiveTimeout = Duration(seconds: 3);
interceptors.add(LogInterceptor(requestBody: true, responseBody: true));
interceptors.addAll(customInterceptors);
}
}import 'package:app_frame_sample/data/network/client/base_http_client.dart';
class TodoApiClient extends BaseHttpClient {
TodoApiClient({
required super.clientBaseUrl,
required super.customInterceptors,
super.customOptions,
});
}import 'dart:io';
import 'package:app_frame_sample/application/application.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:package_info_plus/package_info_plus.dart';
class BaseHeaderInterceptor extends InterceptorsWrapper {
@override
void onRequest(
RequestOptions options, RequestInterceptorHandler handler) async {
await _setHeaderWithAccessToken(options.headers);
await _setHeaderWithPackageInfo(options.headers);
await _setHeaderWithDeviceInfo(options.headers);
super.onRequest(options, handler);
}
Future<void> _setHeaderWithAccessToken(Map<String, dynamic> headers) async {
headers[HttpHeaders.authorizationHeader] =
await AccessManager.getAccessToken();
}
Future<void> _setHeaderWithPackageInfo(Map<String, dynamic> headers) async {
final PackageInfo packageInfo = await PackageInfo.fromPlatform();
headers['appName'] = packageInfo.appName;
headers['packageName'] = packageInfo.packageName;
headers['version'] = packageInfo.version;
headers['buildNumber'] = packageInfo.buildNumber;
}
Future<void> _setHeaderWithDeviceInfo(Map<String, dynamic> headers) async {
final DeviceInfoPlugin deviceInfo = Injector.deviceInfoPlugin;
if (Platform.isAndroid) {
final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
headers['uuid'] = androidInfo.id;
headers['operatingSystem'] = 'Android';
headers['operatingSystemVersion'] = androidInfo.version.sdkInt.toString();
return;
}
if (Platform.isIOS) {
final IosDeviceInfo iOSInfo = await deviceInfo.iosInfo;
headers['uuid'] = iOSInfo.identifierForVendor;
headers['operatingSystem'] = 'iOS';
headers['operatingSystemVersion'] = iOSInfo.systemVersion;
}
}
}μ¬κΈ°μ device μ 보μ package μ 보λ₯Ό μ½λλ° μ¬μ©λ ν¨ν€μ§λ€μ μλμ κ°λ€.
μ μ½λμμ ꡬνλ AccessManager λ data λ μ΄μ΄λ³΄λ€λ application λ μ΄μ΄μ μνλκ² λ§λ κ² κ°μμ μΌλ¨μ application layer μ ꡬνν΄λμκ³ μ½λλ μλμ κ°λ€. shared_preferences ν¨ν€μ§λ₯Ό μ¬μ©νλ€.
import 'package:shared_preferences/shared_preferences.dart';
class AccessManager {
static const String accessTokenKey = 'accessToken';
static Future<void> saveAccessToken(String accessToken) async {
final SharedPreferences preferences = await SharedPreferences.getInstance();
await preferences.setString(accessTokenKey, accessToken);
}
static Future<String> getAccessToken() async {
final SharedPreferences preferences = await SharedPreferences.getInstance();
final String? accessToken = preferences.getString(accessTokenKey);
if (accessToken == null) {
return '';
}
return accessToken;
}
}Last updated