Change before you have to.

androidアプリ開発、iosアプリ開発、rails、deep learning .etc.を使った社会実験。

ヤナティさんが考える価値について

一年ぶりの日記になってしまうけど、

久しぶりに書こうと思った理由はいくつかある。

文章を書くとついつい長くなってしまうので10分で切り上げる。

ところどころ読みにくい点はご愛嬌ということで。

 

一つはヤナティさんのブログを読んでいて色々思うことがあったのでアウトプットしようかなと思ったこと。

d.hatena.ne.jp

 

二つ目は本業で人と話すこと、動かすことが決定的に足りてなくて、周りにいる人を不幸にしないよう、伝えるということを大切にするためにも少しでもアウトプットをしていこうと思ったから。

 

三つ目は個人的に続けている社会実験の振り返り的な整理がしたいと思ったから。

昨年からやっているのは、ウェブというテクノロジーの枠内でどれだけの価値が提供できるのかという社会実験的なことをやっている。

 

具体的には

・金融系サービス

・ファッション系

・その他

の3つで、成果としては順に5:3:2くらいの割合で収入を得ることができている。

全部遵法性を厳格に守ること(大部分の時間を費やしてる)のと、あくまで実験なので本業(サラリー)に影響がないことをルールにしている。

 

f:id:ichonol:20180616213028j:plain

経済価値=本質?

最近思うのは人様からお金をもらうということについて、すごくよく考えるようになった。

例えば通販の類だと、物を作ることや売ることにフォーカスしがちだけど、商品を買ってくれたお客さんがその後、どうだったのかをすごく気になってしまう。

 

その商品のサイズはどうだっただろうか、使い勝手はどうだっただろうか、気に入っていただけただろうか、後悔していないだろうか、継続的に使ってもらえるだろうか、、

 

マーケティングをかじっていれば物を売ること自体はそんなに難しいことじゃないし、インターネットが発達してSNS掲示板でこれだけいろんな人とつながれる社会になった今、作る(正確には調達する)ことさえ特殊な技能はいらなくなっている。

 

だけど果たして、自分は対価に見合う価値を提供できているんだろうか

 

本質的な価値ってなんだっけ

f:id:ichonol:20180616213049j:plain 

正直、物を売る、コンテンツを提供する、時間を省略するという表面的な価値では世の中は満足させることはできないと思っている。

唯一の価値があるとすれば、それは自分が提供しているのはキュレーションだという整理をしているけど、果たしてそこにどこまでの価値があるんだろうか。

 

仮にキュレーションという価値を提供できているとして、それって結局どういうことなんだっけ。

 

キュレーションを自分なりの言葉で表現すると、物やサービスがあふれている今、数あるモノやサービスの中から自分の価値観でお客さんに商品を選んで提供することなんだけど、それって自分の中に提供したい価値=哲学がないと意味がないと思っていて、その哲学が揺らぐとサービスそのものは無価値になってしまう。

 

それは本業でもよくかんがえることなんだけど、例えばキュレーションサイトにおけるレコメンドエンジンに関わる人がいたとして、レコメンドエンジンの本質は類似コンテンツを作ることでも、ましてや文章や画像の類似性を比べたり並べることでもない。

そのコンテンツを見たユーザーが気持ちいいと思うコンテンツを、適切な並び順で提供することなんじゃないかな。

 

当たり前なんだけど、人間の脳はパラレルには考えられないので作り手というのはどうしてもそれを忘れがちになってしまう。

 

f:id:ichonol:20180616212826j:plain

 

 

 

価値を感じる場所は人それぞれ

でも、最近思うのは手段を目的とする人もいるということと、別にそれは悪いことではないんじゃないかなと思うようになった。

上のレコメンドの話でいうとすげーステキな類似性を評価する尺度を作ったり、それを実装することそのものが目的になる人がいてもいいんじゃないかということ。

 

エンジンを作る人、フロントを実装する人など多くの人が関わるサービスの場合、サービスそのもののファンダメンタルを正確に理解することは不可能だと思うので、その人たちをマネジメントする人が価値の根本の哲学を理解し、適切にハンドリングしていることが重要だと思ってる。 

f:id:ichonol:20180616212931j:plain

 

 

この類の話ってこの数年考えていて大きなテーマではあるんだけど、こんな当たり前のこと理解できて当然だよねと自分がエンジニアたちに押し付けることそのものがエゴなで、どうしてもそうなってしまいがちなところは常に自分を振り返りながら反省している。

大事なのはエンジニアたちの価値観に寄り添いながら、それとなく価値をちらつかせるってことなのかなとも思っている。

 

 

冒頭のヤナティさんの価値の本質を提供するっていうことから若干(だいぶ)外れてしまった。

