明日も楽をするために

めんどくさがりなITエンジニアが書くメモ帳

AndroidとiPhoneでhtml5を使用して音声と動画にアクセス時にユーザエージェントが変わる件

Html5で音声と動画にアクセスする際にAndroidiPhoneだとユーザエージェントが異なるものでアクセスされることが分かった。

Androidの場合(Zenfone5)
stagefright/1.2

iPhoneの場合(iPhone6の9.2)
AppleCoreMedia/1.0.0.13D15 (iPhone; U; CPU OS 9_2_1 like Mac OS X; ja_jp)

私が試した環境だと音声だけだが、調べてみると動画でも起きるらしい。Androidの場合は端末によって端末名が入っていたり、Zenfone5のようにAndroidの文字すら入ってない場合もあるのでユーザエージェントをandroidで判定していると痛い目を見る。

UITableViewでUITableViewCellの高さを自動で可変する

今回はUILabelとUITextViewを使用した場合にUITableViewCellの高さを自動で可変する方法を書きます。UITableViewは予め設定し終わった状態と過程して話を進めます。

StoryBoard上の設定は以下のようにmarginをセットしてます。
画像はUILabelですが、UITextViewも同じようにします。
f:id:makoto1212:20160309213400p:plain:w300

UILabelを使用するときは設定でLinesを0にしてください。
f:id:makoto1212:20160309213838p:plain:w300

UITextViewを使用するときは設定でScrolling Enabledのチェックを外してください。
f:id:makoto1212:20160309213840p:plain:w300


そして以下のコードを追記します。

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }

estimatedHeightForRowAtIndexPathは予めUITableViewCellの高さを指定してやることで実際に表示した際に負荷を軽減してくれます。
heightForRowAtIndexPathは実際のUITableViewCellの高さを取得します。


今回は返り値にUITableViewAutomaticDimensionというUITableViewCellの高さを自動で取得してくれる値を書きます。


ちなみにネット上で色々コードが転がっていたので、それぞれ試してみました。

//OK
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 100

//OK
tableView.rowHeight = UITableViewAutomaticDimension
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }

//OK これが同じ所に書けるし、一番いいのでは?
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }

//NG 何故・・・estimatedRowHeightにはUITableViewAutomaticDimensionを直に設定することが出来ない
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = UITableViewAutomaticDimension

iPhoneアプリを一人で開発している俺がstoryboardの分割に踏み切った理由

iPhoneアプリ複数人で開発していると衝突を避けるためstoryboardの分割は必須だと思いますが、一人で開発している分には別に衝突しないし特に気にする必要もないと思っていたのですが、画面数が増えてきたところで色々と問題が出てきたので同じように一人で開発している人に共有したいと思います。


分割しない場合

メリット
・なにも考えないでstoryboardが書ける。

デメリット
・画面数が増えてくると表示に時間がかかる
・新規画面を追加している際に既存の画面を間違えて変更した時に気づきにくい


特に"画面数が増えてくると表示に時間がかかる"


これが結構問題で、作業効率が著しく落ちます。
(※私の仕事で使用しているMacMiniが5年前以上に買った物というのもありますが・・・)

最初はイメージで画面1枚に付き、storyboardを1枚用意しないといけないと思っていたのですがiOS8以降が対象であるならば以下が使用できます。


Storyboard Reference
developer.apple.com

xcodeの右下のほうにあるのですが、これをstoryboard上に持ってきます。
f:id:makoto1212:20160226000618p:plain:w300

Storyboard Reference内の設定でStoryboardのファイル名の一覧がでてきます。
f:id:makoto1212:20160226001004p:plain:w300

あとはStoryboard Referenceに対して今までどおりにSegueを張るだけでOKです。
f:id:makoto1212:20160309220028p:plain:w300


Storyboard Referenceを導入すると

メリット
・画面分割を機能ごとのStoryboardで分割できる
・Segueがそのまま使える

デメリット
・iOS8の場合はRelationship Segueが使用できない

対してデメリットはないのでオススメです!!

PHP5.2でSwiftみたいなmapや、filterみたいなことして見たい

