iPhone SDK on PPC で配布用ビルドを行う

先日の「iPhone SDK on PPC でデバイス用ビルドを行う」と同じようにやっても、ビルドは出来るものの AppStore には登録できません。いろいろ調べてみたところ、結論としては、先日の参照リンクでも議論されていた件と同じことのようです。

PPCでビルドするために/usr/bin/codesignをスクリプトで置き換えるわけですが、その時、スクリプトの中で以下のような操作を行っているところがあります。

rm Application.app/CodeResources
cp Application.app/_CodeSignature/CodeResources Application.app/CodeResources

これはこれで、普段のデバイス用ビルドではうまく行くのですが、AppStore からは受け付けてもらえません。どうしたらよいかというと、本来の形のように、シンボリックリンクにする必要があります。つまりこう。

rm Application.app/CodeResources
ln -sf Application.app/_CodeSignature/CodeResources Application.app/CodeResources

これで AppStore にアップロードできるようになりました。

が、AdHoc なバイナリを作ろうとすると、同じようにはいかず、今度は先述のコピーのままでうまくいくようです。この辺りがなんだかややこしいことになっていますが、普段は先日のスクリプト(コピー版)を使用して、AppStore に上げる時だけシンボリックリンクに書き換える、というのがとりあえずは妥当な作業ではないかと。

まあ、ちょっと一手間かかりますが、非推奨環境ですから、、、ね。というか、いわゆるクロス開発なのにホストアーキテクチャによる差違がこの程度で済むならいいんじゃないでしょうか、とも。

iPhone SDK on PPC でデバイス用ビルドを行う

PPC上のiPhone SDKでデバイス用のビルドを行うと、codesign のエラーが出てしまいます。これはほんとにどうしようもなくて、、、

で、解決策としては、こちらを参照。

ここにある perl スクリプトを書いてある通りに使用すればうまくいくようです。

が、そこにある CodeResources をコピーするのかシンボリックリンクにするのか、という件については、また後ほど。

iPhone SDKをPowerPCにインストールする

iPhone SDKは開発環境としてIntel Macを要求しているわけですが、一応PPCでもインストールして使うことが出来ます。

基本的には、こちらを参照。

ただし、情報がBeta2用ですし、ちょっと補足。

  • インストーライメージ内の Packages の中で個別インストールする必要があるのは、iPhone***.pkgというやつと、DeveloperDiskImage.pkg
  • 上記ページにリンクのある xcspec ファイルをそのまま利用させてもらう

これで、PPCにiPhone用開発環境を構築できます。

iPhotoプラグインを作る「フォト蔵編」-8 : CFNetwork -1

以前、お話していた NSURLRequest と NSURLConnection でサーバとの通信をするというやつですが、いろいろやっているとどうも POST がうまくいきません。必ずうまくいかないというわけではなくて、うまくいかないことがある、というどうにも面倒な感じで。

で、例によって、いろいろとネットを徘徊したところ、なにやら、他のところでもこの件で困っている人がいるようです。

結論としては、NS ではなく CF を使いましょうってことで。手元では CFHTTPMessageRef や CFReadStream を使っての通信(GET も POST も)をなんの問題もなく出来てしまってます。なんか、釈然としないところもあるような感じですが、まあよしということにしましょう。

参考にしたのは、以下のあたり。

この件についてもおいおい詳しく書いていくつもりです。

iPhotoプラグインを作る「フォト蔵編」-7 : ExportMgr メモ -1

iPhotoヘのアクセスを担うExportMgrのAPIメモ

書き出し対象の画像数
-(unsigned int) imageCount;
画像ファイルのパス(NSString)
-(id) imagePathAtIndex:(unsigned int)fp8;
画像ファイルのタイトル(NSString)
-(id) imageTitleAtIndex:(unsigned int)fp8;
画像ファイルのコメント(NSString)
-(id) imageCommentsAtIndex:(unsigned int)fp8;
画像ファイルのキーワード(NSArray)
-(id) imageKeywordsAtIndex:(unsigned int)fp8;

