오픈소스 실행 및 활용 후기 (2)

Susanna Jung·2020년 3월 16일
1
post-thumbnail

지금까지 여행을 만들고 거기에 설명과 함께 사진을 업로드하는 기능을 구현했다. 백엔드에서는 각 여행이 Google 포토에 앨범으로 저장된다.

이번에는 이 애플리케이션을 사용하지 않는 다른 사람들과 여행을 공유할 수 있도록 코드를 수정해 보자.

각 여행에는 Google 포토의 앨범이 지원되므로 URL을 통해 앨범을 '공유'하고 이 URL을 가진 모든 사용자가 사용할 수 있는 방식으로 해 보겠다.

앨범을 공유하기 위한 호출 구현

앨범 상단의 공유 버튼을 누르면 트립 페이지에서 앨범이 공유된다.
코드를 다음과 같이 수정해준다:

lib/pages/trip_page.dart

Future<void> _shareAlbum(BuildContext context) async {
  // Show the loading indicator
  setState(() {
    _inSharingApiCall = true;
  });
  final SnackBar snackBar = SnackBar(
    duration: Duration(seconds: 3),
    content: const Text('Sharing Album...'),
  );
  Scaffold.of(context).showSnackBar(snackBar);
  // Share the album and update the local model
  await ScopedModel.of<PhotosLibraryApiModel>(context).shareAlbum(album.id);
  final Album updatedAlbum =
      await ScopedModel.of<PhotosLibraryApiModel>(context).getAlbum(album.id);
  print('Album has been shared.');
  setState(() {
    album = updatedAlbum;
    // Hide the loading indicator
    _inSharingApiCall = false;
  });
}

lib/pages/trip_page.dart

void _showShareableUrl(BuildContext context) {
  if (album.shareInfo == null || album.shareInfo.shareableUrl == null) {
    print('Not shared, sharing album first.');
    // Album is not shared yet, share it first, then display dialog
    _shareAlbum(context).then((_) {
      _showUrlDialog(context);
    });
  } else {
    // Album is already shared, display dialog with URL
    _showUrlDialog(context);
  }
}

lib/pages/trip_page.dart

void _showUrlDialog(BuildContext context) {
  print('This is the shareableUrl:\n${album.shareInfo.shareableUrl}');

  _showShareDialog(
      context,
      'Share this URL with anyone. '
      'Anyone with this URL can access all items.',
      album.shareInfo.shareableUrl);
}

그러면 공유하기를 누르면 복사할 수 있는 URL이 나온다.

다음은 앱 내에서도 앨범 공유를 할 수 있게 코드를 수정해 보자.

구글 포토에서 앨범은 URL에 접속할 수 있는 URL을 통해 공유할 수 있다. Library API를 통해 공유 토큰을 통해 앨범을 공유할 수도 있다. 공유 토큰은 API를 통해 사용자를 공유 앨범에 가입시키는 데 응용 프로그램 내에서 사용되는 문자열이다.

공유 토큰 표시하기
이전 단계에서 앨범을 공유하는 _shareAlbum(...) 방법을 이미 구현했다.
shareInfo 속성에는 화면에 표시될 "공유 토큰"도 포함되어 있다.

트립 페이지에서 사용자가 화면에서 "SHARE with FIELD TRIPPA" 버튼을 누를 때 호출되는 _showShareToken(...) 방법을 실행한다.

lib/pages/trip_page.dart

void _showShareToken(BuildContext context) {
  if (album.shareInfo == null) {
    print("Not shared, sharing album first.");
    // Album is not shared yet, share it first, then display dialog
    _shareAlbum(context).then((_) {
      _showTokenDialog(context);
    });
  } else {
    // Album is already shared, display dialog with token
    _showTokenDialog(context);
  }
}

lib/pages/trip_page.dart

void _showTokenDialog(BuildContext context) {
  print('This is the shareToken:\n${album.shareInfo.shareToken}');

  _showShareDialog(
      context, 'Use this token to share', album.shareInfo.shareToken);
}

