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 のデータを受け取ります。

  • uploadRequestFinished 送信完了 delegate
  • uploadRequestFailed エラーだった場合 delegate
#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