イッツァハローワールド

恥さらしていこうかなとか。

手作りモーダルダイアログ(もどき)を作る

僕はできるだけ標準のUIつかいたいひとなのですがゲームを作るにあたり、全画面カスタムUIを作る必要性を(勝手に)迫られたのでした。

ペーパーなプロトタイプやモックを作って見た目を吟味するまでは楽しいんだけど、いざ作るとなると結構壁がありました。
そんで手間のかかることかかること...

モーダルダイアログとか関数一発呼べばいいやつを画面から作るとか...
はじめは、どうすんだこれってかんじでした。


この記事では手作りのモーダルダイアログ(もどき)を作ったやりかたを備忘録します。

やったこと

  • ダイアログ用のビューをこしらえる
  • ダイアログ用のビューはディスプレイいっぱい描画して、下のレイヤーを触れなくしておく
  • 親ビューからの呼び出して、親ビューにダイアログ用のビューを重ねる
  • ダイアログのボタン押下でビューを消す

イメージはこんな感じ
f:id:hanamiju:20150211025725p:plain

絵に悪意はない('A`)
注目すべきはダイアログの周りも描画しているところ。
黒の透過40%で塗りつぶしています。これで重ねると陰影で立体感がでるわけ。

こんくらいならそんなに頑張らなくてもできる。

画像作る

f:id:hanamiju:20150211031152p:plain

今回冗談でWindows8テイスト作った。(8つかったことない...)

クラスをつくる

ViewController ... 親ビューのViewController
CustomDialogViewController ... ダイアログのViewController

Story Boardつくる

f:id:hanamiju:20150211033625p:plain

とりあえずこんなかんじ。
親ビュー左上のパワーボタンが押したら「終了しますか?」ってダイアログでるようにします。
ダイアログのOK,キャンセルボタン,右上xボタン押したらダイアログを閉じます。
iPhoneの電源オフはしませんw)

ここで注意すべきは、ダイアログ側のレイヤー構成です。
CustomDialogViewControllerのviewを透過してしまうと全体が透過されてしまうのでダイアログの絵も透過されてしまいます。
なので以下のことをします。

  1. CustomDialogViewControllerのviewはClear Color(alphaは1.0)にする
  2. CustomDialogViewControllerのviewの下にUIViewを敷き、こいつを透過する。(今回はDark Gray Colorのalpha0.4)
  3. ↑の上のレイヤーにダイアログのイメージ以下ボタン等をおく(↑のビューの中に置いてしまうとやっぱり透過します。)


レイヤー構成はこんなん↓(TransparentViewと他が同階層なのに注目)
f:id:hanamiju:20150211041804p:plain
(拡大縮小するとレイアウトが崩れるのでもう一個viewを挟んだりしている。)


あとはCustomDialogViewControllerを選択してStoryBoardID振っておきます。
今回は"CustomDialog"で。
f:id:hanamiju:20150211034354p:plain

Outletをつくる

ダイアログのTitleとContentsラベルは親でいじれるようにOutletにします。
xボタンもOutletにして表示非表示を切り替えられるようにしてもいいかもしれません。

コードを書く

ダイアログビューから書きます。

// CustomDialogViewController.h
#import <UIKit/UIKit.h>

@interface CustomDialogViewController : UIViewController
- (void)setContents:(NSString*)contents;
- (void)setTitle:(NSString *)title;
@end

ダイアログに表示する文字列のアクセッサメソッドを書きます。

// CustomDialogViewController.m

#import "CustomDialogViewController.h"
@interface CustomDialogViewController ()
{
    NSString* _title;
    NSString* _contents;
}
@property (strong, nonatomic) IBOutlet UIButton *mExitButton;
@property (strong, nonatomic) IBOutlet UILabel *mTitleLabel;
@property (strong, nonatomic) IBOutlet UILabel *mContentsLabel;

- (IBAction)okButtonPushed:(id)sender;
- (IBAction)cancelButtonPushed:(id)sender;
- (IBAction)exitButtonPushed:(id)sender;

@end

@implementation CustomDialogViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _mTitleLabel.text = _title;
    _mContentsLabel.text = _contents;
    // Do any additional setup after loading the view.
}

