September 2009 Archives

iPhone Stencil Kitを注文してみました。

| 0 Comments | 0 TrackBacks
iPhone Stencil Kitが、act2.comで販売されていますが、現在、在庫切れになっているようです。

米国の発売元のWebサイトからも、購入できるようなので、先ほど注文してみました。
(PayPalのアカウントが必要です)

iPhone Stencil Kit | Design Commission

納期に関する情報が明示されていないので、いつ届くかわかりませんが、とりあえず待ってみることにします。



Google Documents List Data APIのドキュメントダウンロード機能を使用することで、ドキュメントをいろいろなフォーマットでエクスポート可能であることを、Google Documentsからドキュメントをダウンロードするにて説明しました。大変便利な機能ですが、試してみると、ちょっとした制約があることに気付きました。

Export for Google Documentsアプリケーションの次バージョン(現在Appleに申請中)で、すべてのドキュメントをPDFとしてExportする機能を追加していますが、実際に出力されるPDFのフォーマットが、期待通りにならないケースがあります。

Documentsタイプの場合
各ドキュメントの「印刷設定」に従って、PDF生成時の用紙サイズなどのフォーマット設定が、決定されるようです。特に何も指定していない場合には、デフォルト値が適用され、用紙の方向は、常に縦方向(Portlait)になります。ただし、用紙サイズのデフォルト値は、ユーザの言語によって異なる値になるようです。
日本語の場合: A4(210mm x 297mm)
英語(US)の場合: Letter(8.5" x 11")
特に用紙サイズを指定しない場合は、言語の設定に注意してください。

Spreadsheetsタイプの場合
Webブラウザから実行する場合は、用紙サイズや向きを指定することができますが、API経由では、常に決まったフォーマットになってしまうようです。試してみたところでは、
用紙サイズ: ユーザの言語設定に関係なく、Letter(8.5" x 11")
用紙の方向: 縦
となりました。

Presentationsタイプの場合
そもそも、用紙サイズという概念がないため、常に固定サイズになるようです。


以上、簡単にまとめてみましたが、いかがでしょうか?
Export for Google Documentsをご使用の際には、PDF変換を使用するか否かを、適宜選択していただければと思います。
将来のバージョンで、柔軟に変換フォーマットを指定できるパラメタが追加されることがあれば、対応を考えたいと思います。

MKMapViewの地図のタイプを変更する。

| 1 Comment | 0 TrackBacks
MKMapViewでは、地図のタイプとして、以下の3種類を選択することができます。
  • マップ
  • 航空写真
  • 地図+写真

今日は、この地図タイプの切り替えについてのトピックです。

ポイントは、以下の通りです。
  • 地図のタイプを選択するセグメントコントロールを用意する。
  • UIControlEventValueChangedイベント(セグメントコントロールの値が変わったタイミングで発行されるイベント)を処理するためのメソッドを定義する。
  • セグメントコントロールの値が変わったタイミングで、地図のタイプを変更する。
  • 地図のタイプの設定は、MKMapViewのmapTypeプロパティの値を設定することで行う。

以下に、実装例を示します。

-- MyViewController.h --

-- MyViewController.m --


簡単でいいですね。
MapKit、とても良く出来ています。

MKMapView上にアノテーションを追加すると、当然、ドラッグして動かしたくなりますよね。
今日は、その時に、アノテーションを "ぽよん" と浮かせる方法についての記事です。

ポイントは、以下の通りです。
- MKPinAnnotationViewのサブクラスで、タッチイベントを処理する。
- touchesBegan:withEvent: が呼ばれたら、MKPinAnnotationViewのimageをピンが浮いているように見える画像と入れ替える。

えっ、それだけ?という方もいらっしゃるかもしれませんが、はい、これだけです。

以下に、実装例を示します。

-- MyPinAnnotationView.h --

-- MyPinAnnotationView.m --


注)
なお、この方法は、Location Clipでは、そうしているというだけで、正しいやり方かどうかはわかりません。ご了承ください。

Export for Google Documentsでは、Google Documentsからダウンロードしたドキュメントファイルを、プレビューする機能を備えています。それは、アプリケーションで複雑なレンダリング処理を実装しているわけではなく、iPhone SDK標準のUIWebViewというコンポーネントを利用して実現しています。
UIWebViewは、その名の通り、Webサイトのコンテンツを表示するためのコンポーネントですが、HTML以外の種類のドキュメントにも対応しており、MS OfficeのドキュメントやPDFの内容を表示することができます。
Export for Google Documentsが、MS Officeの形式に変換したドキュメントを表示している処理は、実は、データをUIWebViewに渡しているだけの簡単な実装で実現されています。

