2014年11月30日日曜日

HTTPFileUpload

HTTPFileUploadを試させて頂くが、コンパイルエラーになる。

まず、HTTPFileUpload.hは、UIKitをインポートしないとUIImageが解決出来ない。

#import <UIKit/UIKit.h>

まぁこれは簡単だ。更に、HTTPFileUpload.hでもう一個ビルドエラーが。

"Existing instance variable 'delegate_' for property 'delegate' with  assign attribute must be __unsafe_unretained"

というエラーが出る。何のこっちゃ。どうも、Objective-Cでのメモリ管理に関連するらしい。ARC (Automatic Reference Counting)を使っている場合は問題が出るとか。とりあえず、id@propertyするなら@privateに書いちゃいかんって事らしい。

@interface HTTPFileUpload : NSObject
{
 @private
  id <HTTPFileUploadDelegate> delegate_; // ← つまりこれが問題

  NSMutableArray *postStrings_, *postImages_;
  NSMutableData *resultData_;
}
@property(nonatomic, assign) id <HTTPFileUploadDelegate> delegate;


とりあえず上の行を削除する。この後はHTTPFileUload.mでビルドエラーの嵐。

'release' is unavailable: not available in automatic reference counting mode

これもARCだな。ふむふむ。ARCは参照カウントをマニュアルで操作するreleaseだのretainだのを呼んだらいかんらしいからな。下記を参照させて頂く。
とりあえず、reelaseだのautoreleaseだのでエラーが出まくるので、そこを全部削除するとビルドは通った。あと、まだちょこちょこワーニングが。

Values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead

これ、言うとおりに[postData length]からunsigned longへのキャストを入れると、今度はフォーマットがintを要求しているのに何事ぢゃ!と怒るので、結局intへキャストするのが正解。postWithUriメソッドの最終行について下記のワーニングが出るが、とりあえず無視する。

Expression result unused

以上で一応エラーとワーニングの嵐は落ち着く。

PHP on Rackhub

さて、Webサーバが上がったからには、何かロジックを動かしてPOSTを受け止めねばならぬ。というわけで下記を参考にさせて頂く。


ふむふむ、そう言えばapt-getで色々とアップデート出来るんだっけな、Ubuntuは。Ubuntuが出始めたばかりの7年くらい前に色々いじった記憶があるが、その後すっかり仕事を変えてしまったのでご無沙汰でした。とりあえず、

% apt-get update
% apt-get upgrade
% apt-get dist-upgrade

してひたすらアップデートする。そして、Apacheがあるらしいので確かめる。

% which apachectl
/usr/bin/apachectl


おお、Apachそんなところにおったか。というわけで起動してみる。

% sudo apachectl start

HTTPでアクセスしてみるとちゃんとページが表示される。じゃあ、PHPも試しちゃおうって事で、

% cd /usr/local/httpd/htdocs/
% sudo vi phpinfo.php

<?php phpinfo(); ?>
%

って感じでドキュメントルートにPHPファイルを作り、早速HTTPで叩いてみるとちゃんと表示される。素晴らしい!

(追記)
上記のページに従ってApacheの設定を少し直す。
  1. Options Indexesの削除
  2. AllowOverrideをAllへ
  3. DirectoryIndexを追加

Nginx

「えんじんえっくす」と読むそうだ。
ちなみに「えんじんえっくす」とタイプすると私のATOK君は「はてなキーワード」から変換候補として「nginx」を拾ってくる。何てこった。知らないのは自分一人だったのか。

Wikipedia曰く、

nginx(発音は「えんじんえっくす」[3])は、フリーかつオープンソースWebサーバである。加えて、HTTPSMTPPOP3IMAPリバースプロキシの機能も持つ。処理性能・高い並行性・メモリ使用量の小ささに焦点を当てて開発されている。

だそうだ。凄いな。

Rackhub

アプリから写真をアップロードする先のクラウドって何が良いかなと迷ったのだけれど、Rackhubというのがあるので試してみる事に。下記のサイトを参考にさせて頂くと、とても簡単にサーバの立ち上げとSSHでのログインが出来た。


そんでもって、SSHでログインして

% which nginx
/usr/sbin/nginx
% sudo nxinx

でWebサーバが立ち上がってしまった。楽ちん・・・

で、nginxって何!?

2014年11月29日土曜日

NSDictionaryでハマる

ネットで色々とサンプルコードを参照させて頂くわけだが、時々そのままではうまく動かない事がある。