// OKボタン押下
- (IBAction)okButtonPushed:(id)sender {
    [self closeDialog];
}

// キャンセルボタン押下
- (IBAction)cancelButtonPushed:(id)sender {
    [self closeDialog];
}

// xボタン押下
- (IBAction)exitButtonPushed:(id)sender {
    [self closeDialog];
}

// 内容文字列入力
- (void)setContents:(NSString*)contents {
    _contents = contents;
}

// タイトル文字列入力
- (void)setTitle:(NSString *)title {
    _title = title;
}

// フェードアウトしながら閉じる
- (void)closeDialog
{
    // 0.3秒かけてダイアログを透過する。0.3秒たったらVC,viewを削除する。
    [UIView animateWithDuration:0.3f
                          delay:0.0f
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                         self.view.alpha = 0.0f;
                     }
                     completion:^(BOOL finished) {
                         // このへんで結果の通知とかもやればいいよ。
                         [self removeFromParentViewController];
                         [self.view removeFromSuperview];
                     }];
}
@end
// ViewController.m

#import "ViewController.h"
#import "CustomDialogViewController.h"

@interface ViewController ()
- (IBAction)powerButtonPushed:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (IBAction)powerButtonPushed:(id)sender
{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    CustomDialogViewController* vc = [storyboard instantiateViewControllerWithIdentifier:@"CustomDialog"];
    
    // ダイアログの内容を書く
    [vc setTitle:@"Shutdown"];
    [vc setContents:@"電源落とすでー。"];
    
    // ダイアログを重ねる
    [self addChildViewController:vc];
    [self.view addSubview:vc.view];
    
}

setTitle, setContentsではCustomDialogViewControllerの文字列メンバ変数にダイアログに表示する内容を入力しています。
Outletに直接やろうぜってノリになりたいところですが、setTitleの時点でViewがロードされていないのでOutletたちはまだnilです。ですので、一旦メンバ(_title, _contents)に退避してダイアログクラスのViewDidLoadでラベルにテキストをいれるっていう方法をとります。

実行結果

ボタン押下前
f:id:hanamiju:20150211043657p:plain

ボタン押下後
f:id:hanamiju:20150211043726p:plain

うん。windowsっぽいな(目的が違う)

まとめ

  • そこそこ簡単なコードでつくれた。でももっと簡単な方法あると思う。教えて。
  • 上記コードだと結果の通知はNotificationとかでやんないといけない。呼び出し側毎に結果の通知を別々にしたいなら、あらかじめダイアログクラスにmessageをsetしてあげるとかの処理が必要です。
  • 見た目に満足した。

画面キャプチャをUIImageとして取得する方法

冬休みの宿題ということで、アプリを作っていました。

