2023. 3. 25. 02:32ㆍDevelopers 공간 [Shorts]/Frontend
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew,
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter
- Module Bundler : React, Webpack, Parcel
B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS
C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight
1. What? (현상)
작업을 하다 보면 storage에 접근해야 하는 방법이 다양합니다.
2. Why? (원인)
- X
3. How? (해결책)
- path_provider : Flutter 기본 패키지
- getApplicationDocumentsDirectory() : 앱만의 저장공간이며, 앱의 크기와 관련있습니다.
- getApplicationSupportDirectory()
- getExternalCacheDirectories()
- getExternalStorageDirectories({StorageDirectory type })
- getExternalStorageDirectory()
- getLibraryDirectory()
- getTemporaryDirectory() : 캐시와 같이 임시로 데이터 저장하는 공간입니다.
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
final path = join(
(await getTemporaryDirectory()).path,
'${DateTime.now()}.png',
);
final File file = File(path);
file.writeAsBytes(...);
file.writeAsString(...);
// Get the directory and file List
Directory directory = await getApplicationDocumentsDirectory();
List<FileSystemEntity> fileList = await directory.list().toList();
// Get file names
List<File> allFileList = [];
allFileList.clear();
List<Map<int, dynamic>> fileNames = [];
fileList.forEach((file) {
if (file.path.contains('.jpg') || file.path.contains('.mp4')) {
allFileList.add(File(file.path));
String name = file.path.split('/').last.split('.').first;
fileNames.add({0: int.parse(name), 1: file.path.split('/').last});
}
});
// Retrieving the recent file
if (fileNames.isNotEmpty) {
final recentFile = fileNames.reduce((curr, next) => curr[0] > next[0] ? curr : next);
String recentFileName = recentFile[1];
}
- flutter_secure_storage : JWT와 같은 중요한 정보 저장시 사용
** JWT(Json Web Token) : Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token으로, Oauth를 구현할 때 사용합니다.
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class BasicStorageService {
final _storage = new FlutterSecureStorage();
Future<String> readFromStorage({String key}) async {
// Map<String, String> allValues = await _stroage.readAll();
String jwt = await _storage.read(key: key);
return jwt ?? "";
}
Future<void> deleteFromStorage(String key) async {
//await _storage.deleteAll();
await _storage.delete(key: key);
}
Future<void> writeToStorage(String key, String value) async {
await _storage.write(key: key, value: value);
}
}
- image_gallery_saver : 이미지 갤러리에 저장하기
- ios/Runner/Info.plist : 읽기 권한 key를 추가해줍니다.
<key>NSPhotoLibraryAddUsageDescription</key>
<string> ${PRODUCT_NAME}가 권한이 필요합니다.</string> - android/app/src/main/AndroidManifest.xml : <application> 아래 <activity> 위 추가
android:requestLegacyExternalStorage="true"
- ios/Runner/Info.plist : 읽기 권한 key를 추가해줍니다.
import 'package:image_gallery_saver/image_gallery_saver.dart';
await ImageGallerySaver.saveImage(
Uint8ListObject,
quality: 60,
name: "hello"
);
- gallery saver : 이미지와 비디오를 저장하기
- ios/Runner/Info.plist : 읽기/쓰기 권한 key를 추가해줍니다.
<key>NSPhotoLibraryUsageDescription</key>
<string> ${PRODUCT_NAME}가 권한이 필요합니다.</string> - android/app/src/main/AndroidManifest.xml : <manifest> 아래 <application>위 추가
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- ios/Runner/Info.plist : 읽기/쓰기 권한 key를 추가해줍니다.
import 'package:gallery_saver/gallery_saver.dart';
GallerySaver.saveImage(recordedImage.path)
.then((bool? result){
print('result : $result');
})
.catchError((err) {
print('error : $err');
});
- photo manager : 이미지를 여러개 읽는 것에 사용
- ios/Runner/Info.plist : 읽기/쓰기 권한 key를 추가해줍니다.
<key>NSPhotoLibraryUsageDescription</key>
<string> ${PRODUCT_NAME}가 권한이 필요합니다.</string> - android/app/src/main/AndroidManifest.xml : <application> 아래 <activity> 위 추가
android:requestLegacyExternalStorage="true" - Photo manager를 활용하는 경우 권한에 대한 셋팅을 permission_handler를 사용하지 않고 다룰 수 있는데, 아래와 같이 경우에 따라 구현할 수 있으며, iOS 14이상인 경우 "limited"라는 공유를 원하는 사진만을 선택하는 옵션이 있는데 이 경우는 presentLimited()라는 함수를 활용해 공유를 원하는 사진을 선택하게 해줄 수도 있습니다.
- Album의 type은 AssetPathEntity이며, photo의 type은 AssetEntity입니다. getAssetListRange() 혹은 getAssetListPaged()를 활용해 구현할 수 있는데, 후자는 pagenation을 구현할 때 활용합니다.
** AssetEntity : Android의 MediaStore field, iOS/macOS의 PHAsset object를 의미
- ios/Runner/Info.plist : 읽기/쓰기 권한 key를 추가해줍니다.
import 'package:photo_manager/photo_manager.dart';
PermissionState permitted = await PhotoManager.requestPermissionExtend();
switch(permitted){
case PermissionState.notDetermined:
break;
case PermissionState.restricted:
return;
break;
case PermissionState.denied:
return;
break;
case PermissionState.authorized:
// TODO
break;
case PermissionState.limited: //For iOS 14 and above
// TODO
// await PhotoManager.presentLimited(); //this is for letting them select photos
break;
default:
break;
}
import 'package:photo_manager/photo_manager.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class PhotoAlbum {
List<AssetEntity> photos = [];
int CurrentPages = 0;
Uint8List? thumbnail;
Future<void> _getAssets() async{
List<AssetPathEntity> albums = await PhotoManager.getAssetPathList(onlyAll: true);
AssetPathEntity recentAlbum = albums.first;
// photos = await recentAlbum.getAssetListRange(start: 0, end: 50);
photos = await recentAlbum.getAssetListPaged(page: 0, size: 50);
if(photos.isNotEmpty){
thumbnail = await photos[0].thumbnailData;
}
}
PhotoAlbum() {
_getAssets();
}
}
-----------------------------------------------------------------------------------------------------
<참고 : MacOS에서 확인했을 때 iOS상의 저장된 위치 프린트>
- 사진 : /private/var/mobile/Containers/Data/Application/컴파일ID/tmp/flutter-images/NAME_exif.jpg
- 비디오 : /private/var/mobile/Containers/Data/Application/컴파일ID/tmp/.video/NAME.MOV
-----------------------------------------------------------------------------------------------------
** 이외에 사진 여러장을 한번에 선택 가능하도록 할 수 있는 wechat_camera_picker 플러그인도 있습니다.
https://blog.logrocket.com/flutter-camera-plugin-deep-dive-with-examples/
https://iosroid.tistory.com/45
https://pub.dev/packages/flutter_secure_storage
https://pub.dev/packages/wechat_camera_picker
https://pub.dev/packages/gallery_saver
https://pub.dev/packages/image_gallery_saver
https://aloe-study.tistory.com/m/81
https://www.abdou.dev/blog/build-a-gallery-app-using-flutter
'Developers 공간 [Shorts] > Frontend' 카테고리의 다른 글
[Flutter] ios 셋팅 수정 및 다양한 상황에서 문제 해결하기 (0) | 2023.03.27 |
---|---|
[Flutter] 카메라 촬영 후 보이는 그대로 저장하기 (1) | 2023.03.26 |
[Flutter] Flutter에서 KakaoMap WebView API 활용하기 (0) | 2023.03.24 |
[Flutter] Stacked 패키지 Reactive Provider 설계하기 (0) | 2023.03.19 |
[Flutter] 위젯을 이미지로 찍어내기 (0) | 2023.03.19 |