2015年10月9日金曜日

起動せぬなら 殺してしまおう setupAVCapture:カメラアプリのレイアウトをシミュレータで確認する

どうも。へへへ。おはようございます。
只今絶賛不具合修正中ですが、個人的にちょっと衝撃的だったので、備忘録として投稿ー。

iOSのカメラアプリを開発しているのですが、ワタクシ、実機はiPhone 5sしかもってません。えへへ。だってお金ないもん。
でもXcodeのSimulatorでは、カメラが扱えない。
カメラアプリを起動すると、最初のスプラッシュスクリーンが表示されて、そこで止まってしまうんですね。カメラからの入力画像が表示されない。
だからカメラアプリの開発には、どうしても実機が必要になるのですが・・・。

ここで問題が。
iPadでシャッターボタンなどが表示されないよ、とアップル様からご指摘を受けました。
でも自分は実機持ってない。
・・・どうしよう。試せない。試せないと修正できない。うわー。

で、10分くらい悩んだ結果、はたと思いついた。
「カメラ機能を一時的に使えなくすれば、Simulatorでも動くんじゃね?」

やってみました。
いつもはこうしてるのを、
[self setupAVCapture];
こうしてみた。iPhoneの時だけsetupAVCapture動かしたるw
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {        [self setupAVCapture];    }

・・・動いた。SimulatorのiPadで。ほんとかよ。
まあ、もちろんカメラからの撮影機能とかは試せませんし、リリースする前に元に戻さなきゃならんのですが。
少なくとも、これでレイアウト崩れは再現と修正ができそうです。

やれやれ。