しかし、まだ世に出てきていません(リジェクト2回されている...
今、3回目の申請をしているところです。

初めてゲームを晒します。。作ったのは学校の課題以来...
癖になるクソゲーをコンセプトに作ったのですが、アプリについては世に出てから記事にしようかと。
また何回かリジェクトされそうな予感がするなあ。


というわけで、新しいことをだいぶやってきたので備忘録を起こします。
今回はアプリ内で画面キャプチャをUIImageとして取得する方法です。

ソース

+ (UIImage *)screenCapture:(UIView *)view {

    UIImage *capture;
	
    // ビットマップベースでグラフィックコンテキストを作成
    // 引数は左から、イメージのサイズ, 透過設定(NOで透過あり), 解像度のスケール(0でデバイス固有)
    UIGraphicsBeginImageContextWithOptions(view.frame.size , NO , 0.0 );
    
    // iOS7以降
    if ([view respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
    	// コンテキストにスナップショットをレンダリングする
        [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
    } else {
    	// ビューのLayerをコンテキストにレンダリングする
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    }
    
    // コンテキストをUIImageにする
    capture = UIGraphicsGetImageFromCurrentImageContext();
    // コンテキスト破棄
    UIGraphicsEndImageContext();
    
    return capture;
}


作成したアプリでは、SNSに投稿する際にさくっと結果画面をキャプって貼り付けたりしています。
上記はViewの中身をキャプっているので、いらないボタンとかのコントロールはキャプる直前にhiddenにし、イメージ取得後に戻しておくことで無駄なものまでキャプらないようにしました。

Lineスタンプ早くもリジェクト食らったの巻

くやしいいいいいい。
ので久々に投稿


先日、ノートへの落書きレベルの画力でLINEスタンプを作ったのです。

(感想)一晩でLINEスタンプ作ってみたって話 - イッツァハローワールド


しかし、思ったよりだいぶ早いタイミングでレビューが始まり(レビュー開始メールは来ていない)リジェクトされたのでした。
('A`)のう。
理由はこちら。

対象:画像

1.1.LINEが定めるフォーマットに合致しないもの
※イラストの内部が透過されている
IMG15(目)

該当スタンプを修正のうえ、再度リクエストをお願いいたします。


対象:スタンプ全体

1.5.スタンプ全体のバランスを著しく欠いているもの
※類似した構図・ポーズのスタンプが多数ございます
例:IMG01.09.19.20、02.15.39など色違いのキャラクター


申請されたスタンプは、ほとんどのスタンプが審査ガイドラインに該当いたします。

スタンプを修正のうえ、再度リクエストをお願いいたします。


いやああああああああああ。
バ○カヤロー!!!!色だけでだいぶ違うからいーじゃんかよー。

...てなわけで
使い回し作戦失敗ということで、これからコツコツ書き溜めていきますかねえ...

まとめ

以下の量産作戦はリジェクトされる。

  • 体の向きだけ変える
  • 文字だけ差し替える
  • 服の色、髪の毛の色だけ変える
  • 白目でごまかす

次回の作戦

ポーズが同じなのがいけない(構図は勘弁してくれ)らしいので

  • ムダに手だけポーズを入れてみる。
  • 後ろ向きを描く。

(懲りていない。。。)

PLA 3.3.12 でリジェクトされた

OHAYOで久々にリジェクトされた。
なんか↓のメッセージが来てた。読む気が起きない長文。

PLA 3.3.12

We found that your app uses the iOS Advertising Identifier but does not include ad functionality. This does not comply with the terms of the iOS Developer Program License Agreement, as required by the App Store Review Guidelines.

Specifically, section 3.3.12 of the iOS Developer Program License Agreement states:

"You and Your Applications (and any third party with whom you have contracted to serve advertising) may use the Advertising Identifier, and any information obtained through the use of the Advertising Identifier, only for the purpose of serving advertising. If a user resets the Advertising Identifier, then You agree not to combine, correlate, link or otherwise associate, either directly or indirectly, the prior Advertising Identifier and any derived information with the reset Advertising Identifier."

Note: iAd does not use the AdSupport framework, ASIdentifierManager, or the Advertising Identifier. Therefore they are not required for iAd implementations and should not be included in your app for iAd support.

If your app is serving ads, please:

  • Ensure that you have tested your app on a device, not just the simulator, and that you have removed all previous versions of your app prior to testing
  • Provide us the steps to locate ads in your app

If your app does not serve ads, please check your code - including any third-party libraries - to remove any instances of:

class: ASIdentifierManager
selector: advertisingIdentifier
framework: AdSupport.framework

If you are planning to incorporate ads in a future version, please remove the Advertising Identifier from your app until you have included ad functionality.

To help locate the Advertising Identifier, use the “nm” tool. For information on the “nm” tool, please see the nm man page.

If you do not have access to the libraries' source, you may be able to search the compiled binary using the "strings" or "otool" command line tools. The "strings" tool lists the methods that the library calls, and "otool -ov" will list the Objective-C class structures and their defined methods. These techniques can help you narrow down where the problematic code resides.


広告がらみ...かな。
ってことでググってみると結構関連記事が見つかった。

なんか、広告がないくせにAdvertising Identifierが使われているぞ。ってことらしい。
なんかiAdがずっと表示されない不具合に見舞われていたので先日のアップデートでNendに変更したのです。

日本以外では見れないのかもしれないですねー。
ということで「わしのアプリでは広告使ってるぞ。キャプ添付するから確認オナシャス。」とAppleに送信。
返事くるかな。

(追記)申請とおりました!

備忘録 データ型についてお勉強しました。

またまた備忘録。

配列や、辞書からデータを取り出すときにfor文使って律儀に(メンドクセと思いながら)こつこつかいてきてた人生だった。こんなふうに。

for (int i = 0; i < nCount; i++) {
    id hoge = [arrHoge objectAtIndex:i];
    // だらだらつづく。
}

高速やーつって。たまに↓もつかうけど、↑に使い慣れてしまったのとインデックスをデータ取り出し以外でも使いたいときがあったんであまり使わなかった。

for (id hoge in arrHoge) {
    // だらだら
}

ある本で勉強したところNSArrayにはenumerateObjectsUsingBlock:ってのがあることを知った。

enumerateObjectsUsingBlock: ブロックを使って配列のすべての要素にアクセスする

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block

objにArrayから取り出すオブジェクト、idxに配列のインデックス、stopをYESすると繰り返しを中断する。

enumerateObjectsWithOptions: usingBlock: 配列の全要素に逆順アクセス(オプション指定)

- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block

NSEnumerationOptionsにNSEnumerationReverceを設定すると配列を逆順アクセスする。

enumerateKeysAndObjectsUsingBlock: ブロックを使って辞書のすべての要素にアクセスする

- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))block

key と objのペアを順次取得する。

制作したアプリで上記の構文に置き換えてみた

あんまり慣れない...w
あと、パッパと置き換えられると思ったけど、ブロックの中身が多くなってしまって可読性悪くなってしまっているなあと思う所がいくつか。
これからは↑の関数を使う前提で設計していく努力をしよう。そうしよう。

(感想)一晩でLINEスタンプ作ってみたって話

iOS開発も一段落つきました(ちょっと飽きた)ので、LINEスタンプつくりたいと思いました。
以前から興味がありましたが、なかなかまとまった時間が取れませんでした。

ほんとは、コツコツネタを貯めていければいいのですが、
あんまり辛抱強くないので一気にやりたかったのです。

そういうわけで、昨晩でつくって申請までやりました。(もちろん公開はされていません)
ネタは空いた時間で考えていましたけど。

使った道具

  • サインペン(水性)
  • ノート
  • Adobe Illustrator
  • ひとつまみの絵心(数時間の準備)

まずはネタ探し

自作アプリのときもそうなんですが、前提条件として、
自分が使うこと('A`)

で考えました。そして考えついたのが

真顔スタンプ

ぼく、いきなりですがケータイで文字打つのが嫌いです。チョーめんどう。
なので、返信文書くのが面倒かつ、どうしても返信しないといけないときは絵文字とか一切使わず送信ボタンまで最速でリプライします。
だいぶ感情がこもっていません。いちおう"ワロタ"とかって書きますけど真顔。みんなそうだと思うけど。

そんな真顔な気持ちを込めれるスタンプを作ろうかと。
しっかし真顔な気持ちを生で送られるとおそらくバトルの火種になるので、絵はユルめしてドギツイ印象を避けるようにしようと思いました。

ちなみに真顔スタンプで探してみたらいくつかありましたw
しかし、上記のような根性の曲がったスタンプはありませんでした。さいわい。

よっしゃ作るか('A`)

絵を書く

まず困ったことに、LINEのスタンプって40枚作んないといけないんですね。いきなりハードル高め。

ぼく普段、絵は描きません。昔は似顔絵得意でしたよ。どうでもいいですけど。
それでも基本真顔=無表情だし、髪型だけ何パターンかつくって流用すればいいんじゃねえかと。
加えて、表情や髪の色、服の色を変えればそれなりにバリエーション多めに見えるんじゃねえのと考えまして、着々と量産のアイデアを膨らませていきます。この時点で他のクリエイターのみなさんへの敬意があふれます。

髪型のイラストをググったり雑誌見ながら抽象化し、絵に起こしていきます。
この時点でまだ練習段階。

f:id:hanamiju:20141116134354j:plain

↑x10枚ほど書いて練習します。
一旦鉛筆で下書きして、ペンでなぞってます。(ペンでなぞる練習)

イラレでの編集をできるだけ楽したかったので(&絵のクヲリティは一晩で上がるはずない。)書きながら抽象化していき、簡単に書ける方法を探っていきます。

清書&スキャン

無印の落書き帳はサインペンがにじんでしまったのでノートに清書しました。
f:id:hanamiju:20141116135049j:plain

絵はもちろんドヘタクソですが、「ユルい絵だから〜」とかっていいわけすれば何にも気になりません。次第に旨味すら感じます。

イラレに取り込んで色入れ+文字入れ

スキャンデータをイラレに取り込んで画像トレースします。

  • オブジェクト - 画像トレース - 作成 を選択してトレース
  • オブジェクト - 画像トレース - 拡張 でベクターデータ化

絵をベクターデータにした後は、ライブペイントツールをつかって色を付けます。
はじめて使ったけど便利ね。

f:id:hanamiju:20141116140044p:plain

こんなかんじで微妙に髪色、服の色を変えたり、白目むいたりしながら作っていきます。
この時点で本日の朝を迎えました。意外と出来ちまったよ。おい。

スタンプの申請

LINEクリエイターズマーケットでいよいよ申請です。

LINE Creators Market

まずログインして、口座番号の入力をします。
次にスタンプの登録です。以下を英語(デフォルト言語)とその他の言語で記載していきます。
ぼくは英語と日本語だけ記載しました。

  • スタンプ名
  • スタンプの説明

えいごー。超苦手なのでいろんな翻訳サービスを駆使して以下のように書きました。

f:id:hanamiju:20141116140633p:plain

(意訳:クソ生意気な奴にこの真顔スタンプを使って黙らせるといいよ!)
おこられるかな...

ちなみに日本語

f:id:hanamiju:20141116140820p:plain

名前が大変安直。

その後作ったスタンプ40枚とメイン画像とトークルームタブ画像をアップして作業終了!

審査終了まで

数日で審査終わるって勝手に思っていたけど、数が多い+審査はそれなりに厳しくやるそうで数週間くらいかかりそうです。
(追記)数ヶ月はかかるそうな...ww
リジェクトされないといいなー。ガイドラインは一応目を通しましたので大丈夫だと思うのですが。


審査ガイドライン - LINE Creators Market


ということで待ち。

感想

  • 意外と作れた。題材ごと量産プランを考える必要あるけど。
  • ひさびさに絵がかけて楽しかった。
  • あと女の子のボブが描けるようになってうれしい。

(iOS)グルメアプリ使わない人がグルメアプリをつくったよ。

また一週間以上空けてしまった...
っていうのもいろいろ作業していたからなんだけれど。
またその件はいつか記事にするってことで...


またまたアプリ作りました。
前回はネタに走りすぎたので実用的なもん作りたいなっておもってグルメアプリを。

作ったもの

https://itunes.apple.com/jp/app/zakkuri-jinno-qi-fendegohanwo/id930171614?mt=8&uo=4&at=10l8JW&ct=hatenablog

こちら、お名前の通りグルメをざっくり検索するアプリです。

目的

○ットペッパーとか、○るなびとかのアプリを使ったことがある方は共感してくれると思います。
あの圧倒的使いにくさ('A`)

だーいぶ、検索結果にたどり着くまで操作が必要なのですよ。
食べたいものが明確に決まっていて、かつお店だけきまってない人にはいいのかもしれない。
でも自分はめったにそんなこと思わない。(そのとき食べたいものがあったら大抵知ってるお気に入りの店にいく)
そうはいっても、「なんでもいいし絞るのめんどくせーやー」って全検索するとあんまりいいお店が出てこない。


男「今日のごはんどこにする?」

女「えー、あー、どこでもいいよー」

男「じゃあ、ラーメンいこう」

女「えー、ちょっとなー、ラーメン以外で」

男「うーん、じゃあマクドで」

女「やだ、それ以外」

(以下ループ)

みたいなことはよくあるかと思う。
なんでもいいんだけど気分とか(朝から脂っこいのはやだ、昨日食べた、とか)こだわり(ファーストフードはやだ、とか)ってあるよなあ。じゃあ、気分を入力してざっくりお店の候補を出して選んでもらおう。こだわりがあったら入力してもらえばお店をもっとしぼれるよっていうアプリ作ろうっていうコンセプト。
結構偏見で作っておりますww

目的のまとめ
  • クソ使いにくいグルメアプリたち(全部じゃないよ)
  • 今日のメシ「なんでもいい」は「なんでもよくない」ことが多い
  • ↑の原因は今の気分とその人のこだわりによるんじゃないか。(勝手に過程)
  • じゃあ、気分とこだわりでざっくり検索しようぜ。

デザイン

f:id:hanamiju:20141112015607p:plain

吹き出しふたつに「よろしく!」ボタンのシンプル構成。
ひとつめの大きい吹き出しUIは少し凝っているというか挑戦的なものにあえてしています。
3つあるメニューをあんまし一覧性がよくないカルーセルUIっぽく左右スワイプで選択します。

これは最適なものをひとつ選べ!てかんじでなく、アバウトに気分で選んでもらいたかったので一つ一つ流すように選択してもらいたいなっていう意図があります。(意図通りになるかは...って感じです...)
加えて、画面遷移少なくしてシンプルに見せています。

使ってみて慣れればハマる形かなーっておもってます。(慣れる前提のUIってどうなの...w)
多分はじめて使う人とかはスワイプするってわからないことうけあいなのでガイド機能組み込んだりして工夫はしています。

こだわり選択

小さい吹き出しの方はボタンになっていて、こだわりを選択できます。
f:id:hanamiju:20141112022743p:plain

一部、現在申請中(近日バージョンアップ)の選択項目があります。

検索結果

f:id:hanamiju:20141112022725p:plain

地図にマーカーがボンボンささっているUIがよくあるけど、あまり好きでないのです。
多いと選びづらいしスマホだと詳細が選択しづらいから。
だったら現在地との距離だけ出しておいてお店の情報を載せる方がよいとおもってこんな画面にしてます。
とくに営業時間とかって一覧のうちに確認したいよね。文字数スペースキツめだけど。。

お店詳細

f:id:hanamiju:20141112023332p:plain

f:id:hanamiju:20141112023339p:plain

お店の詳細はタブ(SegmentControl)で切り替えます。アプリ間行き来するのめんどくさいよねっていう仮説から。
加えて次回バージョンアップでシェア機能つけました。

  • メール
  • TwitterDM
  • Facebook Messenger
  • LINE

ホットペッパーに掲載されているお店情報のURLと地図情報をシェアできます。
URLスキームって便利ね。

実装面

とくにそれほど技術的課題はなかったです。一番つまづいたのは上記UIのギミックです。
実装は平日夜と休日で1週間程度でしょうか。

アプリコンテストに出してみた

MA10っていうマッシュアップのイベントに応募してみました。せっかくホットペッパーAPIつかっているし。
MA10地区予選のハッカソンで負けているので記念受験的なひとりで何か作ろうと締め切りぎりぎりに応募しました。

結果はあたりまえの予選落ち。
思いのほかうまくアプリとしてまとまったのでちょっとくやしいんだけど、自己満足分は満たせたので良かったです。

応募時にランディングページとPV作ってみたんだけどこれも思いのほかいい出来になりました(こちらも自己満足)
せっかくなので載せる。

ランディングページ

http://hanamiju.net/zakkly/

使い勝手

実際、割と使えると思う。
先週上京した際使ってみたけどサッと予約までいけた。
けっこうざっくりな感じで検索かけているけど、超正確な検索でなくても結果として表示されてしまえば「あ、ここオシャレな店なんだ」て感じでユーザの背中押すのかなて思った。

あと、ホットペッパーってぐるなびとくらべて掲載店舗が少ない印象。だからクソ田舎な自宅の周りは全く店でないwww
かわりにぐるなびは店舗ごとの情報量にムラがあって店名、住所電話番号くらいの情報しかないものが多い印象。

その他

会社の先輩がAndroid版を作ってくれたんです。パッとトレースしてくれちゃったもんで実装力の差に愕然としました...
Androidな方も上記ランディングページからアプリ落としてみて下さい。

肩書きは「今日のごはんどこでもいい人向けグルメ検索アプリ」とかのが目を引くかな。ってこの記事書きながら思った。