結論:できませんでした。釣りタイトルで申し分けない(´;ω;`)

付き合って頂ける方は下にスクロールをどうぞ




swiftのmapやfilterみたいなことPHPで出来たらいいなぁーと考えてたら、もしかしたら自分が知らないだけで似たようなこと出来るのでは?
PHPのドキュメント漁ってたらあるものを見つけた

PHP: array_map - Manual
PHP: array_walk - Manual

array_mapとarray_walkである
mapって同じ名前が付いているので期待できる!!!

関数はarray_walkが、array_mapの上位互換な感じがあるので以下はarray_walkで説明

<?php
$data = array(1 => 'りんご', 2 => 'みかん', 3=> 'ぶどう');
array_walk($data, function(&$value, $key) {
    $value = $value."ジュース";
});
var_dump($data);

array_walkは第一引数に配列を、第二引数にCallBackを指定することで配列内の値に対して変更を加えることができます。

しかし残念ながらこれはPHP5.3以降にできる書き方。PHP5.2は無名関数が使えないのだ!!

ちなみにPHP5.2で書くと

<?php
$data = array(1 => 'りんご', 2 => 'みかん', 3=> 'ぶどう');
array_walk($data, create_function('&$value, $key',
    '$value = $value."ジュース";'
));
var_dump($data);

create_functionだと!?・・・

(ヽ´ω`)





それでもPHP5.3なら!!

PHP5.3なら!!

foreachとarray_walkの処理速度比較 - rh7's blog

foreachの方がはやい・・・





それでもarray_walkにも何かいいところが!!

PHP5.3.14以降のarray_walkで内部ポインタが破壊される – この先生きのこるには





foreachイイヨネ!!

PexJSで引数にURLではなくバイナリをセットして使用する方法

新年初投稿です。

最近までGoogleのSwiffyを使ってswfをhtml5に変換して使っていたのですが
developers.google.com


特定のバージョンから内部的にCanvasからWebGLに変更されたのか動かなくなってしまった古い端末が増えたため、別の方法を取り入れることになりましてDeNA様のPexJSを使わせて頂く事になりました。
github.com

Swiffyは公開されているruntimeとGoogleのサーバー上で変換されたhtml5は常に揃えないといけないのですが、実はv5.2のruntimeを使用するとv7.3が公開されるまでの間そのまま使用することが出来ました。(古いruntimeはサーバーに残ってるので直打ちでダウンロードできる)

v5.2を使用すると古い端末でも再生できたりします。v7.3辺りからGoogleで生成されるJsonの形式が微妙に変わってしまったため遂に動かなくなりました。


Flashの生成にはswfmillを使用して行っていたのですが、PexJSをそのまま使うと第一引数にURLをセットする必要があるのでPexJSを使用する画面とswfを生成する画面の二画面が必要でした。

どうしても一画面で完結したいので最初はwindow.URL.createObjectURL()を使って試していましたが、Android4.0.4では動かないため別の方法を模索する必要がありました。

PexJSは日本語のドキュメントも充実しているのですが、実は書かれていないオプションがありましてそれが「swfBinary」です

■サンプル(PHP+Javascript)

PHP側でswfのバイナリをbase64にしてhtml側に渡す

base64_encode($swf);

Javascriptbase64をdecodeしてセットする

var option = {
    swfBinary : atob(swf);
};
var pex = new Pex("", "container", option);

これで一画面で完結できます。

Paizaで彼女を作ろうとしてみた件

paiza.jp

Paizaで彼女が作れると言うことでやってみましたがPHPを選択すると

<?php
$input_lines = fgets(STDIN);

こんな感じで表示されるが、普段使わないから最初なんだかよく分からなかった・・・

<?php
$texts = array();
while($text = trim(fgets(STDIN))) $texts[] = $text;

複数行だとこれで取得できる

時間があったら色々進めたいところ

StoryBoardでEmbed inで追加したNavigationControllerをModalViewで開く場合の値の渡し方

StoryBoardでEmbed inで追加したViewControllerにModalViewで開いて値を渡す方法

FirstViewController

NavigationController(SecondViewControllerにEmbed inで追加したもの)

SecondViewController

let modalView = storyboard!.instantiateViewControllerWithIdentifier("NavigationController") as! UINavigationController
modalView.modalTransitionStyle = UIModalTransitionStyle.CoverVertical
let secondView = modalView.visibleViewController as! SecondViewController
secondView.foo = foo//値を送る
self.presentViewController(secondView, animated: true, completion: nil)