とりあえず、このあたりがあれば、必要な情報は手に入れられそうです。

Labの過去記事を復活させました

サーバ故障からようやく本格的に立ち直ってきました。最後のバックアップがとれていた2007年5月以前のブログデータをそのままの形で復活させました。一応、mod_rewriteも使って、以前のURLでもアクセスできるはず。

2007年5月以降のデータはというと、そんなに更新頻度が高くなかったおかげでもあって幸いにもキャッシュに残っていたので、こちらの新規ブログにすでに掲載済みです。

昔のもいずれ、こちらに統合しようかと思っているんですが、まあ、前のURLを補完したいっていうのもありますし、難しいところですね。

iPhotoプラグインを作る「フォト蔵編」-6 : フォト蔵APIヘのアクセス-2 : 写真のアップロード

前回までの NSURLRequest の話を利用して、実際にフォト蔵へ写真をアップロードしてみましょう。使用するAPIは photo_add です。

#define ASCII_DATA(str) [(NSString*)(str) dataUsingEncoding:NSASCIIStringEncoding]
 
{
    NSURL* apiUrl = [NSURL URLWithString:@"http://api.photozou.jp/rest/photo_add"];
    NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:apiUrl];
    // Base64エンコーディング
    NSData* baseData = ASCII_DATA(([NSString stringWithFormat:@"%@:%@", username, password]));
    NSString* baseStr = [baseData stringEncodedWithBase64];
    // Basic認証ヘッダ追加
    [req setValue:[NSString stringWithFormat:@"Basic %@", baseStr] forHTTPHeaderField:@"Authorization"];
 
    // 画像パス
    NSURL* imgUrl = [NSURL fileURLWithPath:imgPath];
    // マルチパート生成 (<a href="http://110k.net/?p=27">前回のエントリ</a>参照)
    NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
        album_id,   @"album_id",
        imgUrl,       @"photo",
        nil];
    NSData* formData = [self generateFormData:params boundary:@"___boundary___"];
    [req addValue: @"multipart/form-data; boundary=___boundary___" forHTTPHeaderField: @"Content-Type"];
    [req setHTTPBody:formData];
 
    // POSTで送信
    [req setHTTPMethod:@"POST"];
    NSURLResponse* res;
    NSData* response = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:nil];
}

これで、各種パラメータを適切に設定できていれば、指定のアルバムに指定の画像ファイルを追加することが出来ます。ここまでくれば、まあ、あともう少しですかね。多分。

iPhotoプラグインを作る「フォト蔵編」-5 : NSURLRequest -2 : データ転送

次は、NSURLRequestでデータを転送する話。特にPOSTの場合。

これもよくわからなかったので、いろいろとネットを徘徊した結果、こちらを参考にしました。

要するに、マルチパートのメッセージを自前でこしらえる必要があるっていうだけのことなんですが、まあ、一から考えるのは手間がかかるので、既存のサンプルを参考にさせてもらったといいますか。

単純にContent-Typeをimage/jpeg固定だとして、上記ソースにちょっとだけ手を加えたものが、以下の通りです。

#define ASCII_DATA(str) [(NSString*)(str) dataUsingEncoding:NSASCIIStringEncoding]
 