価値をいろんな切り口で提供できるのはその通りなんだけど、経済的な価値を得ること以上に自分がお客さんに価値を提供できているのかは永遠のテーマだと思っている。

 

10分経ったので強引なまとめになっちゃったけど今日はここまで。

ひさしぶりに文章書いて見たけど、ひっちゃかめっちゃかだな、、

 

画像はここを参考にした。

オシャレな海外のフリー素材サイト10選|ブログのアイキャッチ画像におすすめ!

 

疲れたー

久しぶりの勉強会。

受ける方ではなく教える方だ、

しかもswift3だ。

 

無料で教えるのではなく、1人二万円くらいもらっているのでなかなか気がぬけず、土曜日の朝始まって日曜の夜まで二日間ぶっ通しで話しっぱなし。

おかげで喉が潰れた。

前回とかは数十人いたけど今回は少し少なめで半分以下だったのは宣伝不足なので仕方ない。

 

画像やラベルの配置、アニメーション、storyboardの使い方、テーブルビュー」ナビゲーションで画面遷移する方法など、一気通貫でほぼ素人さんにわかりやすく教える機会は自分も成長する機会となった

 

swift3は昨年リリースされた言語でソースや資料がない中、まーまー濃い内容を教えられたと思う。

 

その分、自分も成長できた、、

 

今日から何日かに渡ってswift3について解説できればと思う

 

アプリ開発を始めたら子供を授かった話

すみません、若干タイトルが釣り気味です。

 

でも嘘を言ってないと思っているのでまず順を追って書いていきます。


若干エンジニア色が強い内容になっているので細かい技術面みたいな話は流してもらえると助かります。

数年前、アプリを作り始める前は定職についていなかったのですが、
まず最初にアプリ開発を一から学び始めることにしました。


アプリ開発を始めるにあたり、まず最初に資格の学習アプリからシューティング系のゲームまでたくさんのアプリを作りました。

シューティング系のゲームは技術的に低いレイヤーで実装を学びたくて、cocos2d,unityなどのプラットフォームに頼らずに開発しました。
当時日本語版がなかったstackoverflowを見て拙い英語読解力により完全独学で学習したので若干のぎこちなさは残るものの、ある程度期待通りのものを作ることができました。
このiOSスキルが後々自分のアプリ作りの幅を広げてくれました。

ただこれはあまりお金になりませんでした。
毎月何千万、何億円という大量の広告費を投下して、ガチャで支払われる課金で回収していくパワーショベルみたいなゲーム会社に個人が真っ向から挑んで勝てるわけがありませんでした。

これを機に少し考え方を変えて、次は技術ではなく、別の頭を使おうと思って始めたのが資格試験の学習アプリです。

 

資格のアプリを開発する前に、OS別世帯年収のようなデータからお金を払ってくれやすいユーザー層を取り込むためiOSを選んで若干試験料が高めの資格試験を対象にしました。
高い試験料の資格ならば、合格のために数百円のアプリをインストールすることをためらわないだろうと思ったからです。

その後、自分はアプリ作りに専念して、問題作りは資格方面に明るい知り合いに、単純作業はクラウドワークスやshuftiで依頼して、作った問題をcsvとして提出してもらいました。
仕様は自分で決めてcsvを読み込む部分だけ作れば問題のデータファイルだけ変えて、多種多様な資格学習アプリを量産することにし、
アプリの存在を拡散するためにネイバーまとめやブログなどで資格応援サイトとして無料広告みたいなことをたくさん出しました。
全ての試験で成功しませんでしたが、一部試験などでポテンヒットし、それなりのお金になったこともありましたが、残念ながらこれも長くは続きませんでした。

一部の資格の業界団体みたいなところから、おたくのアプリが著作権を侵害しているから運営をやめなければ法的手段に訴えるよーって忠告(というか警告)を受けたのであっさりやめたからです。

この辺の業界は著作権とかガチガチに固められているから、もしやるならちゃんとその筋の人に仁義を切って始めようという教訓を得ましたね(笑)


それからは、のちにイケダハヤト氏も移住したことで知られる、高知県に行って好きなことでもやりながらのんびりしようと思った時期もありました。
知り合いのツテで空き家に住まわしてもらい、家を改修しながら川で釣りをして畑で野菜や果物を収穫し、漁師さんからカツオと大根を物々交換したりして生活していました。高知は小さな滝が多いので小水力の発電事業ごっこみたいなことも経験しました。
一部の集落では若い人も多く、今までにない楽しい時間を過ごすことができたのですが、人間慣れると色々考えてしまう生き物でこれはこれでかなり楽しかったんですが、なんかちょっと違うなということもあり、東京に戻ってもう少し頑張ろうと思いました。

 

