iPhoneでZipファイルを扱うライブラリ ZipArchive
このライブラリを利用するには、「libz.xxxxx.dylib」フレームワークが必要。
非常に簡単、読み込みファイルパスと書き込みファイルパスを指定して、UnzipFileToメソッドを利用するだけ。
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *outputPath = [paths objectAtIndex:0];
NSString *loadFilePath = [[NSBundle mainBundle] pathForResource:@"test"ofType:@"zip"];
ZipArchive *zipArchive = [[ZipArchive alloc] init];
if([zipArchive UnzipOpenFile:loadFilePath]) {
BOOL result = [zipArchive UnzipFileTo:[outputPath stringByAppendingPathComponent:@"ext"] overWrite:YES];
if(result) {
NSLog(@"success!");
} else {
NSLog(@"error!");
}
[zipArchive UnzipCloseFile];
}
[zipArchive release];
以下のディレクトリに書き出される。
/Users/userName/Library/Application Support/iPhone Simulator/version/Applications/appCode/Documents/ext
すばらしい!
うかうかしていたら、Developer用のProvisioning Profileの更新期限が切れてしまった。
で、更新方法は (1) iPhone Developer Program Portal にアクセス (2) Provisioningを選択し、Provisioningファイル一覧の【Renew】をクリックして更新 (3) 【Download】に変わったらProvisioning Profileファイルをダウンロード (4) Xcodeのオーガナイザを開く。 (5) DEVICESを選択し、Provisioning欄の古いProvisioningファイルを削除 (6) 【+】で新しいcProvisioningファイルを選択 ※Provisioningをダブルクリックでインストールすると、なぜかうまくいかなかった (7) Xcodeのプロジェクト設定を編集を開き、コード署名で更新したProvisioningになっているか確認。
ゲーム機Xbox 360の新機種に付属する KinectをPCで利用できるライブラリがあるという。
以前、WiiのリモコンでPCアプリを操作するサンプルをActionScript経由で試した事がある。 ただ、安定性がよくないのとタスクを常に起動しておかないといけないので、あまり実用的ではない気がして保留のままだ。
しかし、今回のXbox 360 Kinectセンサーのライブラリがでており、これはかなり実用性がありそうだ。 Kinect Hack 現状まとめ
Xboxの次世代機器の発表(Kinect)があった時に、個人的に
これは・・・マイクロソフトも捨てたものではないな
と感じた。
基本はC言語ですが、ActionScriptのライブラリもあるみたい。 ちなみにX-codeで開発する場合は
・Kinectを購入 ・OpenKinectとlibusbをダウンロード ・OpenKinectのソースをmakeしてインストール ・Xcodeでコーディング&ビルド ・USB接続でサーバが自動起動(するらしい)
Kinect ハック on Mac OS X:(1) OpenKinect サンプルの実行
何かKinectを使った様々なサービスが浮かんでくる・・・。 と言う事でXbox 360 Kinectセンサーを買う事にするw
WebでAPIを用意してPOSTリクエストし、結果を取得する方法。 基本的にNSMutableURLRequestを利用するが、同期・非同期によってコーディングや構造が異なってくる。 取りあえず処理しやすい同期で実装してみる。
・API URL:http://hoge.com/user_login/ ※APIのプログラムは省略 ・POSTデータ:id、passwd ・API出力データ:JSON
[cpp] NSString *urlString = [self userLoginURI:loginId :password]; NSString *postString = [NSString stringWithFormat:@"id=%@&passwd=%@", loginId, password]; NSData *post = [postString dataUsingEncoding:NSUTF8StringEncoding];
NSURL* url = @"http://hoge.com/user_login/";
NSMutableURLRequest* urlRequest = [[NSMutableURLRequest alloc]initWithURL:url];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
[urlRequest setHTTPBody:post];
NSURLResponse* response;
NSError* error = nil;
NSData* result = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
NSString* resultString = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
NSLog(@"%@", resultString);
if (result != nil) {
NSDictionary *results = [NSDictionary alloc];
results = [[resultString JSONValue] retain];
[user bind:results];
NSLog(@"%@", results);
}
同期処理と言う事で、sendSynchronousRequest:urlRequestメソッドを利用する。
超基本なんだろうな?ってメモ。 数値データ(文字列型)の桁区切り表示。
NSNumberやintからNSStringで桁区切りする例は検索に出てくるけど、 NSStringをそのまま桁区切りする方法が見つからない・・・。 こういうのは、スクリプト言語なら楽なんですけどねぇ。
型変換やキャストで数行必要かな?と思ったけど、NSNumberFormatterでnumberFromString→numberFromStringとしてやると楽かも(!?)
- (NSString *)formatNumber:(NSString *)value {
NSNumberFormatter *formatter=[[[NSNumberFormatter alloc] init] autorelease];
[formatter setPositiveFormat:@"#,##0"];
NSNumber *number = [formatter numberFromString:value];
return [formatter stringFromNumber:number];
}
そもそも外部データを取り込んだ時点で、数値データをint型等に変換すべきではあるのかも知れないけど。 numberFromStringに数字じゃない文字列いれたらどうなるんだろうか?というエラー検証はしてません(^^;)
会社用の証明書を作成して設定していたら、ビルドは成功したのに実機起動時に以下のエラー。
プロビジョニングされた iPhone OS 装置が接続されていません。
どうやら、実機のiPhoneのOS4.1で、Xcodeのバージョンが対応していないとこのエラーがでるようだ。
しかし「プロビジョニングに失敗した?」と勘違いしてしまうエラーメッセージのような気がする。。。
SJIS、EUC-JPからUTF-8に変換する場合、Windows拡張の機種依存文字を含んでいると文字化けする。 その場合、文字コードパラメータを「-win」してやると解決できるようだ。
//Shift-JIS → UTF-8
mb_convert_encoding($value, 'UTF-8', 'SJIS');
mb_convert_encoding($value, 'UTF-8', 'sjis-win'); //Windows拡張対応
//EUC-JP → UTF-8
mb_convert_encoding($value, 'UTF-8', 'EUC-JP');
mb_convert_encoding($value, 'UTF-8', 'eucJP-win'); //Windows拡張対応
UIButtonやUITableViewなどのイベントではなく、画面のタッチイベントについて。
UIResponderクラスで管理している。
#import
#import
#import
UIKIT_EXTERN_CLASS @interface UIResponder : NSObject {
@private
}
- (UIResponder*)nextResponder;
- (BOOL)canBecomeFirstResponder; // default is NO
- (BOOL)becomeFirstResponder;
- (BOOL)canResignFirstResponder; // default is YES
- (BOOL)resignFirstResponder;
- (BOOL)isFirstResponder;
// Generally, all responders which do custom touch handling should override all four of these methods.
// Your responder will receive either touchesEnded:withEvent: or touchesCancelled:withEvent: for each
// touch it is handling (those touches it received in touchesBegan:withEvent:).
// *** You must handle cancelled touches to ensure correct behavior in your application. Failure to
// do so is very likely to lead to incorrect behavior or crashes.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)remoteControlReceivedWithEvent:(UIEvent *)event __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0);
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
@property(nonatomic,readonly) NSUndoManager *undoManager __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
@end
@interface NSObject(UIResponderStandardEditActions) // these methods are not implemented in NSObject
- (void)cut:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)copy:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)paste:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)select:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)selectAll:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)delete:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_2);
@end
@interface UIResponder (UIResponderInputViewAdditions)
// Called and presented when object becomes first responder. Goes up the responder chain.
@property (readonly, retain) UIView *inputView __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_2);
@property (readonly, retain) UIView *inputAccessoryView __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_2);
// If called while object is first responder, reloads inputView and inputAccessoryView. Otherwise ignored.
- (void)reloadInputViews __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_2);
@end
この中で頻度が高そうなメソッドは、
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
かと。 これで、お絵描きソフトとかで描画したり。
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ([touch tapCount] == 2) {
NSLog(@"double touch");
}
}
ただし、画面の上に他のUIViewが追加されていると当然ながらイベントは発生しません。
タイマーで定期時間に処理をさせる場合、NSTimer scheduledTimerWithTimeIntervalを利用しますが、
状況によっては、発動したりしなかったりする
まず、基礎的なコードは以下の通り。
- (void)play {
NSLog(@"---- play ----");
timer = [NSTimer scheduledTimerWithTimeInterval: 1.0f
target: self
selector:@selector(updateTimer:)
userInfo: nil
repeats:YES];
}
- (void)updateTimer:(NSTimer *)timer {
NSLog(@"---- updateTimer ----");
}
これをviewDidLoad内のスコープで動作させたのですが、タイマーが(selector)発動しませんでした。 同じ処理を簡単なサンプルで動かした場合は発動しました。
同じスコープ内に時間のかかる処理をさせてはいけない?
という事なんですかね?
Second Flush NSTimerクラスによると、NSRunLoopでスレッドの監視が起因しているようですが、まだ詳しくは読んでないのでちゃんとしたロジックはわかりません。 しかし、上記のサイトは素人とか言いながら、かなり濃いトピックが載っている感じで参考になりそう。
iPhoneアプリを実機でテストしてみるで、Apple Developerサイトでアプリ証明書の作成やら実機テストやら記載しました。
新しいMacを買ったので、複数台のMacで開発することになりました。 ソースはSVN等で管理すれば良いので問題ないと思いますが、実機テストはそのままではできません。
ただし、また1から登録する必要はなく、
証明書とProvisioning Profilesは登録済みのものを使い回します
(1) 開発登録済みのMacでキーチェンアクセスを開き、自分の証明書を選択する。
(2) iPhone Developer証明書を右クリックでp12ファイルを書き出す。 ※パスワードを入力する
(3) 同様にiPhone Distribution証明書も書き出す。
(4) 新規Macに証明書をコピーする。
(5) 証明書をダブルクリックし、先ほど入力したパスワードで登録する。
ネットで調べると、チェンアクセスの移行だけでOKみたいな感じだったが、自分はダメでした。
(1) 開発登録済みのMacでXcodeのウィンドウ>オーガナイザを開く。
(2) Export Developer Profile...でprofilesを書き出し、新規Macにprofilesをコピーする。
(3) 新規MacのXcodeのウィンドウ>オーガナイザを開き、import Developer Profile...でprofilesを取り込む。