あるサンプルでNSDictionary型のデータ(画像情報のプロパティ)をNSMutableDictionary型にキャストしただけで、そのキャスト後の変数に新たなDictionary値を設定しているものがあったが、これを実行するとSIGABORTしてクラッシュする。NSDictionary型のオブジェクトには新たな値を設定するメソッドが実装されていない為だ。まぁ、こう書いてみれば当たり前だが。

というわけで、NSDictionary型のデータを一旦mutableCopyし、NSMutableDictionary型のデータに入れてから新たなDictionary値を設定する事で回避した。 具体的には、画像データにGPS情報を入れ込む際に、下記の様にした。

UIImage *image = info[UIImagePickerControllerOriginalImage];
NSMutableDictionary *metadata = [info[UIImagePickerControllerMediaMetadata] mutableCopy];
// self.latestLocationには現在位置が記録されている想定
metadata[(NSString *)kCGImagePropertyGPSDictionary] = [self GPSDictionaryForLocation:self.latestLocation];
ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary writeImageToSavedPhotosAlbum:image.CGImage metadata:metadata completionBlock:^(NSURL *assetURL, NSError *error) {
    if (error) {
        NSLog(@"保存失敗: %@", error);
    }
}];

赤字の部分のmutableCopyを忘れるとエラーになるので注意

CLLocationManagerでハマる

何やらLocationManagerがうまく動かないので色々調べてみると、iOS8から仕様変更があった様だ。まず、こちらを参照すると無事ロケーションがアップデートされる様になる。

また、参考にしたサンプルコードは画像にGPS情報を埋め込む為に CLLocationManager.location を直に呼んで最新のロケーションを取得しようとしていたが、これはCLLocationManagerのヘッダファイルを見ると、ロケーションのアップデート中はnilになる模様。
「The last location received. Will be nil until a location has been received.」

とりあえず、直接CLLocationManager.locationを参照せず、didUpdateLocationsが呼ばれたらViewControllerのlatestLocationプロパティに最新位置を設定する事にする。

2014年11月15日土曜日

週末プログラマ活動を再開する・・・の巻

一時期本業が忙しかったのですっかり遠ざかっていたが、やっぱりコード書いてみたくなった。

というわけでiOS向けのアプリでも書こうかと思い色々勉強中。ネットには色々有益な情報があるなあ、と久々に技術情報を検索しながら感心しきり。早速参考にさせて頂く。

これだけ情報があって、後は手元にMacとテストに使えるiPhone実機があって、Xcodeがインストールされてて、Objective-Cはよく分からんが他言語でのプログラマとしての経験があるって言ったら、他に何が要るのかって感じだな。あと開発に必要なのは(1)やる気と(2)アイデアと(3)時間だが、(1)が無いなら開発しなけりゃ良いわけだし、(3)は自分で作るものだから、後の問題は(2)だけ。さーて、腕まくりして頑張るかね。

  1. [iOS]UIImagePickerControllerで撮影した写真にExif・位置情報を書き込んで保存する方法 - カメラアプリを作った時に写真のファイルにジオタグを埋め込む方法
  2. iPhoneの画像からEXIF,GPSデータを取得する - こちらも写真にジオタグを埋め込む方法
  3. Xcodeで作るカメラアプリ開発入門 その① - そもそものカメラアプリの作り方
  4. 実践! iPhoneアプリ開発 カメラアプリの作り方(1) - こちらもカメラアプリの作り方
  5. iOSのカメラ機能を使う方法まとめ【13日目】 - これまたカメラアプリの作り方。世の中にはカメラアプリを作りたい人が一杯いるんだなあと
  6. iphoneで撮った写真をherokuにアップロードする(iosアプリ) - 撮った写真をWebにアップする方法。これはHTTPSを使う奴かな??
  7. 評判のいいiOSアプリ開発のTips ベスト20 - アプリ開発のTIPS集的な
  8. iOSアプリ開発に役立つTips100連発!  - これもTIPS集。凄い数

さて、今回は三日坊主にならない様にしないとな。
つーか、現職ではこういうディジタル、モバイル系のセンスは本業にも活きる筈だから、積極的にシナジーを出していかないとなあ。

(11/16 追記)
カメラで撮ったら保存したいわけだが、その際のコードは下記を参照。

(11/16 追記2)
CoreLocationで現在の位置情報を取得する点は下記を参照。

(11/16 追記3)
参考にさせて頂いたコードでNSDictionaryへの値置き換え周りでコンパイルエラーが起きるのでこちらも参照。