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 |