ここでちょっと違うなっていうのは当時付き合っていた彼女のことを考えたからです。

相方は実家の都合で関東から離れられなかったのと、彼女自身も妙齢だったので結婚や出産のことなどを考えるとこのままフラフラしていられませんでした。

ただ、独り身だったり、相方がどこでもいいよっていうタイプだったら確実に高知に移住していたかもしれません。

 


東京に戻るとアプリでは稼げないんだろうかと思い始めた時期でもありましたので、
全く別のことをやるのか自分の好きなテクノロジー分野で頑張るのか随分悩みました。

自分が辛い時に支えてきてくれた彼女のことなども考えるとこのままというわけにもいられませんでした。

悩んだ結果、就職することにしました。

 

 

それまで自分一人で独学でやってきた開発のスキルが世の中ではどの程度のレベルなのか知りたい、試してみたいと思ったこともありますが、実際は自分自身の成長や挑戦という道ではなく、彼女のため、自分の実力のため安定を選んだということです。


就職した会社はウェブサービスのスタートアップで当時、自分が作っていたシューティングゲームを見せたところ、ちょうどアプリ作りを始めたいのでネイティブエンジニアが欲しいということだったので会社にとっても私にとってもちょうど良いタイミングでした。

 

そこから徐々に世界が開けてきました。

一部ですが投資家の方々にもお会いする機会ができましたし、年齢的な意味での横のつながりの強いスタートアップ業界で少なからず知り合いも増えました。

会社内ではアプリを担当するチームは当初ネイティブでフロントを実装する私とサーバーサイドを担当している女性エンジニアの二人だけでした。

その方は若くとても優秀でしたが、当時のチームは実装上の様々なトラブルを抱え、必要な機能を作るまでの道のりも随分遠回りをしていました。

社内ではアプリ作りに詳しい人はいなかったのでウェブの考えで実装や仕様が決められ、私自身初めての業種の会社に慣れないことの連続でした。

私自身、エンジニアと言っても仕様策定、導線設計、ワイヤー作り、実装、保守を一挙にやっていたのでバックエンドのエンジニアと二人三脚っていう感じでした。

そうこう苦労しながらも数字は伸びてくるわけですが、数字が伸びるにつれてアプリを作っているチームに1人、また1人とメンバーが増えていき、今では10人以上の大所帯となりました。
その中で、私以上に優秀なエンジニアも続々入社してくる中で
適当なタイミングで私自身もエンジニアからディレクターという職種に変わりました。

 

私が入社した当時、アプリの1日の売上が数千円ぐらいでしたが、
エンジニアを退いたタイミングでは数百倍倍ほどになったこともあり、
私自身はこうした数字をさらに伸ばすことだけに特化した肩書きになりました

また入社当時、バックエンドを担当をしていた女性も今年、結婚、出産し、今では第一線を退いています。
実は今出産休暇中で一昨日出産したので、今はゆっくり休みながら早く復職してもらって一緒にまた働きたいです。
まだ全然先のことになりそうですが。。


私自身、プライベートでは、この会社への就職がきっかけとなったかどうかはわかりませんが、付き合っていたその彼女と去年結婚しました。
そしてその1年と1ヶ月後の今年3月末に子供を授かりました。

 


それまではしがない中年男だったけど、
アプリ開発を通して、掛けがいのない貴重な仲間と知り合うことができました。
これが何よりの財産になりました。

本当は実力があったら独立とか起業とかって手段もあったかもしれません。20代前半が中心の若い小さな会社でしたが、そんな中で私のようなアラサーを暖かく迎えてくださった会社の方々には感謝のしようがありません。

 

こんな私でも嫁をもらい、子供を授かり、人並みの幸せをかみしめることができているのは一重にアプリというきっかけがあったからに他なりません。

 

仕事面では数字を伸ばすことにコミットしつつ、自分の好きなテクノロジーという領域でもう少し何かできないかと模索しているところでもあります。

まずは手始めにrailsの勉強も兼ねてサービスを作っていたりします。

awsを使ってiOSアプリのダウンロード数を自動取得してslackに連携してみた

f:id:ichonol:20150704202311p:plain

 

チームで開発を行っていると、開発管理者から今日のダウンロードどのくらい?と聞かれることがあります。

 

特にiOS実装担当者が一人しかいないと、一旦脳内コードのキャッシュを消去して

itunesconnectにログインして、sales and trendを見にいく...

 

でも年をとると一度別のタスクに従事すると再度元のプログラム脳状態に戻るのに時間がかかってしまいます。

これは無駄ですよね。

 

なので、聞かれて調べる前に自動でダウンロード数を更新する方法をご紹介します。

 

 

最近のスタートアップだと、slackを使っているチームも多いと思うので