공유 앨범 나열하기

애플리케이션은 현재 사용자가 소유한 앨범만 나열하고 공유 앨범은 나열하지 않는다.

사용자가 만들거나 Google 포토 라이브러리에 명시적으로 추가한 앨범만 Google 포토 앱 내의 "알범" 화면에 표시된다. Library API에서 album.list를 호출할 때 이러한 앨범만 반환된다. Library API에서 여행 목록(앨범)을 검색하는 방법을 소유 앨범과 공유 앨범을 모두 포함하도록 변경해야 한다.

lib/model/photos_library_api_model.dart

void updateAlbums() async {
  // Reset the flag before loading new albums
  hasAlbums = false;
  // Clear all albums
  _albums.clear();
  // Add albums from the user's Google Photos account
  // var ownedAlbums = await _loadAlbums();
  // if (ownedAlbums != null) {
  //   _albums.addAll(ownedAlbums);
  // }

  // Load albums from owned and shared albums
  final List<List<Album>> list =
      await Future.wait([_loadSharedAlbums(), _loadAlbums()]);

  _albums.addAll(list.expand((a) => a ?? []));

  notifyListeners();
  hasAlbums = true;
}

공유 앨범 가입하기

공유 토큰을 사용하여 앱 사용자를 앨범에 가입시킬 수 있다.

사용자가 입력한 공유 토큰으로 API 모델을 호출하는 조인 트립 페이지에서 _joinTrip 방법을 구현해야한다. 먼저 로딩 인디케이터를 표시한 다음, 로드 인디케이터를 숨기고 이전 화면으로 돌아가기 전에 텍스트 양식의 입력으로 공유 앨범에 가입하도록 호출하면 된다.

lib/pages/join_trip_page.dart

Future<void> _joinTrip(BuildContext context) async {
  // Show loading indicator
  setState(() => _isLoading = true);

  // Call the API to join an album with the entered share token
  await ScopedModel.of<PhotosLibraryApiModel>(context)
      .joinSharedAlbum(shareTokenFormController.text);

  // Hide loading indicator
  setState(() => _isLoading = false);

  // Return to the previous screen
  Navigator.pop(context);
}

실행해보기
이 부분을 시험해 보려면 다른 사용자 계정을 가진 두 번째 장치 또는 에뮬레이터가 필요하다.

한 사용자 아래에서 트립을 생성하고 공유한 다음 "SHARE IN FIELD TRIPPA" 옵션을 선택하여 공유 토큰을 검색한다. 이 공유 토큰을 다른 장치나 에뮬레이터에 복사하고 홈 페이지의 "JOIN A TRIP ALBUM" 옵션을 통해 입력하면 된다.

오픈소스를 사용해본 후기

이렇게 구글 포토와 플러터를 사용한 오픈소스를 직접 설치해 보고 또 사용해 보았다. 생각했던것 보다 많이 어려웠고 중간에 에러가 날때마다 너무 당황스러웠지만 돌이켜보면 재미있었던 경험인것 같다.
나중에 플러터를 사용해 실제 앱 개발을 해보고싶다는 생각이 들었다.

이 앱에 발전 가능성도 많이 보였다. 오픈소스 사용 연습이 아닌 실제 어플리케이션에서 공유를 구현할 때는 공유 토큰을 사용하여 사용자를 앨범에 가입시킬 수 있는 방법에 대해 신중하게 생각해야 할것 같다. 보안 백엔드에 저장하고 사용자 간의 관계를 사용하여 앨범을 만들고 가입하는 것을 고려해 봐야겠다는 생각이 들었다.

오픈소스도 처음이지만 새로운 언어 flutter와 함께 더불어 API도 사용해 볼수 있으니 여러분들도 꼭 한번 오픈소스를 사용하는 연습을 해 보기 바라며 이만 마친다.

0개의 댓글