詳細は、以下のドキュメントを参照してください。

Technical Q&A QA1630: Using UIWebView to display select document types

前回は、実際にGoogle Documentsサービスにアクセスして、
  • ドキュメントの一覧をGDataFeedDocListオブジェクトとして取得する
  • さらに、その中に含まれる個々のドキュメントエントリデータの属性情報(GDataEntryDocBaseオブジェクト)を取り出す
といった方法について、説明しました。今回は、そこから一歩進んで、GDataEntryDocBaseオブジェクトの属性情報を使って、目的のドキュメントをダウンロードする方法について説明したいと思います。

GDataEntryDocBase(エントリデータ)オブジェクト

GDataEntryDocBaseは、抽象スーパクラスであり、ドキュメントの種類ごとに、具象クラスが定義されています。
ドキュメントの種類具象クラス名
ドキュメント(文書)GDataEntryStandardDoc
スプレッドシート GDataEntrySpreadsheetDoc
プレゼンテーションGDataEntryPresentationDoc
PDF
GDataEntryPDFDoc
フォルダ
GDataEntryFolderDoc

各具象クラスでは、スプレッドシートの特殊な操作以外には、インタフェースの拡張はされていないので、通常は、GDataEntryDocBaseとして使用します。

ドキュメントの種類を判定する方法

ドキュメントの種類を判定したい場合は、各エントリデータオブジェクトのカテゴリ情報を使用します。
ドキュメント種類は、GDataDocConstants.hに定数定義されています。
_EXTERN NSString* const kGDataCategoryFolderDoc         _INITIALIZE_AS(@"http://schemas.google.com/docs/2007#folder");
_EXTERN NSString* const kGDataCategoryPDFDoc            _INITIALIZE_AS(@"http://schemas.google.com/docs/2007#pdf");
_EXTERN NSString* const kGDataCategoryPresentationDoc   _INITIALIZE_AS(@"http://schemas.google.com/docs/2007#presentation");
_EXTERN NSString* const kGDataCategorySpreadsheetDoc    _INITIALIZE_AS(@"http://schemas.google.com/docs/2007#spreadsheet");
_EXTERN NSString* const kGDataCategoryStandardDoc       _INITIALIZE_AS(@"http://schemas.google.com/docs/2007#document");

以下に、判定処理の例を示します。
    GDataEntryDocBase *document; // ドキュメントエントリデータ
    NSString *docKindTerm = @"unknown";

    // カテゴリ情報の配列の先頭に、ドキュメント種類が設定されている。
    NSArray *categories = [GDataCategory categoriesWithScheme:kGDataCategoryScheme fromCategories:[document categories]];
    if ([categories count] >= 1) {
        docKindTerm = [[categories objectAtIndex:0] term];

    }
    if([kGDataCategoryFolderDoc isEqualToString:docKindTerm]) {
        // フォルダに固有な処理

    } else if([kGDataCategorySpreadsheetDoc isEqualToString:docKindTerm]) {
        // スプレッドシートに固有な処理
        
    } else {
       // 上記以外のドキュメントに対する処理
        
    }


ドキュメントデータのダウンロード