今回はアプリのインストール数を定期的にslackに投稿する方法をご紹介します。

 

aws経由で投稿する理由は、いわずもがなcronを使いたいからなのですが、

一定の条件さえクリアすればどれでも大丈夫です。

なので、今回は細かいawsの使い方などは解説しません。あしからず。

 

 

その唯一の条件が、javaが実行できるかどうかです。

確認のためjavaと入力してください。

[ec2-user@ip-172-31-4-212 ~]$ java
使用方法: java [-options] class [args...]
...以下省略

 

となればjavaの環境があるのでそのままで大丈夫です。

 

-bash: java: コマンドが見つかりません or command not found


みたいな感じになったらjava がないのでここらへんからインストールをしてください。

 

  次に必要なのがapple公式のコマンドラインツールAutoingestionのダウンロードです。

Autoingestionについてはこちらから取得できます。

2015年7月最新時点で、9ページ目にあるAutoingestion.classを適当な場所にダウンロードしてください。

 

まずは、端末上での取得できるかの確認をします。

ダウンロードしたディレクトリに移動してautoingestion.propertiesというファイルを開いて以下のように入力します。

userID = ***********
password = *****************

それぞれitunesconnectにログインするときのアイパスになります。

 

terminalを開いて先ほどAutoingestion.classをダウンロードした場所にカレントディレクトリを移動して、以下を実行します。

java Autoingestion autoingestion.properties  ************ Sales Daily Summary 20150707


*****はverdor idと呼ばれる、デベロッパーごとに割り振られる8から始まるidになります。

こちらもちょくちょく表示場所が変わるのですが、

2015年7月最新時点で、以下の場所に表示されています(ログイン状態で開いてください。)

iTunes Connect


以下のように返ってきたら成功です。

5862238 Sales Daily Summary 20150702
S_D_85862238_20150702.txt.gz
File Downloaded Successfully

 

以下、aws側の設定を行います。

まずsshでターミナルからログインします。