// マルチパート生成
-(NSData*) generateFormData:(NSDictionary*)dict boundary:(NSString*)boundary
{
    NSMutableData* result = [[NSMutableData alloc] init];
    id key;
    NSEnumerator* enume = [dict keyEnumerator];
 
    while (key = [enume nextObject]) {
        id value = [dict valueForKey:key];
        [result appendData:ASCII_DATA(([NSString stringWithFormat:@"--%@\\n", boundary]))];
        if ([value isKindOfClass:[NSString class]]) {
            // 文字列
            // 単純に追加
            [result appendData:ASCII_DATA(([NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\\n\\n", key]))];
            [result appendData:ASCII_DATA(([NSString stringWithFormat:@"%@",value]))];
        } else if ([value class] == [NSURL class] && [value isFileURL]) {
            // データパス
            // データパス文字列を追加
            [result appendData:ASCII_DATA(([NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\\n", key, [[value path] lastPathComponent]]))];
            // Content-Type
            [result appendData:ASCII_DATA(([NSString stringWithString:@"Content-Type: image/jpeg\\n\\n"]))];
            // データの追加
            [result appendData:[NSData dataWithContentsOfFile:[value path]]];
        }
        [result appendData:ASCII_DATA(([NSString stringWithString:@"\\n"]))];
    }
    [result appendData:ASCII_DATA(([NSString stringWithFormat:@"--%@--\\n", boundary]))];
    return [result autorelease];
}
 
// 呼び出し側
{
    NSData* formData = [self generateFormData:params boundary:@"___boundary___"];
    [req addValue: @"multipart/form-data; boundary=___boundary___" forHTTPHeaderField: @"Content-Type"];
    [req setHTTPBody:formData];
}

とりあえず、これでファイルのPOSTはうまくいきます。

iPhotoプラグインを作る「フォト蔵編」-4 : NSURLRequest -1 : Basic認証

ちょっとの間、フォト蔵、というよりCocoaによる通信のお話。

CocoaでHTTP等の通信を行う場合、NSURLRequestを使うのが一般的でしょう。ここでは、NSURLRequestの一般的な使い方、というより、ちょっとだけ突っ込んだところを見てみます。

で、Basic認証です。Basic認証についての概要は毎度おなじみWikipediaにたよるとして、要するに、username:passwordの組み合わせをBase64でエンコードして、HTTPヘッダにのっける(Authorization: Basic xxxxxx)ということです。やることは二つですね。順番に見ていきましょう。

Base64エンコード

これは、ネットで公開されているサンプルソースをお借りすることにしましょう。(感謝感謝>グースさん)

NSDataのカテゴリとして実装されているので、非常に便利な感じです。ここではNSDataをNSStringとして出力する形となっていますので、そのまま使うとすれば、こういうふうになります。

NSData* data = [[NSString stringWithFormat:@"%@:%@", username, password]
    dataUsingEncoding:NSASCIIStringEncoding];
NSString* base64Str = [data stringEncodedWithBase64];

簡単ですね。

HTTPヘッダへの追加

NSURLRequestのインスタンスにヘッダ情報を追加するわけですが、NSURLRequestはimmutableなのでNSMutableURLRequestを使用します。

// NSMutableURLRequest
-(void) setValue:(NSString*)value forHTTPHeaderField:(NSString*)field;

前述のからの流れとしてはこういう感じになります。

NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
[req setValue:[NSString stringWithFormat:@"Basic %@", base64Str]
    forHTTPHeaderField:@"Authorization"];

で、このreqを用いて、POSTなりGETをしてあげればOKです。

iPhotoプラグインを作る「フォト蔵編」-3 : フォト蔵APIヘのアクセス-1 : まずはcurlで

さて、プラグイン側のひな形も出来たところで、次はフォト蔵へのアクセスを考えましょう。

多くのWebサービスがそうであるように、フォト蔵も外部からアクセスするためのAPIを公開しています。

このAPIはRESTと呼ばれるタイプでして、ものすごく簡単にいうと、指定のURLに対してGETやらPOSTでアクセスすると結果としてXMLが返ってくる、というものです。

あとは、上記サイトに書いてある通りのAPI仕様なのですが、まあ、ここで気にすべきは

  • 認証はBasic認証
  • ファイル送信時にはContent-Typeを指定(全部小文字)

くらいのものでしょう。

早速、試しにcurlを使って nop にアクセスしてみるとこんな感じ。

# curl -u mail@example.com:password http://api.photozou.jp/rest/nop
<?xml version="1.0" encoding="UTF-8" ?>
<rsp stat="ok">
</rsp>

次はこれを Cocoa から動かします。

←Older