ドキュメントエントリデータには、それを一意に識別するためのresourceIDが付与されています。ダウンロードは、HTTP GETリクエストにて行われますが、そのときに指定するURLの中に、resourceIDを含めることによって、目的のドキュメントが識別されます。
尚、このURLは、ドキュメントの一覧を取得時に、GDataEntryDocBaseオブジェクトに設定されるため、アプリケーションでは意識する必要はありません。
以下に、同期型の処理で、ドキュメントをダウンロードする例を示します。

    GDataEntryDocBase *targetDoc = ...; // ドキュメントエントリデータ
 
    // ドキュメントのタイトルを、保存するファイル名として利用
    NSString *fileName = [[targetDoc title] stringValue];
    NSString *savePath = [NSTemporaryDirectory() stringByAppendingString:fileName];

    // ドキュメントデータのURIを取得
    NSString *sourceURI = [[targetDoc content] sourceURI];
    NSURL *url = [NSURL URLWithString:sourceURI];
    if (url) {
        // 同期型でダウンロードする場合の例です。
        // iPhoneSDK標準のHTTP通信のAPIを使用します。
       
        // サービスオブジェクトから、リクエストを生成する。
        GDataServiceGoogle *service = ...];
        NSURLRequest *request = [service requestForURL:url
                                                  ETag:nil
                                            httpMethod:nil];
        NSURLResponse *response = nil;
        NSError *error = nil;
        // NSURLConnectionの同期通信リクエストを実行する。
        NSData *data = [NSURLConnection sendSynchronousRequest:request
                                             returningResponse:&response
                                                         error:&error];

        if (error != nil) {
            // ダウンロード処理のエラーハンドリング例
            NSLog(@"Error retrieving file: %@", error);
            UIAlertView *alertView = [[UIAlertView alloc]
                                      initWithTitle:[error localizedDescription] message:[[error userInfo] description] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alertView show];
            [alertView release];
           
        } else {
            // ダウンロードしたファイルの保存
            BOOL didWrite = [data writeToFile:savePath
                                      options:NSAtomicWrite
                                        error:&error];
            if (!didWrite) {
                // ファイル保存処理のエラーハンドリング例
                NSLog(@"Error saving file: %@", error);
                UIAlertView *alertView = [[UIAlertView alloc]
                                          initWithTitle:[error localizedDescription] message:[[error userInfo] description] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
                [alertView show];
                [alertView release];
           }
        }
    }

これで、目的のドキュメントをダウンロードして、ローカルのファイルとして保存することができますが、デフォルトでは、PDF以外のドキュメントは、HTMLでエクスポートされます。そのままでは扱いにくいので、Export for Google Documentsアプリケーションでは、MS Officeのドキュメントフォーマットでエクスポートするオプションを使用しています。そのためには、ドキュメントのURLに、エクスポートするフォーマットを指定するパラメタ(exportFormat)を追加します。

詳細は、以下のドキュメントを参照してください。
Developer's Guide: The Protocol - Google Documents List Data API v3.0 - Google Code

ここまで、4回に分けて、Google Documentsサービスからドキュメントデータをダウンロードするプログラムを書くための、基本的な手順を説明してきました。Google Documentsを利用するアプリケーションを作る時にご参考になれば幸いです。

すべてをまとめて読みたい場合は、こちらにアクセスしてください。





MapKitが提供するMKAnnotationやMKPinAnnotationViewを使って、MKMapView上にアノテーションを追加することができます。

ポイントは、以下の通りです。
  • MKAnnotationプロトコルを実装したインタフェースを定義する。
  • MKPinAnnotationViewを継承したインタフェースを実装する。
  • MKMapViewDelegate の mapView:viewForAnnotation: で、MKPinAnnotationViewを継承したインスタンスを生成して返却する。
  • MKAnnotationプロトコルを実装したインスタンスを生成して、MKMapView上に追加する。

以下に、実装例を示します。

-- MyAnnotation.h --

-- MyAnnotation.m --
 
-- MyPinAnnotationView.h --

-- MyPinAnnotationView.m --
 
-- MyViewController.h --

-- MyViewController.m --

GPSを使って取得した緯度経度に該当する住所の情報を取得したい場合には、MapKitが提供しているMKReverseGeocorderを使うと便利です。

MKReverseGeocorderを使う時のポイントは、以下の通りです。
  • MKReverseGeocoderのインスタンスを作成し、delegateを設定。delegateには、MKReverseGeocoderDelegateプロトコルを実装しているオブジェクトを設定する。
  • MKReverseGeocoderのstartを呼び出すことで、プレースマークの取得処理が始まる。(結果は非同期で返される)
  • プレースマークが取得できた場合には、MKReverseGeocoderDelegate の reverseGeocoder:didFindPlacemark: が呼び出される。
  • プレースマークが取得できなかった場合には、MKReverseGeocoderDelegate の reverseGeocoder:didFailWithError: が呼び出される。

以下に、実装例を示します。
以下は、GPSからの位置情報を取得した後に、MKReverseGeocoderを使ってプレースマークを取得する場合の実装例です。

-- MyViewController.h --

-- MyViewController.m --

Our First applications are released in AppStore

| 1 Comment | 0 TrackBacks
弊社iPhone Lab.チームで開発した、最初の2つのiPhoneアプリケーションが、本日AppStoreからリリースされました。

Export for Google Documents
Location Clip

無料でダウンロードできますので、ぜひ、お試しいただければと思います。
このブログでは、これらのアプリケーションで使用している技術トピックも公開しています。技術に興味をお持ちの方は、あわせて読んでいただければと思います。

よろしくお願い致します。

iPhone Applications

Twitter