ssh -i ~/.ssh/****.pem ec2-user@xx.xx.xx.xx

vi ~/.ssh/config で予めHost nameなどを設定しておけばこんな長ったらしいのを入力する必要はありません。

 

ログインしたら、端末でやったのと同じようにjavaの環境があるか確認してください。

以下もjavaがインストールされている前提でお話しします。

 

まずローカル環境にダウンロードしたAutoingestion.class及びAutoingestion.propertiesのディレクトリをawsに保存します。

(ローカルにあるAutoingestionディレクトリをscpコマンドでawsに保存する方法)

sudo scp -i ~/.ssh/****.pem -r Autoingestion ec2-user@54.64.146.48:/path/you/want/to/download

※ ****(鍵)とpathは適宜置き換えてください。

 

できれば上記、pathはcronなどで自動実行できるタスクの位置に保存してください。それか、あとでmvコマンドで移動させて上げる必要があります。

 

RoRを使っているのであれば、projectFile/lib/tasks/の直下などであればrakeタスクを定期実行する時にやりやすいです。

もちろん、cakeなどの他のプラットフォームでも実行できますが、

(若干オーバースペックですが)せっかくなので今回はRoRを使うことにします。

 

では、先ほど端末上で実行したjava Autoingestion..をaws上で実行するシェルスクリプトを書きましょう

日時などは常に更新する必要があるので、ここらへんを可変にして随時適切な値が入るようにします。

X日前の入力が入るようにしています。適宜変えてお使いください。

このshellはAutoingestionを保存した場所においてやるといろいろ楽ちんです。

# iTunes ConnectのID
VENDOR_ID=**********
# 取得したいデータ・タイプ
TYPE="Sales Daily Summary"
# 取得したいデータの日付
DATE=`date --date="X days ago" +"%Y%m%d"`
echo $DATE
# 取得したZipファイル名
FILENAME_COMPRESSED="S_D_"$VENDOR_ID"_"$DATE".txt.gz"
# Zipファイル解凍後のテキストファイル
FILENAME="S_D_"$VENDOR_ID"_"$DATE".txt"

#圧縮ファイルのダウンロード
java Autoingestion autoingestion.properties $VENDOR_ID Sales Daily Summary $DATE

#ダウンロードファイルの解凍
gunzip $FILENAME_COMPRESSED

 

 

 定期実行するためRoR上でcronの設定を行うために
Gemfileに以下を入力します。

 

gem 'whenever', :require => false
gem 'slack-api'

 

Gemfileを保存して閉じたあと

bundle update

を実行して更新してください。

 

wheneverの更新がうまく行くと

プロジェクトファイル/config/schedule.rbに以下を追加します。

every 1.day, at: '8:40 am' do
 rake "slack:send_message"
end

 

これは毎日8時40分にslack.rakeファイルにあるsend_messageを実行するという意味です。

 

schedule.rbを入力して保存した後、ターミナル上で以下実行をしてcronを更新するのを忘れないでください。

whenever -i

 

cronを更新させたら、shell scriptを実行させるため、

crontab -e

と入力してcron設定ファイルを開きます。

 

 

すると、

40 8 * * * /bin/bash -l -c 'cd /home/ec2-user/rails/hoge && RAILS_ENV=production bundle exec rake slack:send_message --silent >> log/cron.log 2>> log/error.log'

などとなっていると思いますが、この前に

 

35 8 * * *  /bin/sh /home/ec2-user/rails/hoge/lib/tasks/doAutoingestion.sh

などと入力してあげると毎日8時35分にshell scriptが実行されるようになります。

 

今までを整理すると

毎日8時35分に「java Autoingestion ...」を実行して前日のアプリインストール情報ファイルをダウンロードして、その五分後にslack.rakeのsend_messageブロックを実行するようにしました。

 

最後にsend_messageを作成して、shell scriptでダウンロードしたファイルの内容を集計します。

rubyに慣れている人は以下読まないでいいですw

私自身rubyに親しくないため、かなり汚いコードです、なので、自分でできる人は極力自分で良いように集計してください。

 

それでは、

vim lib/tasks/slack.rake

を実行してrakeファイルを作成してください。

(もちろん、エディタはvimじゃなくても大丈夫です)

 

以下入力してください(AとBの2つのアプリがある場合)。

task :send_message1 => :environment do |t, args|
 message = "install速報(ios)"
 channel = "#ios"
 num_of_A = 0 #アプリAインストール数
 num_of_B = 0 #アプリBインストール数
 sku_of_A = "A"
 sku_of_A = "B"
 today = (Date.today - 2).to_time
 todayYYYYMMDD = today.strftime("%Y%m%d")
 p todayYYYYMMDD
 filename = "lib/tasks/S_D_85862238_#{todayYYYYMMDD}.txt"
 line_num = 0
 text=File.open(filename).read
 text.gsub!(/\r\n?/, "\n")
 text.each_line do |line|
  which_of_sku = "NULL"
  word = text
  word_num = 0
  line.gsub!(/\t/, "\n")
  line.each_line do |word|
  if ( line_num != 0) then
   if(word_num == 2) then
    which_of_sku = word.gsub!(/\n/, "")
   end
   if ( word_num == 7) then
    num_of_install = word.gsub!(/\n/, "")
    p "#{line_num}行目のインストール数:#{which_of_sku} #{num_of_install}"
    if (which_of_sku == sku_of_A) then
      num_of_A += (num_of_install.to_i)
     p "A : #{num_of_A}"
    elsif (which_of_sku == sku_of_B) then
     num_of_B += (num_of_install.to_i)
     p "B : #{num_of_B}"
    end #if (which_of_sku == sku_of_A) then
   end #if ( word_num == 7) then
   word_num += 1
  end #if ( line_num != 0) then
 end #line.each_line do |word|
 line_num+=1
end # text.each_line do |line|
result = "最新インストール状況:#{todayYYYYMMDD}集計結果: A=#{num_of_A}, B=#{num_of_B}"
p result

Slack.configure do |config|
 config.token = "*********************************************************************"
end
Slack.chat_postMessage(icon_url: "適当なアイコンのurlをセットしてください",
 username: "iOS速報ちゃんねる" ,
 channel: channel,
 text: result)

end


どうですか、汚いでしょう。ここで晒すには恥ずかしすぎるコードなのですが、

objective-cしか書いたことない私にはこれっぽっちが限界なので、

学習コストとして恥をかきます。

 

だれか詳しい人がいたら、もっと簡単に書けるよ的な指摘を頂けると助かります。

 

コード中の

config.token = *********************************************************************

は、トークンコードによってslack-apiがどのスラックチームなのかを判断するために必要な箇所で

こちらから取得してください。

 

もし朝の8時40分までに待てない人はターミナル上で

/bin/sh doAutoingestion.sh
rake slack:send_message

で実行を確認してみましょう。

圧縮ファイルがダウンロードできるかと思います。

 

発展系として、app storeのレビューを自動取得することもできますし、slackで、昨日のアプリダウンロード数を聞いたら自動的に返信してくれるbotや投稿したメッセージをアプリユーザーにプッシュ通知で投げてくれるbotもありますので、よかったら調べてみてください。

 

plus.appgiga.jp

【fastlane】テスト、profileの選択、ビルド、(crashlyticsやdeploygate)配布、デプロイ全て一度に出来るCIツール

先日fastlane開発者KrauseFx氏(github)のmeet-upに参加してきました。

f:id:ichonol:20150626194152j:plain


当日はfastlaneの概要や使い方の説明から、どうやっているかなどの内部仕様的な話まで幅広くお話を聞くことができました。
だいぶ遅くなりましたが、この場を借りてお礼申し上げます。
ありがとうございました。
thank you for splendid speach @krausefx !! :)

 

https://fastlane.tools/assets/img/logo-desktop-large.png 



fastlane便利!

前からCIについて調べて、fastlane自体はかなり前から知っていましたが、日本語の記事がないこと、archiveする際にxcodeのショートカットで割り当てを行っていたこともあり、crashlyticsでの配布自体にそこまで負担がなかったので切迫した必要性を感じていませんでした。

 


ただ、配布する時にrelease, adhoc(時にはdevelopも)用に用意するのはそれなりに時間がかかるし、特にapple watch対応アプリでは純粋にその3倍(メインターゲットに加えて、watchkit app, extionsionの2ターゲット分)の設定は面倒でした。


何よりもその作業を開発者自身が行うのは無駄だなーと思っていました。

加えて、たまになんですが配布がうまくいかないことがあり、Apple Developer ポータルに行くと、必要なprofileがinvalidになっていることもあって、いちいち確認しなくてはいけなかったのも面倒でした。

 

標題の通り、fastlaneにはテスト、ビルド、配布、デプロイメント作業の他にも便利な機能があり、その一つがprofileのチェックとvalidationの自動化でした。

 

使い方

それではざーっと書いていきます。

fastlane自体はrubyで書かれていて、

最初にインストールする時もgemを使います。

 

sudo gem install fastlane

 

 fastlaneを使う場合は最初にプロジェクトファイルで、初期化するため以下実行します

fastlane init

 

そうするといろいろ聞かれますが、最初は全てyesで返します。(yと入力します)
途中でapple idに登録しているアカウントやbundle idも聞かれるので、正しく入力してください。


結果、プロジェクトファイル内にfastlaneというディレクトリができるので

cd fastlane


で移動し、以下で設定を編集します。

vim fastfile


少し見るとわかりますが、rubyで書かれていますので、フロントしか書いたことがない人は慣れましょうw

fastlaneは実行するの単位がブロックごとになっていて、

最初に実行するブロックが

    
  before_all do
    # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."

    # cocoapods

    # increment_build_number

    ipa # Build your app - more options available

    # xctool # run the tests of your app
  end


最後に実行するブロックが、

  after_all do |lane|
    # This block is called, only if the executed lane was successful
    
    # slack(
    #   message: "Successfully deployed new App Update."
    # )
  end

です。

 

例えば、最初のブロック(before_all do)で

ipaとあるのは、(与えられた設定で)アーカイブしてipaファイルを作成してくれます。

デフォルトでは コメントアウト(#)されていることがありますが、

cocoapodをコメントインすれば、対応しているライブラリを自動でアップデートしてくれます。

 

increment_build_numberとあるのはバージョンの自動インクリメントです。

 

 

以上だけでもめちゃくちゃ便利なのですが、snapshotというコードがあって、

(若干時間かかりますが)シミュレータを自動起動し、画面遷移ごとにスクショを撮ってくれます。

これはテストやデバッグにも使えますが、ストアにsubmitするときのスクショにもそのまま使えるので、もう一画面ごとに手動で画面コピーする必要もありません。

submitといえば、面倒な作業の一つにprovisioning profileの更新、キーチェーンへの登録、xcode上での登録というのがありますが、これも自動でやってくれます。

 

sighというのがそれです。

 

これはデベロッパー管理画面に行って、profileをダウンロードしてキーチェーン登録、xcodeの登録を自動でやってくれます。

たまにある、アーカイブする時に訳わからんエラーになった時にありがちな、profileが自動的に無効になっている場合、わざわざprofile管理画面に行って有効化しなくてはいけなかったのですが、これがあればもうその必要はありません。

 

他にもcrashlyticsやdeploygateでチーム内の同僚や他のテスターに配布してくれる機能もあるのですが、これは次回。

一通り編集が終わったらもう一度コマンドライン上で

lane :test

を実行します。

 

 

デフォルトでは、testがsnapshotのみなのでシミュレータが自動的に起動してスクショを撮ってくれます。
test が終了するとfastlaneディレクトリのscreenshotsサブディレクトリができていて、その中に各言語環境で適切サイズごとにスナップショットが保存されています(感動)。

しかも、その間バックグラウンドで実行してくれるので、他の作業ができます。めちゃくちゃ便利w


将来的には、profile登録→ビルド→テスト→自動インクリメント→配布→デプロイを一通り自動化したいと思っています。

あとは、バージョンインクリメントした後、配布する前にgithubと連携して、現状のブランチをプッシュするところもやりたいです。

今回は疲れたので、以上です。

iOSアプリの更新に必要な5つのこと(apple watch対応でも必要!)

覚えたと思っても、1年後の忘れたころにやってくる証明書の更新方法。
どれか一つでも失念していると全てやりなおして確認しなくてはいけないので忘れないうちに簡単にメモを作成しました。

追記 : 2015年3月28日、apple watchにも対応しました

 

 

 なにをやっているか
・開発端末が開発者登録された開発者のものであることの証明書を取得し、
・開発、submit、adhoc、プッシュ通知(開発、リリース用それぞれ)のprofileに結びつける
・それをxcodeに登録する(Build Settingsで指定するだけで終わってしまい、Account設定することを忘れがち)

 

 

# 1.証明書の期限の確認
https://developer.apple.com/account/ios/certificate/certificateList.action?type=distribution

>Certificates > ALL
開発者個人はDevelopment
リリース用やプッシュ通知はProduction

Expire確認して、そろそろだと思ったら以下2以降の作業実施。

 

# 2. キーチェーンから認証局に証明書を取得

ここが詳しい→http://www.sirochro.com/note/apple-developer-certificate-update/

以下項目だけ簡単に。
・キーチェーン起動
・メニュー > キーチェーンアクセス > 証明書アシスタント > 認証局に証明書を要求
・開発者登録したときのapple IDをユーザーのメールアドレスに入力
・通称は適当に(後ほどxcodeに登録する時に聞かれる)
・CA のメールアドレスは空欄、ディスクに保存、鍵ペア情報を指定を選択してOK
・鍵のサイズ : 2084ビット / アルゴリズム : RSA であることを確認し 続ける
・作成すると、CertificateSigningRequest.certSigningRequest がデスクトップに保存される。

 

# 3. iOS developerの「Certificates, Identifiers & Profiles」で証明書を登録

・もう一度以下のリンクにてCertificatesの右上にあるプラスボタン押下
https://developer.apple.com/account/ios/certificate/certificateList.action?type=development

・以下ラジオボタンがあるので、選択した上でcontinue(あとは指示通りそれぞれ作成する)
※指示に従う中で先ほどデスクトップに保存したcertSigningRequestファイルを指定する
>Developerment > iOS App Development
>Developerment > Apple Push Notification service SSL (Sandbox)
>Production > App Store and Ad Hoc
>Production > Apple Push Notification service SSL (Production)

 

# 4.Provisioning profileの作成
・同上リンクにて必要なprofileにて、テスト端末、アプリIDとともに上記3で作成したcertificateをラジオボタンで登録
(profileは、iphone,ipad,ipodの開発、adhoc, submit, 及びapple watchの開発、adhoc, submitの計6つ必要)
※当然だが、アプリのbundle ID が登録されたIdentifiersの中の適切なIDを選択する必要がある

・6つ全てgenerate > downloadで適当な場所に保存して、実行する(自動的にキーチェーンに保存される)


# 5. xcode側でprovisioning profileを同期

①開発者情報をxcodeに認識(忘れがちなので注意!!)

まずxcode > preference > accounts を選択

f:id:ichonol:20150328153103p:plain

 

そうすると右下「View Detail」からdistributionとdevelopmentをあることを確認して、左下の更新ボタン押下

f:id:ichonol:20150328153109p:plain

 

そうすると、「codesignは、キーチェーンに含まれるキー"******"を使用して署名しようとしているます。この項目へのアクセスを許可しますか?」みたいなダイアログが出てくるので、常に許可を選択

f:id:ichonol:20150328152157p:plain


※"*****"は項目2で証明書を要求した時に入力した通称


②Build Setting でprovisioning Profileを登録
・ナビゲーションペインでルートプロジェクトファイルを選択
・ターゲット > Build Settings > Code Signing の以下1と2で適切なprofileとidを選択
1.Provisioning Profile > Debug 及び Release
2.Code signing identitiy > Debug 及び Release
apple watch対応する場合は本アプリと同様、apple watch用のターゲットを選択して上記同様に実施する
※上記1を実施してから2を実施しないと2で適切なidが選択できない

 

備考:証明書の期限切れではなく、複数台端末で実行する場合は、
上記作業を実施した端末から証明書の書き出し > p12ファイルを作成 > 別端末で登録
ということをやる必要がある。
その場合、必ず1台目から書き出す必要がある(2台目から3台目は不可能)

iOSを使ってdeepMindにニューラルネットで対抗してみた

前回までのところでニューラルネットワークの基礎を自分のメモとしてまとめてきましたが、

計算方法はわかったけど、それで何ができるのという部分は示せてないので

具体的な実験タスクを決めようと思います。

前回までの結果を一度まとめます。

出力層-中間層間ニューロンの接続荷重の更新 

{ \displaystyle ΔW_{j,k} = -δ \cdot output_k \cdot (1-output_k) \cdot hidden_j \cdot δ}

 

 

出力層-中間層間ニューロンの接続荷重の更新

{ \displaystyle ΔW_{i,j} = -δ \left\{ \sum_{j'=0}^{{max}_j} (output_k-supervisor_k) \cdot output_k \cdot (1-output_k) \cdot W_{h,k} \right\} hidden_j \cdot (1-hidden_j) \cdot input_i}

 

 


無性に機械学習がしたくてdeep learningをアプリに実装してみた話② - Change before you have to.

 


無性に機械学習がしたくてdeep learningをアプリに実装してみた話③ - Change before you have to.

 

今回は実験タスクなので、単なる数値の羅列を学習する数値学習でも良いかなと思いましたが
それでは分かりづらいし、このブログではせっかくiOSを使うと謳っているのでもう少しインパクトのあるゲームみたいなものを設定したいなと思いました。

ちょっと調べていると、breakoutというゲームがお手軽に作れそうだと思いました。
breakoutは単なるブロック崩しです。

昔のゲームなのでわからない方は、以下動画を参照してみてください。
https://www.youtube.com/watch?v=H3iDiVygTsY


Super Breakout (Atari 5200) How to Beat Home Video Games - YouTube


採用した理由は
・知名度があるので、多くの人に分かりやすい
・すでにgithubなどで公開している人もいたので、学習結果を簡単に反映できそう(※)
・学習対象のブロックの動きの可動範囲が二次元ではなく、一次元なので学習がスムーズになるかなと思ったのも理由です。(一番大きな理由)
あとは、恐れながら、google のdeep-learningにも対抗したいって思ったのもありますw
※tnantoka/hello-spritekit
tnantoka様、MIT Licenseだったので使わせて頂きました。

少しいじって、タイトル画面をでなくしたり、
pod updateで最新のライブラリに更新しました。
上記プログラムでは各種パラメータがjsonになっているので簡単に修正できます。

ちなみに、プログラムは通常のobjective-cに加えて、SKSpriteの知識が必要です。

そうして、実行した結果が以下です。

https://www.youtube.com/watch?v=EuDqeFS1KiQ


movie def - YouTube

学習もなにもしていないので、手動でしかパドル(下にいる動くやつ)が変化しません。
defaultでカーソル位置でタップすると下のパドルが変化します。


これでは簡単すぎるので、ボールの速度を速くしました。
(重力加速度などはすべて無視しているのと、摩擦もないです。デフォルトのプログラムではボールがだんだん早くなるように設定されていましたが、将来の学習に必要ないので常に一定速度にしました)

その結果が以下です。

https://www.youtube.com/watch?v=6TBZnY0Agys


movie fast - YouTube

かなり速くなりましたが、(本当は失敗する様子を出したかったものの)なぜかちゃんとできていますが、半分くらいはボールを落としてしまっていますwww
下手ですね。。


それで、前回までにまとめたニューラルネットワークにパドルの位置座標とボールの位置を
学習データとして、ボールを落としたら罰を、ボールを落とさずにパドルがうまく跳ね返すことができれば褒めてあげる的な機構を組み入れた結果が
以下です。

 

学習パラメータ
ニューロンシグモイド関数の傾き:0.6(勾配)
バックプロパゲーション時における接続荷重の学習効率:0.75
また、実際にやってみると一定以上の学習がうまくいった場合かなり高速にパドルを動かしてしまっていてブレてしまうので
一定以上の精度で学習がうまくいった場合、移動距離にスムージングをかけてあげる判断をいれるニューロンをいれています。
赤ちゃんの手の動きは無駄があるけど、陶芸家の手の動きってほとんどブレがないですよね。
それを少し明示的にしてあげました。

学習回数10回目


init learning - YouTube

まだうまく学習できていないですね..

学習回数200回目


movie init - YouTube

徐々に対応できるようになってきました。

学習回数1000回目


movie after learning - YouTube

 

スムージングニューロンは初期状態からオフでしたが、
400回目あたりからオンになってきて、徐々にオンとなる確率が高くなり、1000回目ではほとんどオン状態です。
1000回目の動画をみるとほとんどパドルの動きにブレがないことがわかります。

 

上記、どうでしょうか

まだまだ改良の余地があると思っていて、
例えば、疲れるのを防ぐため人間は無駄な動きをしないので、ボールが遠くにある状態でのパドルの位置変化は無駄な動きであると思います。
具体的にはエネルギー評価関数を入れて、あまりエネルギーを消費するような動きをした場合には罰を与えるような学習をしていこうと思っています。


次回に続きます。