ASIHTTPRequest と XCode4.3.1
XCode 4.3.1を利用して、ASIHTTPRequestを利用しようとして、手間取ったのでそれをまとめます。
target OSは5.1を想定して作っています。
ASHIHTTPRequest Github
https://github.com/pokeb/asi-http-request
設定手順
http://allseeing-i.com/ASIHTTPRequest/Setup-instructions
手順にも書かれていますが、以下のファイルをプロジェクトにコピーする必要があります。
逆にいうと、他のファイルは不要。
- ASIHTTPRequestConfig.h
- ASIHTTPRequestDelegate.h
- ASIProgressDelegate.h
- ASICacheDelegate.h
- ASIHTTPRequest.h
- ASIHTTPRequest.m
- ASIDataCompressor.h
- ASIDataCompressor.m
- ASIDataDecompressor.h
- ASIDataDecompressor.m
- ASIFormDataRequest.h
- ASIInputStream.h
- ASIInputStream.m
- ASIFormDataRequest.m
- ASINetworkQueue.h
- ASINetworkQueue.m
- ASIDownloadCache.h
- ASIDownloadCache.m
- ASIAuthenticationDialog.h
- ASIAuthenticationDialog.m
- Reachability.h (External/Reachability フォルダにあります)
- Reachability.m ( 〃 )
また、frameworkの追加から以下を追加
- CFNetwork.framework,
- SystemConfiguration.framework,
- MobileCoreServices.framework,
- CoreGraphics.framework,
- libz.dylib
Xcode 4.2以降だと、ARC(Automatic Reference Counting)がデフォルトで有効になっており、コンパイルしようとしても、retainやautoreleaseなどのリファレンスカウンタを制御する文で、エラーとなっていまいコンパイルできない。
ファイル単位でARCを解除できるので、Build Phasesから取り込んだファイルだけ、ARCを解除する。
ソースの横にある -fno-objc-arc を追加してやる。
下のObjective-Cプログラムは、現在書き途中のカメラアプリの一部サンプルソース。
cameraBtnActionメソッドで、カメラを起動して postBtnActionメソッドで撮影した画像を ASIHTTPRequest を利用しサーバーに送信しています。サーバーはbasic認証で Contents-Type は multipart/form-data のデータを受け取ります。
#import "ViewController.h" #import "ASIHTTPRequest.h" #import "ASIFormDataRequest.h" @interface ViewController () @end @implementation ViewController @synthesize pictureImageView = _pictureImageView; #define URL @"http://example.com/post/" #define USER_ID @"user_id" #define PASSWORD @"password" - (void)viewDidUnload { [self setPictureImageView:nil]; [super viewDidUnload]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } - (IBAction)cameraBtnAction:(id)sender { if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { NSLog(@"カメラがついてない機種です。"); return; } UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init]; imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera; imagePickerController.delegate = self; [self presentModalViewController:imagePickerController animated:YES]; } - (IBAction)postBtnAction:(id)sender { NSURL *url = [NSURL URLWithString:URL]; ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; [request setUsername:USER_ID]; [request setPassword:PASSWORD]; NSData *imageData = UIImageJPEGRepresentation(self.pictureImageView.image, 0.9); [request setData:imageData withFileName:@"coordi.jpg" andContentType:@"image/jpeg" forKey:@"image"]; [request setDelegate:self]; [request setDidFinishSelector:@selector(uploadRequestFinished:)]; [request setDidFailSelector:@selector(uploadRequestFailed:)]; [request startAsynchronous]; } - (void)uploadRequestFinished:(ASIHTTPRequest *)request{ NSString *responseString = [request responseString]; NSLog(@"Upload response %@", responseString); } - (void)uploadRequestFailed:(ASIHTTPRequest *)request{ NSLog(@" Error - Statistics file upload failed: \"%@\"",[[request error] localizedDescription]); } - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [self dismissModalViewControllerAnimated:YES]; } - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo { [self dismissModalViewControllerAnimated:YES]; self.pictureImageView.image = image; } @end
Mac homebrewとgitを入れる
- XCodeを入れる。
- homebrewを入れる
$ ruby -e "$(curl -fsSLk https://gist.github.com/raw/323731/install_homebrew.rb)"
- gitを入れようとする
$ brew install git
- 以下のエラーがでる場合は、XCodeを開いて Preferences-Download-Command Line Toolsをダウンロードしてから、できるようになります。
- エラー内容
==> Downloading http://git-core.googlecode.com/files/git-1.7.9.2.tar.gz File already downloaded in /Users/aaa/Library/Caches/Homebrew ==> make prefix=/usr/local/Cellar/git/1.7.9.2 CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clan GIT_VERSION = 1.7.9.2 * new build flags or prefix * new link flags ./generate-cmdlist.sh > common-cmds.h+ && mv common-cmds.h+ common-cmds.h /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -o hex.o -c -MF ./.depend/hex.o.d -MMD -MP -Os -w -pipe -march=native -Qunused-arguments -I. -DUSE_ST_TIMESPEC -DNO_GETTEXT -DHAVE_DEV_TTY -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM hex.c /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -o ident.o -c -MF ./.depend/ident.o.d -MMD -MP -Os -w -pipe -march=native -Qunused-arguments -I. -DUSE_ST_TIMESPEC -DNO_GETTEXT -DHAVE_DEV_TTY -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM ident.c /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -o kwset.o -c -MF ./.depend/kwset.o.d -MMD -MP -Os -w -pipe -march=native -Qunused-arguments -I. -DUSE_ST_TIMESPEC -DNO_GETTEXT -DHAVE_DEV_TTY -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM kwset.c /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -o levenshtein.o -c -MF ./.depend/levenshtein.o.d -MMD -MP -Os -w -pipe -march=native -Qunused-arguments -I. -DUSE_ST_TIMESPEC -DNO_GETTEXT -DHAVE_DEV_TTY -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM levenshtein.c /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -o list-objects.o -c -MF ./.depend/list-objects.o.d -MMD -MP -Os -w -pipe -march=native -Qunused-arguments -I. -DUSE_ST_TIMESPEC -DNO_GETTEXT -DHAVE_DEV_TTY -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM list-objects.c /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -o ll-merge.o -c -MF ./.depend/ll-merge.o.d -MMD -MP -Os -w -pipe -march=native -Qunused-arguments -I. -DUSE_ST_TIMESPEC -DNO_GETTEXT -DHAVE_DEV_TTY -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM ll-merge.c /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -o lockfile.o -c -MF ./.depend/lockfile.o.d -MMD -MP -Os -w -pipe -march=native -Qunused-arguments -I. -DUSE_ST_TIMESPEC -DNO_GETTEXT -DHAVE_DEV_TTY -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM lockfile.c In file included from hex.c:1: In file included from ./cache.h:In file included from ident.c:8: In file included from 4: ./git-compat-util.h:93:10:./cache.h:4: ./git-compat-util.h:93:10: fatal error: 'unistd.h' file not found fatal error: 'unistd.h' file not found #include <unistd.h> ^ #include <unistd.h> ^ In file included from kwset.c:37: In file included from ./cache.h:4: ./git-compat-util.h:93:10: fatal error: 'unistd.h' file not found #include <unistd.h> ^ In file included from levenshtein.c:1: In file included from ./cache.h:4: ./git-compat-util.h:93:10: fatal error: 'unistd.h' file not found #include <unistd.h> ^ In file included from ll-merge.c:7: In file included from ./cache.h:4: ./git-compat-util.h:93:10: fatal error: 'unistd.h' file not found #include <unistd.h> ^ In file included from list-objects.c:1: In file included from ./cache.h:4: ./git-compat-util.h:93:10: fatal error: 'unistd.h' file not found #include <unistd.h> ^ In file included from lockfile.c:4: In file included from ./cache.h:4: ./git-compat-util.h:93:10: fatal error: 'unistd.h' file not found #include <unistd.h> ^ 1 error generated. 1 error generated. 1 error generated. make: *** [levenshtein.o] Error 1 make: *** Waiting for unfinished jobs.... make: *** [hex.o] Error 1 1 error generated. make: *** [ident.o] Error 1 make: *** [lockfile.o] Error 1 1 error generated. make: *** [ll-merge.o] Error 1 1 error generated. make: *** [kwset.o] Error 1 1 error generated. make: *** [list-objects.o] Error 1 ==> Exit Status: 2 http://github.com/mxcl/homebrew/blob/master/Library/Formula/git.rb#L47 ==> Environment HOMEBREW_VERSION: 0.8.1 HEAD: (none) HOMEBREW_PREFIX: /usr/local HOMEBREW_CELLAR: /usr/local/Cellar Hardware: 8-core 64-bit sandybridge OS X: 10.7.3 Kernel Architecture: x86_64 Xcode: 3.2.2 GCC-4.0: N/A GCC-4.2: N/A LLVM: build 2336 Clang: N/A MacPorts or Fink? false X11: /usr/X11 System Ruby: 1.8.7-249 /usr/bin/ruby => /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby Which Perl: /usr/bin/perl Which Python: /usr/bin/python Which Ruby: /usr/bin/ruby => /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby ==> Build Flags CC: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang CXX: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ => /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang LD: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang CFLAGS: -Os -w -pipe -march=native -Qunused-arguments CXXFLAGS: -Os -w -pipe -march=native -Qunused-arguments MAKEFLAGS: -j8 Error: Failed executing: make prefix=/usr/local/Cellar/git/1.7.9.2 CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang CFLAGS=-Os\ -w\ -pipe\ -march=native\ -Qunused-arguments LDFLAGS= install These existing issues may help you: https://github.com/mxcl/homebrew/issues/9023 https://github.com/mxcl/homebrew/issues/9618 https://github.com/mxcl/homebrew/issues/10225 https://github.com/mxcl/homebrew/issues/10544 Otherwise, please report the bug: https://github.com/mxcl/homebrew/wiki/checklist-before-filing-a-new-issue
Corona SDKで、Google画像検索+Jsonパース+画像取得+アニメーションさせてみた
Corona SDKのサンプルソースを見ながら、コードを書いてみた。
たった、数十行でこれだけの事ができるなんて、感動しちゃいます。
内容)
HTTPのリクエストで、Google 画像サーチAPIをたたいて、Jsonの結果をデコード
require("json") http = require("socket.http") data = json.decode(http.request("http://ajax.googleapis.com/ajax/services/search/images?q=KARA&v=1.0"))
画像のURLから、画像の取得したオブジェクトをつくる
function networkListener( event ) if ( event.isError ) then print ( "Network error - download failed" ) else event.target.x = math.random(300) event.target.y = - 100 - math.random(600) physics.addBody( event.target, { density=0.9, friction=0.2, bounce=0.3} ) end end display.loadRemoteImage(value.tbUrl, "GET", networkListener, value.imageId, system.TemporaryDirectory)
出来上がった、全ソース
physics = require("physics") --重力設定 physics.start() --重力開始 require("json") http = require("socket.http") -- HTTPのRequest display.setStatusBar( display.HiddenStatusBar ) --ステータスバーを消す data = json.decode(http.request("http://ajax.googleapis.com/ajax/services/search/images?q=KARA&v=1.0")) function networkListener( event ) if ( event.isError ) then print ( "Network error - download failed" ) else event.target.x = math.random(300) -- 画像の位置をランダムに散らす event.target.y = - 100 - math.random(600) -- 画像の位置をランダムに散らす physics.addBody( event.target, { density=0.9, friction=0.2, bounce=0.3} ) end end local function onTilt( event ) physics.setGravity( 10 * event.xGravity, -10 * event.yGravity ) -- 加速度センサーで、重力の設定を変える end Runtime:addEventListener( "accelerometer", onTilt ) -- 加速度センサーのイベント追加 for key, value in pairs(data.responseData.results) do -- ネットの画像を取得する display.loadRemoteImage(value.tbUrl, "GET", networkListener, value.imageId, system.TemporaryDirectory) end
ただ、実機確認しようとするとコンパイルするのに、ソースをサーバーに送らないとコンパイルしてくれないので、1分弱待たされます。シュミレーターもあるんですが、ジャイロセンサーなどを使おうとなると、すぐにデバッグできないので結構イライラしました。
Androidアプリ リリースバージョンでClassNotFoundException
Debug中では起こらなかった、ClassNotFoundExceptionが必ず発生するエラーを仕込んだままリリースするという事故が起きた。
デバッグでは、コンパイルできて正しく実行できているのに、リリースでコンパイルしたapkファイルを逆コンパイルして確認してみると、あるはずのclassファイルが消えてなくなっている・・・。
丸1日調査して解決したのが、どうもProGuardでやらかしているようだ。
もともとの原因は、今まで開発していた環境から Android SDK Toolsのバージョンアップをr16にアップデートした事が始まりっぽい。
どうも古いProGuardの設定が悪さをするようだ・・・。
下記ブログその手順どおりやって、どうにか対処できました。
http://wada811.blog.fc2.com/blog-entry-62.html
Android toolのExport Signed Application packeageからビルドすると、最後に「Conversion to Dalvik format failed with error 1」などが出た場合は、プロジェクトのcleanをしてから再度実施。
当然だと思われるかもしれないが、リリースする前にコンパイルしたapkファイルは一度実機で動作確認してから、リリースしたほうがよさそうだ。
Corona SDK勉強会 参加しました
Corona SDK 勉強会 in 渋谷 に参加してきました。
[ATND]
http://atnd.org/events/23395
Corona SDK
Flashエンジニアが今までの資産などを使って、簡単にゲームができるという雰囲気でした。Unity3Dと比べると、今までのFlashで作った素材などを利用できるのは、大きいかなおと思います。
Flashでアニメーションを作ってから、一枚の画像ファイルに書き直して、CSSスプライトのような事をして画像の読み込みを少なくして、速度をあげるようです。
その後、Corona SDKでその素材をもとにゲームなどをつくる手順っぽい。
ただ、Unity3Dと比べると、GREEのSDKなどに簡単につながる機能がないので、iTunes Store、Android Marketでゲーム単体として売る事を目的にしか利用できなさそうな感じでした。
日本コロナの会 山本 直也さん(発表資料)
https://sites.google.com/site/corona20120201/
Coronaでよく聞かれること 木村さん
Storyboard API 鍵山さん
http://keygx.blogspot.com/2012/02/storyboard-api-corona-sdk.html
flasherがcoronaを使う 寺井さん
http://nijibox.jp/smap/category/coronasdk/
drops
http://www.calm-design.com/lifestyle/Apps.html
あと、Corona SDKの日本語書籍が、2/24に発売されるそうです。
http://www.7netshopping.jp/books/detail/-/accd/1106122300
大きい画像をImageViewで表示しようとするとOutOfMemory起こすよ
カメラで撮った画像などをそのままImageViewで表示しようとすると、画像がサイズが大きすぎて、簡単にOutOfMemoryが発生してたので、file_pathを渡すと小さい画像のBitmapに変換するプログラムを書いて利用しています。
カメラで撮った画像をそのまま利用する事がないという想定です・・・。
たとえば、サーバーに画像を送信するときなど、どの画像を選択したのかサムネイル表示する際に利用していただければいいと思います。
サイズは適当です・・・。
package jp.sharakova.util; import android.graphics.Bitmap; import android.graphics.BitmapFactory; public class BitmapResize { public static Bitmap decodeLargeFile(String path) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; int scaleW = options.outWidth / 380 + 1; int scaleH = options.outHeight / 420 + 1; int scale = Math.max(scaleW, scaleH); options.inJustDecodeBounds = false; options.inSampleSize = scale; return BitmapFactory.decodeFile(path, options); } }
Google Map API keyをデバッグ、リリースで分ける
Google Map API Keyは、リリースとデバッグで分ける必要があったので、プログラムでdebugとreleaseの判定をできるようにしました。
ApplicationInfo.FLAG_DEBUGGABLEのフラグがたっているかで、判定しています。
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0); return ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == ApplicationInfo.FLAG_DEBUGGABLE);
サンプルコード
MapView map = new MapView(this, GoogleMapKey.getKey());
package jp.sharakova.app.android.golfcaddie.utils; import android.content.Context; import android.content.pm.ApplicationInfo; public class GoogleMapKey { public static String getKey (Context context) { // TODO: DEBUGとRELEASEのキーを記述 return isDebug(context) ? "DEBUG_GOOGLE_MAP_API_KEY" : "RELEASE_GOOGLE_MAP_API_KEY"; } private static Boolean isDebug(Context context){ try { ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0); return ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == ApplicationInfo.FLAG_DEBUGGABLE); } catch (Exception e) { e.getStackTrace(); return false; } } }