🔥Firebase
夏休みなのでFirebaseの練習をした。
ライブフォトをシェアするSNSのプロトタイプを作った。ライブフォト好きだけど、他の人に共有しづらくて困っている。
📝参考にしたもの
基本的にFirebase Guidesを読んで作った。 これでだいたい分かるので、すごい。
ただ、Apple Developer Portalの設定が必要な箇所になると急に説明が雑になるので、そこは茅場町モバイルアプリもくもく会で教えてもらった。
🔥開発の様子: Firebase
ログイン
Firebase Authenticationを使うと、あっさりGoogleアカウントログインが作れる。便利。
Firestore
Firestoreでプロフィール情報を保存するようにした。
コンソールからデータが確認できて便利。
データの保存には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 MessagingとCloud Functionsを使ってfav通知を作った。
Cloud MessagingでAPNsを使う方法は2通りあるがAPNs authentication keyのほうが、どのアプリでも使えて便利。(茅場町モバイルアプリもくもく会で教えてもらった)
通知のロジックを書く場所が分からなかったが、Cloud FunctionsでDB等の変更を監視して通知を送るのがよいらしい。
(What can I do with Cloud Functions?から引用)
コンソールから通知を送る方法が分からなかったが、Growカテゴリの下にあった。
📱進捗: 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 } // .... } }
作成は、PHLivePhoto
の request
に、 画像と動画の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 レポジトリにした。
夏休み
気分転換のために何度か近所の喫茶店に行ったが、夏休みの宿題をやっているらしき兄弟がいて、夏を感じた。
そうか東京の子どもは喫茶店で宿題やるのか。 そんな文化しらないぞ、という気持ちにもなる。