ホームページ >バックエンド開発 >PHPチュートリアル >Parseからアプリを保存する方法
著者: Reinder de Vries、原文リンク、原文日付: 2016/01/09
翻訳者: Indigo K;ドラフト: numbbbb
編集者注: この記事は、LearnAppMaking.com の独立系アプリ開発者である Reinder de Vries によって書かれました。
今年 1 月 28 日、Parse はサービスを終了すると発表しました。彼らは、提供してきた「バックエンド サービス」を徐々に縮小しており、2017 年 11 月 28 日にサービスを完全に終了する予定です。
2011 年以来このサービスに依存してきた 50 万人以上の開発者にとって、これは本当に悪いニュースです。 Jameson 氏がブログ投稿で指摘しているように、開発者は信頼が裏切られたと感じています。
Parse は 2013 年に Facebook に 8,500 万ドルで買収されましたが、今や「ビッグ 5」のリーダーは冷酷にも開発者のアプリケーションのサポートを打ち切りました。
2013 年に Parse を買収することは実際には非常に危険でしたが、当時 Facebook はモバイル市場で足場を築く必要があったため、買収する必要がありました。 Facebookの最新決算報告によると、2016年第4四半期のモバイル広告は2014年と2015年に比べて52%増加し、同社がモバイル市場で足場を築いたことを示している。
Amazon、Microsoft、Google によるクラウド サービスの競争は激化しており、Facebook にはもはや Parse は必要ないと思われるかもしれません。ビジネスの観点からは完全に同意しますが、開発者の観点から見ると、これは悪い決定です。
本当にそうなのでしょうか?
アプリを作る前は、Web サイトを開発していました。無数のウェブサイト。 HTML、CSS、JavaScript、PHP、MySQL など、必要なスキルをすべて学びました。当時は鳥肌が立つようなコードのクオリティとエレガントさでしたが、試行錯誤を繰り返しながら、最終的には高品質な Web サイトを出力するテクニックを習得しました。
毎年、私は自分の技術を最新の状態に保つために Web アプリを開発しています。私の仕事でも使用できる、より新しくて高度なツールがたくさん登場しています。私は jQuery から Angular、そして React に移行し、非常に多くの JavaScript フレームワークに触れ、パッケージ管理ツールと GitHub (SourceForge、他に誰か?)、そして PHP 4 から PHP 5、PHP 5.6、そして次期 PHP 7 の出現を目の当たりにしました。 MySQL テーブルが継ぎ目で破裂してしまったので、Elasticsearch と Mongo に切り替えました。
少し前、ニュースレターの電子メール サインアップと TestFlight へのテスト招待を自動化したいと考えていました。ニュースレターを購読して購読を確認すると、この自動プロセスにより TestFlight のテスト グループに自動的に追加されます。私は FastLane ツールとそのボード コンポーネントについてある程度の知識を持っており、このグラフィカル ボード コンポーネントの HTML ページにはハイジャックできる POST URL エントリ ポイントが必要です。実際に、テーブルから購読者の電子メール アドレスを取得し、搭乗テーブルに入力します。 TestFlight のテスト グループにサブスクライバーを追加するなど、残りの作業は Boarding が行います。
問題が 1 つだけあります。搭乗フォームは CSRF で保護されており、リクエストごとに一意のトークンが必要です。これらのトークンはサーバー側で生成されるため、自動化プロセスで取得する方法はありません。
私はボーディングのソース コードにアクセスできるので、理論的には CSRF 保護を無効にしてこの問題を修正できます。注意点が 1 つあります。ソース コードは Ruby で書かれていますが、私はこれまでの人生で Ruby コードを 1 行も見たことがありません (いや、もしかしたら 1 行もあるかもしれません)。
バックエンド プログラミングの広範な経験のおかげで、なじみのないテクノロジーを習得することを恐れません。長年にわたる試行錯誤の結果、Web がどのように機能するかを深く理解できるようになりました。私は何も知らなかったこのテクノロジーに取り組むことに恥ずかしがらず、むしろ深く掘り下げました。
これまで見たことのないさまざまなライブラリとその奇妙な名前を比較検討した結果 (そんなものなのでしょうか?)、ついに CSRF 保護機能を管理するファイルを見つけました。最終的に、この機能をオフにすることはコントローラーを空にすることと同じであることがわかりました。
成功するほとんどすべてのアプリケーションは、何らかのバックエンド サービスを使用してユーザーを接続し、サーバー上にユーザー データを保持します。
私が出会ったり指導したりする開発者の多くは、バックエンド プログラミングについての十分な理解を欠いています。非常にシンプルなダッシュボード上で Parse の設定項目を設定し、クエリ文を書くだけで、データが「そこにある」と考えます。クラウドで何が起こっているのか知りたい人がいるでしょうか?
私はよく Parse を「アプリケーション用のスプレッドシート」として説明します。重要なのは、Parse はアプリのバックエンド サービスを提供し、そのダッシュボードは Google スプレッドシートと同じくらいシンプルです。データをクエリするためのステートメントを記述する必要はなく、代わりに次のような単純なメソッドを使用できます。
これも Parse のせいかもしれません。 PFQueryTableViewController は使用するのが簡単すぎるだけでなく、非常に危険でもあります。バックエンド コードをアプリケーションのビュー コントローラー (既に ViewModel になっている) に直接関連付けます。 Parse から Firebase に移行したい場合でも、コードとバックエンドは密接に結合されているため、移行前にアプリケーション全体を書き直す必要があります。
Parse の PFObject クラスにはマッピングが組み込まれているため、ネイティブの Swift String オブジェクトのように文字列データを直接使用でき、Parse SDK はこれらのデータをインターネット経由で送信できるデータに内部的に変換します。ユーザー向けコードで PFObject インスタンスを使用している場合、将来的にそれを新しい「サービスとしてのバックエンド」SDK に置き換えるのは困難になります。
独自のバックエンドを最初から構築している場合は、たとえば true (ブール値) は JSON にエンコードされるときに true (文字列) に変換されることを知っておく必要があります。その JSON データがアプリに到着すると、期待していた Bool 型ではなく String インスタンスを扱うことになります。 Swift には素晴らしい型システムがありますが、オプションの if let バインディング ステートメントは不一致な型を処理できません。問題は解決しません。
では、Parse の閉鎖はどのようなメリットがあるのでしょうか?これは、実験を開始し、バックエンドのブラック ボックスをさらに深く掘り下げて、コードを再びこのようなものから保護する絶好の機会です。
次にアプリを開発するときは、これら 3 つの方法を念頭に置いてください。これらを使用すると、Parse のシャットダウンのような問題が再び発生した場合に身を守ることができます。アプリの継続的な成長と成功に不可欠なサードパーティのサービス プロバイダーを 100% 信頼しないでください。
Parse には、Firebase などの類似したプロバイダーがいくつかあります。 Parse がシャットダウンするまで、Firebase について聞いたこともなかったかもしれません。
素晴らしいのは、これらのサービスのほとんどは、あなたが探しているものを知っているということです。 Google で「パース シャットダウン (翻訳者注: パース シャットダウン)」または「パース移行 (翻訳者注: パース移行)」と検索すると、サービスへの移行を求める関連性の高い Google AdWords 広告が多数表示されます。こんなことはしないでください!
代わりに、代替案のリストを作成する必要があります。そこにあるものに慣れるように努めてください。万が一に備えて、信頼する必要があるプロバイダーと代替プロバイダーのリストを作成してください。スーパーマーケットが主要な牛乳供給業者が倒産した場合に備えて予備の牛乳供給業者のリストを作成するのと同じように、取引先の企業のリストも作成する必要があります。
もちろん、リストにある代替ベンダーで自分に関連するテクノロジーや SDK について調査することもできます。 Urban Airship は高すぎると感じたため、Urban Airship に代わる無料のプッシュ プロバイダーを探し始めるまで、OneSignal についてまったく知りませんでした。
これは何千回も聞いたことがありますが、Model-View-Controller (翻訳者注: Model-View-Controller) という言葉は依然として意味を持ちます。私たちは Model-View-Whatever (翻訳者注: Model-View-Anything) に慣れてきましたが、実際の MVC の概念は、コントローラーはビューを構成できず、ビューはモデルを操作すべきではないというものです。
Cocoa Touch フレームワークでは MVVM (Model-View-ViewModel) を使用しないことは困難ですが、だからといって、モデル コードとビュー コントローラー コードを緊密に結合する必要があるというわけではありません。
プログラミング理論には、カップリングとカプセル化という 2 つの原則があります。 2 つの密結合クラスを使用するということは、ClassA が ClassB の内部機能について多くの仮定を行うことを意味します。
車とドライバーを想像してみてください。ステアリングコラムがエンジンに直結しているため、ドライバーは車の前部に座りますが、突然ドライバーが車の後部に座って運転したらどうなるでしょうか。これは絶対にうまくいきません。もちろん、このような状況は現実には決して起こりませんが、コード内には常に存在します。
密結合に対する保護の 1 つはカプセル化です。これは、各クラスに、speedUp() や steerLeft() などの厳密に定義されたメソッドのセットがあることを意味します。可燃性エンジンを利用することで、ドライバーが燃焼室にガソリンをさらに送り込む代わりに、speedUp() を呼び出すだけで済みます。この方法では、ドライバーはエンジンがどのように動作するかについての複雑な知識を知る必要がなく、安全であることがわかっているメソッドを呼び出すだけで済みます。
このエンジンを燃焼室のない電気エンジンに置き換える場合、ドライバー コードを変更する必要はありません。ドライバー コードは、injectGasMixture()、gasMixture、およびスパークタイマー(訳者注:混合ガソリンの噴射、混合ガソリン、スパークタイマー)。
デカップリングとカプセル化を理解するのが難しいと感じる場合は、それらを責任であると考えてください。運転するのは誰の仕事ですか?ドライバ。車を前進させるのは誰の仕事ですか?エンジン。
当你正在编写一个有后端能力的应用时,要清楚地定义组件以及组件的职责。创建一个在后端代码和前端代码之间只起媒介作用的中间件。前端代码基于你自己的类构建,就像 Car,后端代码处理你用到的后端 SDK 并且使用类似 PFObject 的类。
中间件的工作是沟通前端和后端。假使你的后端代码过时,你可以替换中间件的代码让它使用新的后端 SDK,无需重写前端代码。
第三种也是最后一种方法是减少代码耦合。Adapter Pattern(适配器模式),比互联网自身还要老,是一个面向对象编程的模式。这是一套编程设计规则,可以用它来将两个不相容的类变得相容。
这类似于构造一个“ wrapper(封装器)”,不只是暴露资源接口(像是封装一个 REST API ),它还会在两个不相容接口间制定一套规则。在很多编程语言里这些规则叫接口(JAVA 和 PHP),在 Swift 和 Objective-C 中它们叫 protocols(协议)。
你一定知道 Swift 的范型,对吗?如果有个东西游起来和叫起来像一只鸭子,那么它一定是只鸭子。Adapter Pattern(适配器模式)也有类似机制。要让 ClassA 和 ClassB 解除耦合,你需要构造一个 ClassA 的适配器,而不是直接在 ClassA 里调用 ClassB。
这个适配器类包含有关 ClassA 如何工作的复杂知识。适配器类也遵循一个协议。这个协议说:“你可以确定我有 X,Y 和 Z 方法”。
ClassB 不知道 ClassA。它只知道它想要一个遵循适配器协议的实例。它不在乎这个实例是不是个鸭子,只要它游起来叫起来像个鸭子就行了。
使用适配器有什么好处?假设你原来的 ClassA 代码废弃了,你只需要找另一个类(例如另一个 Parse 的替代品)并且为这个类写一个适配器。只要这个适配器遵循协议,也就是你之前制定的规则,ClassB 依旧能够工作。
事实上,你可以写一个带有下面这个签名的方法的适配器( MyTwitterAdapter):
class MyTwitterAdapter:AnyTwitterServiceProtocol{ func getTweetsWithUser(user:User, withPage page:Int = 0) { ...
协议( AnyTwitterServiceProtocol)包含了与上面一模一样的方法签名,但是它没有任何逻辑或者方法实现,只是定义了规则。
protocol AnyTwitterServiceProtocol{ func getTweetsWithUser(user:User, withPage page:Int = 0); ...
前端代码( MyTweetsViewController)有一个未定义类型的变量 twitter,这个工厂方法可以保证当你更换适配器的时候你只需要替换类的名字一次(或两次)。
如果你将 twitter 类型严格定义为 MyTwitterAdapter,你的代码中可能还有很多耦合处。这样的话,如果你要将适配器替换为一个新的适配器,还是需要更新大量代码。
一旦你设立了这段检查机制,就可以测试这个你正在工作的实例 twitter 是否遵循 AnyTwitterServiceProtocol。
if let _twitter = twitter as? AnyTwitterServiceProtocol{ // Yes, it conforms}
你的前端代码再也不用关心 twitter是否是 Car、 FooBar或 Facebook类型,只要它遵循了 AnyTwitterServiceProtocol就行。它只想知道这个实例是否有一个方法叫 getTweetsWithUser:withPage:。
注:假设你真的需要严格定义 twitter 的类型,可以使用协议作为类型,这样你也能使用泛型。
现在你已经学会了怎么改善业务代码、怎么处理你依赖的供应商以及保护你的代码,我想你已经明白怎么应对类似的危机了。
你是不是正要转到 Firebase ?你应该知道 Firebase 属于“五巨头”中的 Google。虽然 Parse 关闭不意味着 Firebase 也会关闭,但依赖一个新的供应商会让你的应用和之前一样脆弱,除非你想办法保护你的代码。
学习后端编程是一个好办法。Parse 已经发布了一个优秀的替代产品,Parse Server,你可以在其上运行你自己的服务器(只要它可以运行 NodeJS 和 MongoDB)。在下面的文章中我会向你展示如何将一个简单的应用(包括 Heroku 和 MongoLab)从 Parse 迁移至 Parse Server。
继续阅读: 指南: 如何将一个简单的应用(包括 Heroku 和 MongoLab)从 Parse 迁移至 Parse Server
另一个相对容易的练习是将你的推送通知部署到两个服务中,不要把鸡蛋放在一个篮子里。实现推送服务供应商的客户端 SDK 相对来说比较容易,通常你只需要发送唯一的 ID 并建立一个段。
アダプター パターンを使用して、フロントエンドで使用する統合インターフェイスを作成します。プロトコルを定義して、実際のアダプターをフロントエンド コードから切り離します。代替プッシュ通知プロバイダー (Urban Airship、Mixpanel、Pusher、PushOver など) を選択し、代替アダプターを作成します。アダプターがこのプロトコルに従っていることを確認し、サービスのクラッシュをシミュレートして、アダプターを再デプロイする方法を確認します。それで、あなたの問題は解決しましたか?
ブラックボックスを詳しく調べることを恐れないでください。独自のバックエンド REST API を作成することは素晴らしいアイデアであり、実際に実行すれば多くのことを学ぶことができます。
Crashlytics が Twitter によって所有されていることをご存知ですか?どのサービスもダウンしている可能性があります... Crashlytics が何をするのか、どのように機能するのかを確認してください。これが、常に収益を上げられる安定した信頼できるビジネスを構築する唯一の方法です。
次に、あなた自身がウサギの穴に落ちなければなりません。
Reinder de Vries は独立したアプリ開発者であり、LearnAppMaking.com で意欲的な開発者やマーケティング担当者にアプリの構築方法を教えています。彼は 50 を超えるアプリケーションを開発しており、彼のコードは世界中の何千人ものユーザーによって使用されています。コーディング以外のときは、濃いエスプレッソと旅行を楽しんでいます。
この記事は SwiftGG 翻訳チームによって翻訳され、著者から翻訳の許可を得ています。最新の記事については http://swift.gg をご覧ください。