(最初からStoryboard使ってレイアウト作っとけばよかったな。次はそうしよう

2015年10月5日月曜日

iOS9のいじわるー。:iOS9でcanOpenURLを使ってみた

こんばんわ。お久しぶりです。
なんか寝つけないので、ブログでも更新してみんとす。

ついこの間リリースされた「iOS9」で、カスタムURLスキームを使って別のアプリを呼び出そうとしてたんですよ。
でも、iOS9には痛い目に遭っているので(詳しくはまたいずれ)、今度は事前によーく調べてからにしようかなーと、検索してみましたら、こちらの記事がヒット。

【追記】iOS9でcanOpenURLを有効にする方法

えっなになに・・・「iOS9でcanOpenURLが使えなくなった」・・・。
ダメじゃん。きー!とか思ってたら、対処方法も書いてあった。ふんふん。
「Info.plist」に「LSApplicationQueriesSchemes」のキーと、アプリで許可するカスタムURLスキーマを登録すればいいらしい。

ふんふん。
で、このinfo.plist、XcodeでProperty Listとして値を編集することもできるようですが(というかこっちがデフォルト)、最近Xcodeがすっごく重くなってまして。

一度Property List表示で編集しようとしたら、画面が乱れてしまいました・・・
(;_;)
仕方ないので、Open AsのSource Listでソースとして開いて編集。
これなら問題ないやね。
というか、ワタシはもともとSGMLやらXMLのヒトなので、こっちの方がやりやすかったりする。

で、端末にカスタムURLスキーマを設定した自社アプリがあればそっちを起動するし、なければApp Storeのダウンロードページを表示するようにしてみた。

んー。上手くいかない(笑)
・・・最初は「canOpenURL」で分岐させてたんだけど、上手くいかないー。
ちょっと悩んだけど、もっと単純に考えたらあっさりできました。
要はデバイスのアプリをまず開いてみて、失敗したらストアに飛ばしゃいいのよ。うん。

NSURL *url_store = [NSURL URLWithString:@"https://アプリストアのURL"];
NSURL *url_device = [NSURL URLWithString:@"CustomURLSchema://"];
if ([[UIApplication sharedApplication] openURL:url_device]) {
        NSLog(@"OK");
} else {
        [[UIApplication sharedApplication] openURL:url_store];

}

この、何でもめんどくさく考える癖、直さなきゃな。
ということで、おやすみなさーい。










2015年9月17日木曜日

滅びゆくものこそ美しけれ。:iOSのカメラロールに任意のアルバムを作成しようとしてハマった話

へいへいへい。みなさんこんばんは。おひさしぶりです。

今日はiOSのカメラアプリ開発で、ハマったことをメモ代わりにちょっとだけ。

ALAssetsLibraryを使って、デバイスのカメラロールにアプリの名前がついたアルバムを作成しようとしてたのです。

こちらの記事「iPhoneアプリ開発 芳名帳アプリ作成(6) -写真に保存-」を参考にさせて頂いたのですが・・・
うーん、説明は分かりやすいんだけど、まず、どうしてもアルバムが作れない。
なーんでーだろー?と思ってたら、

アルバム名にスペースが入ってた
・・・ソフト名「XXX Pro」をそのままアルバムの名前にしようと思ってたんですけど、・・・スペースの代わりにアンダースコア「_」にしたら、あっさり作成に成功。

ハマりポイントその1:アルバム名にスペースはいってた!

で、アルバムを作成できたのはいいんですが、今度はそこに写真を保存する方法がわからない。
それまでは、ALAssetsLibraryの「writeImageToSavedPhotosAlbum」でカメラロールに写真を保存してたわけですが・・・。
そもそもアセットとは何か、というのをロクに理解もせずに使っていたので、さて、アルバム指定するにはどうしたらよかんべ?となると、ちんぷんかんぷん。

アルバム名はわかってるんだから、「writeImageToSavedPhotosAlbum」にアルバム名を指定するオプションとかあるんじゃないのー?と勝手に考えてました。
ないない。そんなの。なかった。

結局は、
1. ALAssetsLibraryの「enumerateGroupsWithTypes:ALAssetsGroupAlbum」を使ってアルバムの一覧を取得
2. 目的のアルバムが見つかったところで、おもむろに「ALAssetsGroup」の「addAsset」を使って、「ALAssetsGroup」(アルバム)にAsset(写真)を追加
こんな流れで、ようやく指定したアルバムに写真を保存できました。

ハマりポイントその2:Assetってなんなのか良くわかってなかった

ま、ぐだぐだだったけど、なんとかできて良かった。
アルバムに写真を保存するところでは、「Quiita」さんのこの記事ios7,8でアルバム名を指定して画像を保存するが参考になったわけですが・・・
Swiftで書かれてて・・・ちょっと・・・難儀しましたねえ・・・
まあ、やってることは同じなんで、大変たすかりましたが・・・。
なんか、英語の資料を見ながらフランス語のレポートを作ってるような気分になりましたよ・・・。

・・・。
でも、今日配布がはじまったiOS9では、Asset Libraryはdeprecated(非推奨)となるそうな・・・。


The Assets Library framework is deprecated as of iOS 9.0. Instead, use the Photos framework instead, which in iOS 8.0 and later provides more features and better performance for working with a user’s photo library.
・・・せっかく覚えたのに・・・。
ちょっとね、なんだかなあ、ってオチですみません。
うん、寝よう。


2015年8月2日日曜日

サンプルはあくまでサンプルである:Mapbox iOS SDKを使ってOpenStreetMapを表示する

やー、まいにちマイニチ蒸し暑くていやになっちゃいますねー、こんばんは。
というわけで今夜もファミレスに逃げてきましたよ。

今日はMapboxを試してました。
自分を自分好みにカスタマイズして公開できるという、素敵なウェブサービスです。

OpenSreetMapがベースだし、iOSやAndroidのSDKもあるし、ずっと試してみたかったんですよねー。
モバイルアプリを作るからには、地図は使いたい!
でもAPI制限のことを考えるとGoogle Mapはどうも気軽に使いにくいというかー。

途中、ちょこちょことつまづきましたが・・・Mapboxのサンプルを見ながら、なんとかiPhoneアプリまで作成。
といっても地図をiPhoneに表示させるだけですけど。

一つ、はまった点があったので、備忘録としてメモメモ。

サンプル通りにコード書いて、実機で確認しようとビルドすると「RMFoundation.h」が無いと怒られました。
もちろん、ファイルがあるのは確認済み。あっれー?おっかしーいーなー。

色々検索したところ・・・一つ前のバージョンのSDKにすればいいみたい。
ここを参考に、バージョン1.6.0に戻しました。
「'RMFoundation.h' file not found in 1.6.1 #631」

以下のようにpodfileに書いて、pod installを実行。
無事バージョン1.6.0に戻り、ビルドも通りましたとさ。
pod 'Mapbox-iOS-SDK', '1.6.0'
で、とりあえず作ったのがコレ。地図のスタイルはすっごくシンプルにしてみた。

地図のデザインは、Mapbox側で色々といじれるみたいなので、これから楽しみ!




2015年7月29日水曜日

ちょー便利なライフログアプリ:Google Mapアプリにタイムライン表示機能が追加

こんばんはー。おひさしぶりです。
毎日暑いですねー。

今日はAndroidアプリのお話。

最近、Android版のGoogle Mapアプリが更新されましたね。
知らない場所へお出かけするときには、必ずお世話になるこのGoogle Map。
このGoogle Mapに、前回のアップデートでタイムライン表示機能が追加されました。

まあこんな感じ。すげー。


自分が訪れた場所と道のりが、地図と時系列で確認できちゃいます。
Androidの設定でロケーション履歴を有効にしていることが条件だと思うのですが、びっくりしたのは、その場所で撮った写真も、タイムラインに表示されるってこと。

自分は行動記録をメモする代わりに、移動した先でちょいちょい写真を撮るようにしています。
仕事で訪れた場所や、ポストに投函した手紙、銀行での振り込み、エトセトラエトセトラ。
それらの写真は、あとで「あの手紙、いつ出したっけな」とか、自分の行動を振り返るのに使っています。
位置情報もつけているので、写真を撮った場所も地図で表示できますしね。

だから、別に驚くことでもないかもしれないんですが・・・。

なんかこう、今回のGoogle Mapのタイムラインのように、こうやってタイムラインという形でまとめてくれちゃうと、・・・なんかすっごく便利ですね。

ちょっと前から「Moves」というアプリを使っていて、行動記録代わりにしていたのですが。歩数とか計算してくれるし、便利ではあったけど、撮った写真を見せてくれるところまではいかない。

もう、ちょっとしたライフログアプリじゃないですか、これ。

位置情報付きの写真だとか、ロケーション履歴だとか、もうずっと以前からあった技術ではあるんですが、それらを上手く組み合わせて便利なものを作ってしまう。

こういうのが、本当の創造性だと思うのですよね。

一応、IT技術者のはしくれではあることですし、「あ、いいなコレ」って思ってもらえるアプリを作れるように、また明日から頑張りたいと思います。

でもせめてクーラーの効いた場所で仕事したい。扇風機だけだと脳みそ溶ける。










2015年7月10日金曜日

日本語でおk!?:iOSでEXIFのUserCommentに日本語を設定しようとすると、途中で切れる

こんにちは。ぷんぷん。怒っています。

今日は朝からXcodeくんと戯れていました。
カメラアプリです。
撮影した写真に、メタ情報を埋め込もうとしていたのです。ええ、EXIFのUserCommentですね。

AndroidではCommons Imagingを使って、さくっと行きましたので、まあiOSでも問題ないだろうと。
こんな感じで。
UserComment = @"そんなこといったって、だめだもんはだめだで、しゃーがないべさ。ほだら。だば、あきらめてしごとしてくんろ。ほりほり。わーったか?ほーり。";
[EXIFDictionary setObject:UserComment forKey:(__bridge NSString *) kCGImagePropertyExifUserComment];

で、ビルドして、実機でテスト。
アプリで撮った写真をMacに転送し、コマンドラインからexiftoolを実行して、UserCommentを確認しましたら・・・。
User Comment: そんなこといったって、だめだもんはだめだで、しゃーがないべさ。ほだ
途中できれとるがな
なんでやねん。
EXIFのUserCommentに文字数制限なんかあったか?・・・まああるかもしらへんけど、そんな長い文字列とは思えへんしー。
ネットで検索したら、日本語と英語が混じってる時は、途中で切れることもあるとか書いてあるけど、・・・今回、全部日本語やしー。
ううう。

ちなみに、全部英語だったら、長い文字列でもいいのかなー?
というわけで、以下の文章でテスト。

NSString *UserComment = @"Can I set Exif UserComment String in such a way? I cannot understand why apple doesn't pass Japanese Characters. Are they jerous about Japanese Food? Sushi? Tenpura!?";
・・・きれてなーい。きれてないよー?

もうね、これ、日本語があかん、というやつなのかなー・・・。
まあ引き続き調査はしますが、あまりに腹がたったので記事にしました。ぷんすか。

(オチなし)

2015年7月9日木曜日

たかが一行、されど一行:ClamAV + Amavis-new + Postfixでウイルス対策

はー。死ぬかと思った。こんばんわ。
今日はメールサーバーのお話です。ていうか懺悔。

実は先日、一年ほど前に立てたメールサーバーでちょっとやらかしちゃいまして。
bad_headerが理由で、メールが配信されずに削除されちゃって、ユーザーさんにご迷惑をおかけしてしまいました。
せっかくだから、もう一度サーバの設定を見直そうと思ったわけです。


例によってグーグルせんせーに教えを請いまして。
メールヘッダがぶっ壊れてるメールへの対処は「/etc/amavisd/amavisd.conf」の、$final_bad_header_destinyですればいいんだな、ふんふん、なるほど。
「$final_bad_header_destiny = D_PASS;」ってやっとけばヘッダが壊れてようが華麗にスルーか、なるほどなるほど、ああ現代人にはスルー力が足りないよな、とか、のん気に構えていました(まだこの時点では)。

$final_virus_destiny・・・へー・・・これ、ウイルスメールを華麗にスルーするかどうかって設定か・・・。
ほんとうはウイルスはがっちりサーバーで削除するのがいいんだけど・・・。
誤検出とかあったら、またこっぴどく怒られるしな・・・
いやいやでもでも、ウイルスメールをユーザーに華麗にスルーそのまま配信するってどうなの・・・?やっぱり削除しといて、隔離するべきじゃない?
どうしようかな・・・。

ま、結局「$final_virus_destiny = D_DISCARD;」にして、削除+隔離することにしました。
あとは隔離する先のディレクトリを設定。
「$QUARANTINEDIR = "/var/virusmails";」、これでよし。
amavisdと念のためpostfixも再起動して。
まあ念のためにテスト用ウイルスメールで、隔離動作を確認しときましょうか。

テスト用ウイルスはここからダウンロードできるみたいですね。
でも、もっと簡単な方法が。
この記事「必ずスパムと判定されるメールと、ウィルスの作り方」を参考にさせていただきました。
以下の文字列を貼るだけ。わー便利!ちょーかんたん!
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
ほくほくほく。やっぱ簡単なのがいいよねー。
別のパソコンからメーラー起動してー。メール本文にさっきのウイルス文字列(w)コピペしてー。宛先を自分にしてー。送信ッ!ひゃっはー。
そそくさと「tail -f /var/log/maillog」を実行して、ログを監視。
でっきるっかな でっきるっかな♪

Jul  8 12:46:34 myserver amavis[25298]: (25298-01) Passed CLEAN {RelayedInbound}, [xxx.xx.xx.xx]:35856 [xxx.xx.xx.xx] <admin@mydomain.com> -> <user@mydomain.com>, Message-ID: ...

・・・。え?ぱす?クリーン?きれい?
ウイルスにひっかかったら「Blocked INFECTED (Eicar-Test-Signature)」ってでるんじゃないの?えええええ!?
あわてて、ウイルスメールの隔離先として設定した「/var/virusmails」を確認・・・予想通り、なーんもない。からっぽ。

さてここから苦悩の時間がはじまりました。
なになになに?えっウイルスとして認識されてないってこと?ウイルス定義が古いのか?いやいや毎日更新するスクリプト作ったし!もしかしてLocalSocketあたりが違う?あばばばそもそもこのテスト用ウイルスって信用できるのー?いやいやそれじゃテストの意味ないしそもそもこういうの信用しないと本当にウイルスメールなんか用意できるわけないしおあおうぇいとぉえwそいいえちwsっを!!!

・・・。
ま、結論からいうと、
「/etc/amavisd/amavisd.conf」の「@bypass_virus_checks_maps = (1); 」がコメントアウトされてました・・・。
そっかー・・・そもそもウイルスチェック自体を華麗にスルーしてたのか俺は・・・。
「まさかそんな」って思い込みのせいで発見が遅れました・・・

で、この行をコメントして、amavisd再起動して・・・テストのウイルスメール送信したら・・・
さくっと・・・
Blocked INFECTED (Eicar-Test-Signature) {DiscardedInbound,Quarantined}
はい、ちゃーんと隔離もされてました・・・あわててGoogleで事例調べまくって振り回されたりせずに、設定ファイルを一つずつ冷静に吟味してたら、もっと早く復旧できたよなー・・・
反省。自戒の意味をこめて、今日はこのブログを書きました。

ま、そのあと「(!)ClamAV-clamd av-scanner FAILED: 」なんてエラーがでて、もうひと慌てしたんですが。
これは「/etc/clamd.conf」に、/var/配下をスキャンの除外フォルダとして指定してたためでした。
さすがにこれはすぐわかった。といっても一通りGoogleで検索して、わちゃわちゃしましたが(笑)
#ExcludePath ^/var/
ま、なんにせよ、日付が変わる前に致命的なところは解決してよかった。めでたしめでたし。