みずぴー日記

人間の再起動ボタンはハワイのビーチにある

🔥Firebase

夏休みなのでFirebaseの練習をした。

ライブフォトをシェアするSNSのプロトタイプを作った。ライブフォト好きだけど、他の人に共有しづらくて困っている。

f:id:mzp:20180828221417p:plain

📝参考にしたもの

基本的にFirebase Guidesを読んで作った。 これでだいたい分かるので、すごい。

ただ、Apple Developer Portalの設定が必要な箇所になると急に説明が雑になるので、そこは茅場町モバイルアプリもくもく会で教えてもらった。

🔥開発の様子: Firebase

ログイン

Firebase Authenticationを使うと、あっさりGoogleアカウントログインが作れる。便利。

Firestore

Firestoreでプロフィール情報を保存するようにした。

コンソールからデータが確認できて便利。

f:id:mzp:20180828222603p:plain

データの保存にはCodableFirebaseが便利だった。 Codable な構造体を型安全に扱えてよい。

func get<T: Codable>(documentPath: String) -> SignalProducer<T?, NoError> {
   let ref = Firestore.defaultStore().collection("collectionName")
   return SignalProducer { observer, _ in
     ref.document(documentPath).getDocument { document, error in
       if let data = document?.data(),
          let entity = try? FirestoreDecoder().decode(T.self, from: data) {
            observer.send(value: entity)
       }
       observer.sendCompleted()
    }
  }
}

Storage

Cloud Storageで画像を保存できるようにした。

通知

Firebase Cloud MessagingCloud Functionsを使ってfav通知を作った。

Cloud MessagingでAPNsを使う方法は2通りあるがAPNs authentication keyのほうが、どのアプリでも使えて便利。(茅場町モバイルアプリもくもく会で教えてもらった)

通知のロジックを書く場所が分からなかったが、Cloud FunctionsでDB等の変更を監視して通知を送るのがよいらしい。

f:id:mzp:20180828230025p:plain (What can I do with Cloud Functions?から引用)

コンソールから通知を送る方法が分からなかったが、Growカテゴリの下にあった。

f:id:mzp:20180828230530p:plain

📱進捗: Firebase以外

差分更新

画面更新にはDifferenceKitを使った差分更新を採用した。reloadData を読んでた箇所をDifferenceKitに書き換えるだけでよかったので便利。

index c7e6661..ab0d428 100644
--- a/Sources/Controllers/PhotosViewController.swift
+++ b/Sources/Controllers/PhotosViewController.swift
@@ -5,6 +5,7 @@
 //  Created by mzp on 2018/08/20.
 //  Copyright © 2018 mzp. All rights reserved.
 //
+import DifferenceKit
 import MobileCoreServices
 import NorthLayout
 import Photos
@@ -40,11 +41,15 @@ public class PhotosViewController: UICollectionViewController,
             UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #s
elector(add))
 
         collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: kCell)
+
+        self.dataSource.combinePrevious([]).signal.observeValues { oldValue, newValue in
+            let changeset = StagedChangeset(source: oldValue, target: newValue)
+            self.collectionView.reload(using: changeset) { _ in }
+        }
         PhotoFetchLatest().call().collect().startWithResult {
             switch $0 {
             case .success(let photos):
                 self.dataSource.swap(photos)
-                self.collectionView.reloadData()
             case .failure(.firebase(let error)):
                 self.presentError(title: "Firebabse", message: error.message)
             case .failure(.filesystem(let error)):

ライブフォトの読み書き

ライブフォトの読み書きはアンドキュメントな機能を使う必要がある。

読み込みは、imagePickerController(_:,didFinishPickingMediaWithInfo:)info から取得する。

extension ViewController: UIImagePickerControllerDelegate {
    public func imagePickerController(_ picker: UIImagePickerController,
                                      didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        guard let livePhoto = info[UIImagePickerController.InfoKey.livePhoto] as? PHLivePhoto else { return }
        guard let imageURL = photo.value(forKey: "imageURL") as? URL else { return }
        guard let videoURL = photo.value(forKey: "videoURL") as? URL else { return }
        // ....
    }
}

作成は、PHLivePhotorequest に、 画像と動画のURLを渡すことで生成できる。 PHLivePhotoInfoCancelledKey に対応する値が0になるまで待たないと生成されない。

func create(imageURL: URL, videoURL: URL) {
  PHLivePhoto.request(
    withResourceFileURLs: [imageURL, videoURL],
    placeholderImage: nil,
    targetSize: .zero,
    contentMode: .aspectFit) { livePhoto, info in
        if let canceled = info[PHLivePhotoInfoCancelledKey] as? NSNumber,
           canceled == 0,
           let livePhoto = livePhoto {
             // ...
        }
  }
}

✨その他

GitGuardian

なにも考えずにPublicレポジトリでやっていたら、GitGuardianから警告メールが来た。 あわててrevokeしてprivate レポジトリにした。

f:id:mzp:20180828232548p:plain

夏休み

気分転換のために何度か近所の喫茶店に行ったが、夏休みの宿題をやっているらしき兄弟がいて、夏を感じた。

そうか東京の子どもは喫茶店で宿題やるのか。 そんな文化しらないぞ、という気持ちにもなる。