iPhoneのサンプルプログラム

加速度の記録とアップロード

upload1a.cgi(サーバー側のCGI)
#!/usr/local/bin/perl
use CGI;
use File::Copy;
use File::Basename;

my ($sec, $min, $hour, $day, $mon, $year) = localtime(time);
$year += 1900;
$mon += 1;

my $q = new CGI;

my $fh = $q->upload('filename'); # ファイルハンドル兼ファイル名
my $temp_path = $q->tmpFileName($fh); # アップロードされた
                                      #ファイルのフルパス
fileparse_set_fstype('MSDOS');   # WinIE用パス文字設定
# my $filename    = basename($fh); # アップロードされたファイルの
                                 # ファイル名
my $upload_dir  = "../../work";

my $filename = sprintf("%d%02d%02d_%02d%02d%02d.csv", $year, $mon, $day, $hour, $min, $sec);
my $upload_path = "$upload_dir/$filename";

move ($temp_path, $upload_path)  # File::Copy の moveメソッドで
  or die $!;                     # 移動
close($fh);                      # おまじない

print $q->header( -type=>'text/html', -charset=>'euc-jp', );
print <<"END_OF_HTML";
<body><p>完了!</p></body>
END_OF_HTML
 
exit;

Acc_Recorder.h
#import <Foundation/Foundation.h>

@interface Acc_Recorder : NSObject {
    NSMutableArray *arrayData;
}

- (id)init;

- (void)addAcc_Values: (float)ax accY:(float)ay accZ:(float)az;

- (void)upload: (NSString *)url
  dataFilename:(NSString *)data_filename delegate:(id)dg;

- (void)dealloc;

@end

Acc_Recorder.m
#import "Acc_Recorder.h"

@implementation Acc_Recorder


- (id)init
{
    if (self = [super init]) {
        arrayData = [[NSMutableArray alloc] initWithCapacity:100];
    }

    return self;
}

- (void)dealloc
{
    [arrayData release];
    [super dealloc];
}

- (void)addAcc_Values: (float)ax accY:(float)ay accZ:(float)az
{
    [arrayData addObject:[NSNumber numberWithFloat:ax]];
    [arrayData addObject:[NSNumber numberWithFloat:ay]];
    [arrayData addObject:[NSNumber numberWithFloat:az]];
}

- (void)upload:(NSString *)url
  dataFilename:(NSString *)data_filename delegate:(id)dg
{
    NSString *boundary = @"___boundary___";

    // 加速度データのとりまとめ
    NSMutableString *buffer = [NSMutableString stringWithCapacity:120];
    int i = 0;
    for (NSNumber *num in arrayData)
    {
        i++;
        if (i == 3) {
            [buffer appendFormat:@"%f\n", [num floatValue]];
            i = 0;
        }
        else {
            [buffer appendFormat:@"%f,", [num floatValue]];
        }
    }
    NSData *data = [buffer dataUsingEncoding:NSASCIIStringEncoding];

    // 送信先の設定
    NSURL *cgiUrl = [NSURL URLWithString:url];
    NSMutableURLRequest *postReq = [NSMutableURLRequest requestWithURL:cgiUrl];
    [postReq setHTTPMethod:@"POST"];

    // 送信データ準備
    NSMutableData *result = [NSMutableData dataWithCapacity:(NSUInteger)120];

    [result appendData:
     [[NSString stringWithFormat:@"--%@\r\n", boundary]
      dataUsingEncoding:NSASCIIStringEncoding]];

    [result appendData:
     [[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",
       @"filename", data_filename]
      dataUsingEncoding:NSASCIIStringEncoding]];

    [result appendData:
     [[NSString stringWithString:@"Content-Type: text/csv\r\n\r\n"]
      dataUsingEncoding:NSASCIIStringEncoding]];

    [result appendData:data];

    [result appendData:
     [[NSString stringWithString:@"\r\n"]
      dataUsingEncoding:NSASCIIStringEncoding]];

    // user
    [result appendData:
     [[NSString stringWithFormat:@"--%@\r\n", boundary]
      dataUsingEncoding:NSASCIIStringEncoding]];

    // マルチパート終端
    [result appendData:
     [[NSString stringWithFormat:@"--%@--\r\n\r\n", boundary]
      dataUsingEncoding:NSASCIIStringEncoding]];

    // POST実行
    NSString *s1 = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [postReq addValue:s1 forHTTPHeaderField:@"Content-Type"];
    [postReq setHTTPBody:result];

    NSLog(@"通信開始");

    NSURLConnection *conn = [NSURLConnection connectionWithRequest:postReq delegate:dg];

    if (! conn) {
        NSLog(@"送信失敗!");
    }
}

@end

ViewController.h
#import <UIKit/UIKit.h>
#import "Acc_Recorder.h"

typedef enum {
    kInit,
    kOnRecord,
    kUpload,
    kDelete
} AppState;

@interface ViewController : UIViewController {
    IBOutlet UILabel *labelX;
    IBOutlet UILabel *labelY;
    IBOutlet UILabel *labelZ;

    IBOutlet UIButton *btn1;

    AppState state;

    Acc_Recorder *recorder;
}

- (IBAction)onButton1;

@end

ViewController.m
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.

    state = kInit;

    UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
    accel.delegate = nil;
    accel.updateInterval = 1.0f/2.0f; // 加速度のサンプリング間隔[s]

    recorder = nil;

    [labelX setText: [NSString stringWithString:@"x:"]];
    [labelY setText: [NSString stringWithString:@"y:"]];
    [labelZ setText: [NSString stringWithString:@"z:"]];

    [btn1 setTitle:@"測定開始" forState: UIControlStateNormal];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (void)accelerometer:(UIAccelerometer *)acel
        didAccelerate:(UIAcceleration *)acceleration
{
    float ax = acceleration.x;
    float ay = acceleration.y;
    float az = acceleration.z;

    [recorder addAcc_Values:ax accY:ay accZ:az];

    [labelX setText: [NSString stringWithFormat:@"x: %f", ax]];
    [labelY setText: [NSString stringWithFormat:@"y: %f", ay]];
    [labelZ setText: [NSString stringWithFormat:@"z: %f", az]];
}

- (void)onButton1
{
    UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];

    switch (state) {
        case kInit:
            recorder = [[Acc_Recorder alloc] init];

            NSLog(@"delegate start...");
            accel.delegate = self;
            state = kOnRecord;
            [btn1 setTitle:@"測定停止" forState: UIControlStateNormal];
            break;

        case kOnRecord:
            accel.delegate = nil;
            state = kUpload;
            [btn1 setTitle:@"アップロード" forState: UIControlStateNormal];
            break;

        case kUpload:
            state = kInit;
            [btn1 setTitle:@"測定開始" forState: UIControlStateDisabled];
            [recorder upload:@"http://www.tosiyama.jp/personal/cgi/upload1a.cgi"
                dataFilename:@"target_2012.csv" delegate:self];
            break;

        default:
            break;
    }
}

- (void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse *)response
{

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{

}

- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error
{

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [recorder release];
    recorder = nil;
    [btn1 setTitle:@"測定開始" forState: UIControlStateNormal];
}

@end

アプリのIcon(57x57)