이번 블로그 포스트에서는 플러터 앱에서 파일 업로드와 다운로드를 처리하는 방법에 대해 알아보겠습니다. 우리는 get_it
패키지를 사용하여 의존성 주입을 구현할 것입니다. 의존성 주입을 사용하면 코드의 유연성과 재사용성을 개선할 수 있습니다.
get_it 패키지 설정하기
먼저, get_it
패키지를 프로젝트에 추가해야 합니다. 이를 위해 pubspec.yaml
파일을 열고 get_it: ^x.x.x
와 같은 형식으로 의존성을 추가합니다. 그런 다음 터미널에서 flutter pub get
명령을 실행하여 패키지를 가져옵니다.
의존성 주입 클래스 생성하기
의존성 주입을 사용하기 위해 DependencyInjector
클래스를 생성하겠습니다. 이 클래스는 앱의 시작 시점에서 한 번만 초기화됩니다.
import 'package:get_it/get_it.dart';
class DependencyInjector {
static final GetIt injector = GetIt.instance;
static void init() {
injector.registerSingleton<FileRepository>(FileRepositoryImpl());
}
}
위의 코드에서 FileRepository
는 파일 업로드와 다운로드를 처리하는 인터페이스입니다. FileRepositoryImpl
은 이 인터페이스의 구현체입니다. 여기서는 단순히 registerSingleton
메서드를 사용하여 의존성을 등록합니다.
파일 업로드 및 다운로드 구현하기
의존성 주입을 설정했으므로 이제 파일 업로드와 다운로드를 처리하는 클래스를 작성할 수 있습니다. 아래 예제에서는 FileService
클래스를 구현하였습니다.
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:dio/dio.dart';
abstract class FileRepository {
Future<String> uploadFile(File file);
Future<File> downloadFile(String url);
}
class FileRepositoryImpl extends FileRepository {
final Dio _dio = Dio();
@override
Future<String> uploadFile(File file) async {
String fileName = file.path.split('/').last;
FormData formData = FormData.fromMap({
"file": await MultipartFile.fromFile(file.path, filename: fileName),
});
Response response = await _dio.post(
"https://example.com/upload",
data: formData,
);
return response.data['url'];
}
@override
Future<File> downloadFile(String url) async {
Directory directory = await getTemporaryDirectory();
String filePath = '${directory.path}/${url.split('/').last}';
await _dio.download(url, filePath);
return File(filePath);
}
}
위의 코드에서 uploadFile
메서드는 주어진 파일을 서버로 업로드하고 업로드된 파일의 URL을 반환합니다. downloadFile
메서드는 주어진 URL로부터 파일을 다운로드하고 파일 객체를 반환합니다.
파일 업로드 및 다운로드 사용하기
이제 파일 업로드와 다운로드를 사용하는 방법을 알아보겠습니다.
import 'dart:io';
import 'package:flutter/material.dart';
class FileUploader extends StatefulWidget {
@override
_FileUploaderState createState() => _FileUploaderState();
}
class _FileUploaderState extends State<FileUploader> {
final FileRepository _fileRepository = DependencyInjector.injector<FileRepository>();
File _selectedFile;
Future<void> _uploadFile() async {
if (_selectedFile == null) return;
String url = await _fileRepository.uploadFile(_selectedFile);
// 업로드된 파일의 URL 사용하기
}
Future<void> _downloadFile() async {
String url = "https://example.com/sample-file.jpg"; // 다운로드할 파일의 URL
File downloadedFile = await _fileRepository.downloadFile(url);
// 다운로드된 파일 사용하기
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("File Uploader"),
),
body: Column(
children: [
RaisedButton(
onPressed: () async {
File file = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_selectedFile = file;
});
},
child: Text("Select File"),
),
RaisedButton(
onPressed: _selectedFile != null ? _uploadFile : null,
child: Text("Upload File"),
),
RaisedButton(
onPressed: _downloadFile,
child: Text("Download File"),
),
],
),
);
}
}
위의 예제에서는 _uploadFile
메서드를 호출하여 선택한 파일을 업로드하고 _downloadFile
메서드를 호출하여 파일을 다운로드합니다. 파일의 처리는 FileRepository
클래스에서 수행되며, 의존성 주입을 통해 이를 구현체로 주입받습니다.
결론
이제 get_it
패키지를 사용하여 플러터 앱에서 파일 업로드와 다운로드를 처리하는 방법을 알아보았습니다. 의존성 주입을 통해 코드를 더 유연하고 재사용 가능하게 만들 수 있습니다.