Upgrade to Pro — share decks privately, control downloads, hide ads and more …

結婚式を支えた技術 Firebaseを活用したサーバレスiOSアプリケーション開発

Motoki Narita
September 17, 2017

結婚式を支えた技術 Firebaseを活用したサーバレスiOSアプリケーション開発

Motoki Narita

September 17, 2017
Tweet

More Decks by Motoki Narita

Other Decks in Technology

Transcript

  1. "CPVUNF w HJUIVC UXJUUFS RJJUBNPUPLJFF w J04%$+BQBOελοϑ w גࣜձࣾι΢κ΢ͰϝϧΧϦΧ΢ϧͷ։ൃΛ͍ͯ͠ΔJ04ΤϯδχΞ w

    ι΢κ΢͸ϝϧΧϦʹଓ͘৽ͨͳαʔϏεΛ࡞ΔձࣾͰ͢ w γΣΞαΠΫϧαʔϏεNFSDIBSJ४උத w ϋʔυ΢ΣΞ΋Ͱ͖ΔPSڵຯ௡ʑͳJ04ΤϯδχΞɺେืूத
  2. ࡉ͔͘ w ࣸਅʢλΠϜϥΠϯʣ w Χϝϥ͔ΒͷΞοϓϩʔυ w ΞϧόϜ͔ΒͷΞοϓϩʔ υ w Ξοϓͨࣸ͠ਅʹ-JLFతͳ

    ͜ͱ͕Ͱ͖Δ w Ξοϓͨࣸ͠ਅʹίϝϯτ Ͱ͖Δ w ࣸਅΛՃ޻Ͱ͖Δ w 1VTI௨஌ w ݁ࠗࣜલ೔ʹʮ໌೔͸ΑΖ͘͠ ͓Ͷ͕͍͠·͢ʯͱ͔ૹΓ͔ͨͬ ͨ w ੮࣍දӾཡ w ͜Ε෼͔ͬͯΔͱخ͍͠͸ͣ w ͓஌Βͤը໘ w Կ͔͋ͬͨΒ͜͜ʹදࣔͯ͠ʮಡ ΜͰͶʯ͕͔ͨͬͨ͠
  3. ՝୊੔ཧ w εέδϡʔϧ w ϦϦʔε೔݁ࠗࣜ౰೔ʜͩͱؒʹ߹Θͳ͍ͷͰ೔͘Β͍લ w αʔόαΠυʢͳʹΛ࢖͏ʹͯ͠΋ઈରؒʹ߹Θͳ͍ʣ w ࣌ظʢ৽͍͠04 4XJGUͳͲ͕ग़Δ͔ग़ͳ͍͔ͷλΠϛϯάʣ

    w ഑෍ w Πϯετʔϧ͢ΔਓΛͬͪ͜Ͱίϯτϩʔϧ͍ͨ͠ w Ϣʔβʔ w ࣗ෼ͨͪͷ༑ୡಉੈ୅ w ෕਌ɺ฼਌ɺ਌଒ εϚϗ࢖͍׳Εͯͳ͍ਓ͕ଟ͍  w 04͸ʜʁJ04ͷਓ͍ͨΒͲ͏͠Α͏
  4. ΍Γ͍ͨ͜ͱ w ࣸਅ w Χϝϥ͔ΒͷΞοϓϩʔυ w ΞϧόϜ͔ΒͷΞοϓϩʔ υ w Ξοϓͨࣸ͠ਅʹ-JLFతͳ

    ͜ͱ͕Ͱ͖Δ w Ξοϓͨࣸ͠ਅʹίϝϯτ Ͱ͖Δ w ࣸਅΛՃ޻Ͱ͖Δ w 1VTI௨஌ w ݁ࠗࣜલ೔ʹʮ໌೔͸ΑΖ͘͠ ͓Ͷ͕͍͠·͢ʯͱ͔ૹΓ͔ͨͬ ͨ w ੮࣍දӾཡ w ͜Ε෼͔ͬͯΔͱخ͍͠͸ͣ w ͓஌Βͤը໘ w Կ͔͋ͬͨΒ͜͜ʹදࣔͯ͠ʮಡ ΜͰͶʯ͕͔ͨͬͨ͠
  5. ΍Γ͍ͨ͜ͱ w ࣸਅʢλΠϜϥΠϯʣ w Χϝϥ͔ΒͷΞοϓϩʔυ w ΞϧόϜ͔ΒͷΞοϓϩʔ υ w Ξοϓͨࣸ͠ਅʹ-JLFతͳ

    ͜ͱ͕Ͱ͖Δ w Ξοϓͨࣸ͠ਅʹίϝϯτ Ͱ͖Δ w ࣸਅΛՃ޻Ͱ͖Δ w 1VTI௨஌ w ݁ࠗࣜલ೔ʹʮ໌೔͸ΑΖ͘͠ ͓Ͷ͕͍͠·͢ʯͱ͔ૹΓ͔ͨͬ ͨ w ੮࣍දӾཡ w ͜Ε෼͔ͬͯΔͱخ͍͠͸ͣ w ͓஌Βͤը໘ w Կ͔͋ͬͨΒ͜͜ʹදࣔͯ͠ʮಡ ΜͰͶʯ͕͔ͨͬͨ͠ ແ೦ɺ͜Ε͚ͩͰ͖ͣ
  6. final class FirebaseDatabaseManager { private var reference: FIRDatabaseReference = FIRDatabase.database().reference().child("articles")

    func save(_ article: Article, completion: CompletionHandler?) { reference.child(article.id).setValue(article.encoded) { _, _ in completion?() } } func load(_ completionHandler: @escaping ([Article]) -> ()) { reference.observeSingleEvent(of: .value) { snapshot -> Void in completionHandler(Article.build(snapshot.value)) } } func added(_ completionHandler: @escaping (Article?) -> ()) { let handler: (FIRDataSnapshot) -> Void = { snapshot in completionHandler(Article.decodeSingle(snapshot)) } reference.observe(.childAdded, with: handler) } 'JSFCBTF4%,Λ࢖͍ɺ3FBMUJNF%BUBCBTFͷมߋΛ؂ࢹ
  7. protocol PhotoViewerViewModelProtocol: class { func didUpdate(_ state: PhotoViewerViewModel.State) } final

    class PhotoViewerViewModel { enum State { case list([Article]) case add([Article]) case update(Article) case loading case error(String) } func refresh() { guard reachability.isReachable else { delegate?.didUpdate(.error("σʔλΛऔಘͰ͖·ͤΜͰͨ͠")) return } delegate?.didUpdate(.loading) database.load { [weak self] articles in self?.delegate?.didUpdate(.list(articles)) self?.subscribe() } } 7JFX.PEFMͰ4UBUFΛఆٛɺ%BUBCBTFͷมߋʹԠͯ͡ঢ়ଶΛߋ৽͢Δ
  8. func didUpdate(_ state: PhotoViewerViewModel.State) { cameraButton.isEnabled = true switch state

    { case .list(let article): tableView.isHidden = false refreshControl.endRefreshing() SVProgressHUD.dismiss() dataSource = article tableView.reloadData() case .add(let articles): tableView.isHidden = false dataSource = articles + dataSource tableView.reloadData() SVProgressHUD.dismiss() case .loading: cameraButton.isEnabled = false tableView.isHidden = false SVProgressHUD.show(withStatus: "loading...") 7JFX$POUSPMMFS͸4UBUFʹԠͯ͡දࣔΛ੾Γସ͑Δ
  9. final class FirebaseStorageManager { private let storageRef = FIRStorage.storage().reference(forURL: "gs://{project

    id}.appspot.com/") func newsLoad(_ completion: @escaping ([News]) -> Void) { storageRef.child("news.json").data(withMaxSize: maxSize) { (data, error) in guard error == nil, let data = data else { return } completion(News.decode(data)) } }
  10. func applicationDidBecomeActive(_ application: UIApplication) { let storage = FirebaseStorageManager() storage.newsLoad

    { news in NewsHistoryContainer.news = news NotificationCenter.default.post(name: updateNewsCount, object: nil) } }
  11. w େࣄͳ৘ใ͸1VTI௨஌ˍ͓஌Βͤ഑৴ w ձ৔·Ͱͷϧʔτ w ెา෼਺ w J04%$Ͱಘͨ஌ݟ w આ໌จΛॻ͍ͯ΋ͳ͔ͳ͔ಡΜͰ΋Β͏͜

    ͱ͸೉͍͠ w J04%$ͷΞϓϦͰ΋ࠔΓͲ͜Ζ΍ޙͰฉ͍ ͯΨοΧϦ͢ΔΑ͏ͳ৘ใ͸UXJUUFSΞΧ΢ ϯτͷ΄͔ɺ1VTI௨஌Ͱ഑৴ʢࠓ͔ΒͰ΋ ݟͯͶʣ
  12. w ΞϓϦͱ1VTI௨஌ͷ഑৴ɺจݴΛ ܾΊΔͷ͸Ԟ͞Μͷ໾ׂʹ w Ԟ͞Μ͸։ൃͱ͔શؔ͘܎ͳ͍ ࢓ࣄ w ීஈɺΤϯδχΞ͕ͲΜͳ࢓ࣄΛ ͍ͯ͠Δ͔ͷཧղʹ΋ͭͳ͕Δ w

    ίʔυॻ͘ͷ͸΄ͱΜͲҰਓͰ׬ ݁ͯ͠͠·͏ͷͰԞ͞Μʹʮਃ͠༁ ͳ͍ʯײ͕ग़ͯ͘Δ w lؔΘ͍ͬͯΔzײɺνʔϜײ w ೉ͦ͠͏ɺྑ͘෼͔Βͳ͍ͱࢥ ΘΕͳ͍Α͏ʹ