Furyu
[フリュー公式]

Tech Blog

フリュー株式会社の技術ブログです

2018年06月25日

furusin

フリュー主催の勉強会(京都Devかふぇ#2)を開催しました!

こんにちは。ピクトリンク事業部の古川です。

前回に引き続き、フリュー主催の勉強会を開催しましたのでご報告します。

前回のレポートはこちらから

京都Devかふぇ#2 〜WWDC & Google IO総復習会〜

今回も30名以上とたくさんの方々にご参加頂きました!

新たな取組みとして「突発LTやりたい人がいたらどうぞ!」としてみました。

実際には手は上がらず私が登壇しましたが、発表における門扉を広くできたらなと考えています。

 

勉強会の様子

15分発表枠

トップバッターは弊社の足立より、WWDC 2018 のまとめを発表しました。

IMG03135

WWDCの情報は日本語では意外と多くなく、情報を欲している方が多かったようで、皆さん食い入るように聴かれていました。

発表資料はこちら

 

2人目は @kwmt27 様より、Google IO 2018で発表されたNavigation Architecture Component についての発表でした。

Navigation Architecture Component(京都Devかふぇ バージョン) from Yasutaka Kawamoto

実際にGoogle IOに参加されただけあって、非常にわかりやすく、かつ深く解説されていました!

XcodeのStoryboardに似ており、注目されているコンポーネントです。

 

3人目は@AkihiroTokai 様より、実際にGoogle IO 2018に参加されたレポートの発表でした。

現場の写真をたくさん見せて頂き、当日の臨場感をたくさん感じられる発表でした!

LT大会

1人目は弊社の森嶋より、WWDCで発表されたiOS12におけるUITextContentTypeについての発表でした。

IMG03137

ユーモアを交えた発表で、会場からは笑いがあり、LT大会ならではな感じがあってとてもいい雰囲気でした!

UITextField iOS12 from kenta morishima

最後は私がGoogle IOでも会場で実際に触る場所が設けられた、Google Codelabsを実際に触ってみた感想について発表しました。

意外とハマり所もありますが、非常に良いツールですので皆さんにも触ってみて頂きたいです。

Google Codelabsをやってみた from furusin

 

懇親会の様子

 

簡単ですが食事を用意し、前回に引き続き好評頂きました!

IMG_20180615_195730749

IMG_20180615_195711721

今回から、ティーンズやソフトドリンク派な皆さん向けにステッカーを用意しました。

IMG_20180615_200501595

これで間違ってお酒を勧めてしまい「あああ・・・すみません・・・」を減らす対応ができました。

まとめ

参加した皆さんもたくさんTwitterでツイートしてくださり、とても盛り上がった勉強会となりました!

懇親会でお話した方から「とても楽しいからまたやってほしい!」というお声を頂きましたので、

是非ともまた開催したいと思います!


2018年06月4日

furusin

フリュー主催の勉強会を開催しました!

IMG02937

 

こんにちは!ピクトリンク事業部サービス開発2課の古川です。

5/25(金)に、先日告知していました勉強会を開催しました。

30名程度集まれば大成功かな、と思っていたところに55名もの方が参加してくださり大盛況となりました。

また、ハッシュタグ #KyotoDevCafe でもたくさんツイートがありました。

今回はそのレポートをお送りします。

勉強会の様子

大盛況となったことから、多少席が詰まってしまったことは申し訳ない限りです。

ですが皆さん発表者のお話を食い入るように聞かれていました!

こちらは始まりの挨拶の様子です。

IMG_20180525_190353

初めてAndroidアプリを作ってみた話やiOSのニッチな話、

Swiftをアプリからサーバサイドまで使い倒した話まで幅広く発表いただきました!

懇親会の様子

簡単ですが弊社よりケータリングを用意しました!

IMG02949

カツサンドが非常に好評でした!

運営メンバーも美味しくいただきました。

また、懇親会中に弊社荒木より突発的LTがありました!

IMG_7554

このLTは本当に突発的でしたが意外とウケていたようで、非常に好評でした!

最近流行りのVRに関した発表で、Daydreamを持ってきて装着していました。

 

全体を通して

今回は「モバイル」という少し広めのテーマでの開催となりましたが、Android/iOSのバランスがが丁度よく、開場も盛り上がっていました。

また、難易度もコアな発表から初心者向けのものまで幅広く、多くの方に楽しんで頂ける内容になり、

運営として非常に嬉しい限りです。

初めての開催でしたので拙い部分もあったかと思いますが、どんどん回数を重ねてより良い勉強会にしていきたいと思っております。


2017年01月30日

adachi

try! Swift Tokyo 2017 に協賛します!!

こんにちは
コンテンツ・メディア第1事業部の足立です。
ピクトリンクというプリントシール機で撮影した画像データを使ったコミュニケーションアプリのiOS版の開発を担当しています。

 

弊社は2016年に引き続き3月2日から行われる try! Swift というイベントにシルバースポンサーとして協賛させていただきます。

 

try! Swift

HP: https://www.tryswift.co/tokyo/jp
スケジュール: https://www.tryswift.co/tokyo/jp#schedule

「try! Swift」はプログラミング言語Swiftに関するコミュニティ主催のカンファレンスです。
ベストプラクティス、アプリケーション開発、サーバーサイドSwift、オープンソースSwiftなど、Swiftに関する技術情報とコミュニケーションを目的に2017年3月2日〜4日の3日間にわたって開催されます。

 

去年は3日間全て講演でしたが、今年は3日目は参加者によるハッカソンを行うようです。
また、登壇者の講演とは別に、try! Swift の参加者によるライトニングトークセッションも用意されています。

 

登壇者による講演もですが、ライトニングトークでどの様な発表を聴けるか楽しみですね

 

Swiftを使用した開発について

弊社の手掛ける ピクトリンク というiOSアプリ(Android版, Web版あります)では、 Swift を使用して開発を進めています。

 

2014年のWWDCで Swift のBeta版が発表された頃、アプリの全面的なリニューアルを行っていました。
その頃に思い切って「Swiftへ移行しましょう。今変えないでいつ変えるんですか」的なことをチーム内で提案したのを覚えています。
発表まもないうえに初めての言語でしたので、 Objective-C からの作り変えに楽しくも辛い(?)日々が良い思い出です。

 

SwiftVersion 1.0, 2.0 そして Version 3.0 と約2年をかけてバージョンアップされて来ました。
バージョンアップによる言語仕様の変更などに伴う修正などは覚悟してしていましたが、大幅な仕様変更には泣かされました。
ですが Objective-C から Swift へ移行することで、Optional・Optional Chainning などを利用できる様になり、開発効率や可読性などが大幅に上がりました。
今ではあの頃に Objective-C から Swift へ移行しておいて本当によかったと思っています。

 

まだ、Swift が怖くて手が出せてない方や、Objective-C からの移行コストを気にして Swift に移行できていない方がいるとおもいますが、
今、この Tech Blog を見た瞬間から1行、1機能でも良いのでぜひ Swift で実装してみてはいかがでしょうか!?

 

みなさんもぜひ try! Swift してみませんか。
Swift 楽しいですよ!!

 

去年の記事: try! Swiftに協賛します


2016年07月6日

maeda

AppStore自動更新購読のレシートについて

こんにちは、コンテンツ・メディア第1事業部の前田です。

業務で自動更新購読型のAppStore課金を取り入れたのですが、AppStoreから返却される自動更新購読レシートの中身がよく分からず行き詰まることがありました。今回は自動更新購読レシートを調べた中で分かった仕様や消耗型・非消耗型レシートとの違い、ユーザの課金状態によってレシートの内容はどう変化するかについて書いていきます。

AppStore自動更新購読のざっくりとした流れ

MjPZWUULH3UMZYQP-24407

上図が購入から完了までの流れになります。今回はレシートの内容についてなので詳細には触れません。

この図中にあるAppStoreAPIから返却された検証結果レシートの内容について詳しく見ていきます。

レシート仕様

AppStoreから返却されるレシート例を以下に示します。

レシートパラメータの各値は伏せ字にしておきます。見難いかと思いますがご了承下さい。

※レシートデータの内容はiOSのバージョン毎に異なりますので注意して下さい。

各パラメータ内容

重要なパラメータのみ説明します。

プロパティ 子プロパティ 内容
status レシートが正しければ0、異常であれば対応したエラーコードとなる。なお購読の有効期限が切れても0が返る。
receipt in_app latest_receiptの詳細となる。下記「in_app~消耗型・非消耗型プロダクトとの違い~」で詳しく説明。
latest_receipt_info 今まで購入した自動更新のレシートがすべて入る。下記「latest_receiptについて」で詳しく説明。
product_id なんの商品(たとえば1ヶ月購読と半年購読があったりした場合)を判別できるもの。
transaction_id 購入または更新に対するID。latest_receipt_infoの配列毎に値は異なる。
original_transaction_id product_idを購読購入したということに対するID。購読購入→一度やめる→また1年後に購入とした場合でも値は同じとなる。下記「original_transaction_idの検証で詳しく説明」
purchase_date transaction_idに対応した購読開始日時。
original_purchase_date transaction_idに対応した購読購入した日、または更新した日時。更新というのはApple側が更新をかけた日時であって、購読更新日(この日からまた購読)という日時ではない。
expires_date transaction_idに対応した購読期限。
cancellation_date Appleを通してキャンセルされた場合に入る。設定から自動更新オフした場合とかではない。ここに値が入っている場合は有効期限内であっても購入はキャンセルされているので注意。
latest_receipt 自動更新購読型にのみ存在する。アプリから渡され、レシートデータとしてAppStoreAPIへ渡す。ある購読情報をBase64エンコードしたもの。

in_appについて~消耗型・非消耗型プロダクトとの違い~

自動更新購読のレシート構造は消耗型・非消耗型プロダクト(ゲームなどによくあるアイテム課金等)のレシート構造といくつか違いがあります。非消耗型プロダクトのレシートは、in_appの中に課金したアイテムの情報が入ってきます。ですのでそのとき購入した情報はin_appを見れば分かるのですが、自動更新購読レシートはそうとは限りません。自動更新購読のin_appにはlatest_receiptに紐付く購入情報が入ってきます。latest_receiptが一番最新の購入情報であればin_appには最新の購入情報が入りますが、古いlatest_receiptであればin_appには古い購入情報が入ってきます。

具体的には下図のようになります。下図では自動更新購読の内容を「一ヶ月の定期購読課金」としています。

MjPZWUULH3UMZYQP-F3A95

 

 latest_receipt_infoについて

latest_receipt_infoは一見すると最新のレシートのみが入ってくるようにみえるのですが、ここにはアプリ内で購入した自動更新のレシート情報が全て入ってきます。一度更新をやめてしばらく経ってから再度購読を開始した場合でも、以前の購読レシートは一緒になって返ってきます。また、アプリ内にプロダクトが複数あり(300円コース、1000円コース等)、かつ両方で課金したことがある場合には両方の情報が入ってきます(下図参照)。

MjPZWUULH3UMZYQP-BA574 (1)

original_transaction_idの検証

以下図にある3つの状態でレシートを取得した際、original_transaction_idの内容について検証した結果をまとめます。

ここでは、自動更新購読の内容を「一ヶ月の定期購読課金」としています。

 

①1月1日に購読を開始し、2月、3月も購読を更新している場合

MjPZWUULH3UMZYQP-AB86F

latest_receipt_infoには3ヶ月分の購読情報が入ってくる。また、この3つのoriginal_transaction_idは全て同じものである。

 

②1月1日に購読を開始。1月5日に自動更新を解除したが、1月10日に更新解除をやめ、2月、3月と購読した場合

MjPZWUULH3UMZYQP-6EE2D

latest_receipt_infoには3ヶ月分の購読情報が入ってくる。また、この3つのoriginal_transaction_idは全て同じものである。

 

③1月1日に購読を開始し、1月5日に自動更新を解除。3月1日に購読を開始した場合。

MjPZWUULH3UMZYQP-7E69C

latest_receipt_infoには1月、3月の購読情報が入ってくる。また、この2つのoriginal_transaction_idは全て同じものである。

 

つまり、あるアプリ内で自動購読を開始すると、途中で更新解除→再度課金してもoriginal_transaction_idは全て同じとなります。じゃあどこで月々の購読情報を見分けるの?と言うと、transaction_idで見分けることができます。パラメータ内容にも書きましたが、transaction_idには購読が更新される毎に違う値が入ってくるからです。

感想

初めはレシートの中身がややこしすぎて全く分からない…と焦っていたのですが、実際に取得したSandboxのレシートを見てみることによって仕組みを理解することができました。今後自動更新購読を実装する際に参考になればと思います。

参考

In-App Purchaseプログラミングガイド

レシート検証プログラミングガイド

自動購読課金について【iOS編】- サイバーエージェント 公式エンジニアブログ

商標について

AppStore、In-App Purchaseは、Apple Inc.の商標です。


2016年05月26日

araki

Google Tag Manager でモバイルアプリのABテスト -ウェブテストの目的-

コンテンツ・メディア第1事業部の荒木です。ピクトリンクというアプリのAndroid版を作っています。今回は、Google Tag Manager(以下、GTM)でAndroidアプリのABテストを効果的に行うためにウェブテストの目的を設定します。ちなみに今回の記事の内容は、Androidアプリに限らずiOSアプリでも使えます。

GTMによるモバイルアプリのABテスト開始方法については、前回の記事(Google Tag Manager でAndroidアプリのABテスト -ABの出し分け-)を参照してください。

設定の概要

ウェブテストの目的は、各パターン(Aパターン、Bパターン)の優劣判定に使われます。GTMは、ウェブテストの目的を基準にして各パターンの優劣を判定します。GTMの「Google アナリティクスのウェブテスト」変数の編集画面から目的を設定することができます。

ウェブテストの目的

デフォルトでは、スクリーン数、セッションの長さ、例外数、クラッシュ数の四つから選ぶことができます。たとえば、スクリーン数をウェブテストの目的に設定していると、Google Analytics(以下、GA)で送信したスクリーン数が多いパターンが優秀と判定され、クラッシュ数を目的に設定していると、クラッシュ数が少ないパターンが優秀と判断されます。

GAの目標を作成する

さて、ここで特定ボタンのクリックイベントが多いパターンを優秀と判定したい場合を考えてみましょう。カスタムの目的を設定するには、GAの目標を利用します。GAにログインし、「アナリティクス設定」タブの「目標」を選択してください。このとき、アカウント・プロパティ・ビューがGTMのウェブテストと連携していることを確認してください。

GAの目標を選択

目標の設定画面に遷移したら、「+新しい目標」ボタンから目標の作成を開始してください。目標作成は「① 目標設定」「② 目標の説明」「③ 目標の詳細」の3ステップで実施します。

① 目標設定

「テンプレート」と「カスタム」から選びます。テンプレートは、プロパティ設定で指定されている業種で一般的に目標に設定されるものの候補を表示してくれるので、これから何を目標とすべきかわからないときに参考にしてください。今回は特定ボタンのクリックという目標がすでに決まっているので、「カスタム」を選択します。

② 目標の説明

ここでは、目標の名前とタイプを設定します。タイプとは目標の達成基準に関わるもので、全4種あります。以下は、各タイプの目標達成基準です。

  • 到達ページ:特定スクリーンへ到達したか
  • 滞在時間:滞在時間が設定した時間より長いか
  • ページビュー数 または スクリーンビュー数:1セッションあたりのPV数またはスクリーン数が設定した数より多いか
  • イベント:特定イベントが送信されたか

今回は、ボタンのクリックイベントを目標としたいので、「イベント」を選択します。

目標の説明

③ 目標の詳細

ここでは、 ②で選択した目標タイプごとの詳細設定を行います。今回は、イベントの目標詳細を設定します。イベントの詳細設定では、GAイベントのカテゴリ、アクション、ラベル、値についてそれぞれ条件を設定することができます。カテゴリ、アクション、ラベルは「等しい」「先頭が一致」「正規表現」で一致条件を設定します。値については、「超」「完全一致」「未満」で条件を設定できます。ここで設定した条件が全て満たされた場合に、目標達成となります。なお、空欄の条件は無視されます。

目標の詳細

GAの目標を目的に設定する

GAの目標作成が完了したら、GTMの設定に戻ります。「Google アナリティクスのウェブテスト」変数の編集画面で設定できるウェブテストの目的に、先ほど作成したGAの目標「特定のボタンをタップ」が追加されています。これを選択すれば、ボタンのクリック率が良いパターンが優秀と判定されるようになります。

GAの目標をテスト目的に

テスト結果の確認

テスト結果の確認は、GAで行います。GA左サイドメニューの「行動」→「ウェブテスト」から、ウェブテストの進捗や結果が確認できます。ウェブテストの目的で設定した基準の達成率(コンバージョン率)を元に、各パターンの優劣が判定されます。GTMの設定によっては、テスト終了時に成果の高いパターンに自動で固定したり、テスト中に徐々に成果の高いパターンに移行していくということが可能です。

ウェブテストの結果

おわりに

ウェブテストの目的を適切に設定することで、ユーザーの動向にリアルタイムに追従して、より適切な画面を出せるようになります。みなさんもウェブテストの目的を設定して、よりユーザーに楽しんでもらえるようなアプリを作りましょう!

以上です。