Recently in Export for Google Documents Category

iPhone OSにおいて、アプリケーション間でデータを共有する、最も簡単な方法は、ペーストボードを使用することです。

典型的なパターンをあげてみましょう。
ユーザがメモアプリケーションで文字列を選んで「コピー」の操作をし、メール送信画面で「ペースト」操作を行うと、その文字列がメールに貼り付けられます。これは、コピー操作で、メモアプリケーションが文字列をペーストボードに格納し、メールアプリケーションが、ペースト操作の時にそこから文字列を取り出すことで実現されています。それと同じ方法で、どんなアプリケーションでも、ペーストボードを介してデータを受け渡すことが可能です。

ペーストボードには、文字列だけでなく、さまざまな種類のデータを格納することができます。例えば、弊社のExport for Google Documentsというアプリケーションでは、Googleドキュメントからエクスポートしたドキュメントデータを、ペーストボードに格納する機能を持っています。

ここでは、どのような形でペーストボードにデータを格納すればいいのか及び、弊社製Copy & Sendアプリでそのデータを活用する例について簡単に説明したいと思います。

UIPasteboardクラス

iPhone SDKの中では、UIPasteboardクラスがペーストボードを表現するオブジェクトになります。システム内には、複数のペーストボードが存在していますが、それぞれが、UIPasteboardのインスタンスに対応します。

システム標準で用意されているものには、以下の2種類があります。
  • General pasteboard
    • システム標準のペーストボードであり、通常のコピー/ペースト操作で使用されます。
  • Find pasteboard
    • 検索バーに入力されたテキストが保存されるペーストボード

上記以外に、各アプリケーションで固有なものを、自由に作成することができます。標準のペーストボードは、予期しない場面で勝手に上書きされてしまうことがあるので、アプリケーション固有のデータは、固有のペーストボードを使用することをお奨めします。

また、各ペーストボードには、一意に識別するための名称が付与されており、名称が不明なペーストボードにはアクセスできないようになっています。

ペーストボード内のデータ構造

ペーストボード内のデータは、アイテムと呼ばれるNSDictionryの集合として管理されています。
アイテムのNSDictionryのキーは、データの種類を表すUTI(Uniform Type Identifier)と呼ばれる文字列であり、値としてデータのオブジェクトが格納されています。したがって、アイテムの中には、異なる種類のデータを複数格納することができます。
以下に、データ構造の概念図を示します。

Pasteboard_items.png

これは、少し複雑な組合せの例になっています。
1つ目のアイテムは、URLとテキストのペアで構成されています。例えば、Safariでハイパーリンクを長押ししてコピーした場合は、この形になります。
2つ目のアイテムは、Excelのスプレッドシートを、単独で格納したアイテムの例です。
3つ目のアイテムは、JPEG画像とテキストのペアで構成されています。カメラロールの写真をコピーした場合には、この形になります。

Copy & Send及び、Copy & Send Liteで、ペーストボードの内容をブラウズすると、これらのデータ構造を確認することができます。興味がある方は、お試しください。

UIPasteboardのAPIについて

アイテムを操作するためのAPIは、以下の種類に分かれます。
(詳細は、UIPasteboardのリファレンスを参照してください)

  • 標準的な単一タイプのデータを扱うためのもの
    • データにアクセスするためのプロパティとして定義されています。
      • string/strings
      • image/images
      • URL/URLs
      • color/colors
  • 任意のデータタイプを扱うためのもの
    • 上記以外に、UTIを明示的に指定してデータを操作するメソッドが用意されています。

ペーストボードの活用例

一部、冒頭で述べたことの繰り返しになりますが、弊社製の以下のアプリ間で、ペーストボードを使ったデータ連携を実現しています。
  • Export for Google Documents
    • Googleドキュメントからエクスポートしたドキュメントデータを、ペーストボードに格納する。
  • Copy & Send / Copy & Send Lite
    • ペーストボードに格納されているアイテムを活用する機能を実装している。
  • 他のデバイスへの送信
  • 永続領域への保存
  • 内容のブラウズ
これによって、Export for Google Documentsのドキュメントデータを、他のデバイスに送信するといったことができるようになっています。


みなさんが作成したアプリケーションでも、Copy & Send / Copy & Send Liteを有効に活用していただければ幸いです。

開発者の方のために、具体的な連携機能の実装方法について、アプリの中からアクセスできるヘルプドキュメントにて説明しています。よろしければ、そちらをご参照いただければと思います。

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



12/18にアップデートを申請していたExport for Google Documentsのアップデートが、Ready for Saleになりました。6日間というのは、これまでで最短記録です。

Export for Google Documents (AppStore)

今回は、主に2つの機能追加が中心となっています。

Copy & Sendアプリケーションとの連携

これまでも、ドキュメントをペーストボードに格納する機能を提供していましたが、そのデータを活用できるアプリケーションが存在していなかったので、中途半端な状態でした。
同じデバイスの中に、Copy & Sendがインストールされていれば、このアプリでペーストボードに格納したドキュメントを利用することができます。

06_PasteBoard.png

ペーストボード状態表示画面で、「Copy & Sendを起動する」ボタンをタップすると、Copy & Sendが起動されます。あとは、Copy & Sendの機能を使って、ドキュメントを別のデバイスに送信したり、永続領域に保存するなどできるようになります。

Copy & Send (有料版) (AppStore)

Copy & Send (無料版) (AppStore)

スプレッドシートからワークシートを選択する

スプレッドシートをPDFとしてエクスポートする場合、ワークシートを選択することができるようになりました。

02_ChooseSheet.png


通常の流れですと、本日中にAppStoreにも出てくるはずですが、米国がクリスマス休暇に入っているため、スムーズに行かない可能性もあります。その場合は、ご了承ください。






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変換を使用するか否かを、適宜選択していただければと思います。
将来のバージョンで、柔軟に変換フォーマットを指定できるパラメタが追加されることがあれば、対応を考えたいと思います。
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を利用するアプリケーションを作る時にご参考になれば幸いです。

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





Our First applications are released in AppStore

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

Export for Google Documents
Location Clip

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

よろしくお願い致します。
Google Documentsにあるドキュメントデータに、iPhoneアプリケーションからアクセスするには、Google Data APIs Objective-C Client Libraryを使用するのが便利であることを、これまでに説明してきました。

Google Data APIのObjective-Cクライアントを動かしてみる
iPhoneアプリケーションに、Google Data APIクライアントを組込む

前回までは、準備作業のみでしたが、今回は、具体的なプログラミングについて、見ていきたいと思います。とりあえず、ファーストステップとして、Google Documentsから、ドキュメントの一覧を取得する処理を例に説明します。

サービスオブジェクトの生成

このクライアントライブラリでは、すべてのリクエストのハンドリングを、「サービスオブジェクト」と呼ばれるオブジェクトを介して行います。まずは、そのオブジェクトを生成して、通信するための準備をする必要があります。
以下に、サービスオブジェクトを生成するためのコーディング例を示します。
/**
 * サービスオブジェクトを生成します。
 * @param username ユーザ名
 * @param password パスワード
 * @return サービスオブジェクト
 */
- (GDataServiceGoogleDocs *)docsServiceWithUserName:(NSString *)username password:(NSString *)password {
    
    // サービスオブジェクトの宣言
    // インスタンスは再利用できるよう、キャッシュしておきます。
    static GDataServiceGoogleDocs *service = nil;
    
    if (!service) {
        // 初回のみ、インスタンスを生成して、必要な初期設定を行います。
        service = [[GDataServiceGoogleDocs alloc] init];
        
        [service setUserAgent:@"MyCompany-SampleDocsApp-1.0"]; // 自分のアプリに固有な名称
        [service setShouldCacheDatedData:YES];
        [service setServiceShouldFollowNextLinks:YES];
    }
    
    if ([username length] && [password length]) {
      // ユーザ名/パスワードを設定します。
     [service setUserCredentialsWithUsername:username
                                       password:password];
    } else {
        [service setUserCredentialsWithUsername:nil
                                       password:nil];
    }
    
    return service;
}


前回のエントリで、クライアントライブラリを入手して、サンプルアプリケーションをビルド/実行するまでの手順を説明しました。

Google Data APIのObjective-Cクライアントを動かしてみる

今回は、クライアントライブラリを、実際にiPhoneアプリケーションから利用するための手順について、説明したいと思います。
(すでに、クライアントライブラリのプロジェクトを入手済みであることを前提とします)

手順は、以下のドキュメントでも説明されています。

GDataObjCIntroduction - gdata-objectivec-client - Introduction for Objective-C Developers - Project Hosting on Google Code

具体的な操作イメージがしにくいところがあるので、以下に、補足説明します。

クライアントライブラリのソースへのリンクを張る

クライアントライブラリのプロジェクト(GData.xcodeproj)と、自分のアプリケーションのプロジェクトを、Xcodeで開きます。そこで、クライアントライブラリのソースをドラッグ/ドロップで、自分のアプリケーションプロジェクトに取り込みます。

GDataSrcLink.png
このときに、コピーではなく、「リンク」を選択してください。

ビルドオプションを設定する

メニューの、プロジェクト --> プロジェクト設定を編集で、プロジェクト情報編集パネルを開き、「ビルド」タブを選択します。そこで、以下の通り設定します。

Xcode_prj_setting1.png

Xcode_prj_setting2.png

この状態で、プロジェクトをビルドし、エラーが出なければ、組込みは成功です。
次回は、実際のコーディングイメージについて、説明したいと思います。


現在、Appleに申請中の、Export for Google Documentsというアプリケーションでは、Google Data APIを使用して、Google Documentsサービスに置かれているドキュメントアクセスしています。
Google Data APIのサイトで、APIの詳しい説明がされていますが、iPhoneアプリケーション開発に特化した内容は、あまり多くありませんので、開発作業の中で得たノウハウを、何度かに分けて紹介したいと思います。

Google Data APIには、さまざまなプログラミング言語のための、クライアントライブラリが、サンプルとともに提供されているので、各プロトコルの詳細を完全に理解しなくても、開発することができます。iPhoneアプリケーション開発の場合は、当然のことながら、Google Data APIs Objective-C Client Libraryを使用します。今回はそのライブラリを入手して、サンプルを起動するまでを説明したいと思います。
プロトコルやAPIの詳細な説明は、Google Data APIのサイトを参照してください。

注: 各サンプルは、MacOSXで実行するためのアプリケーションになっており、iPhoneでそのまま実行可能なサンプルは、提供されていません。


API概要

Google Data APIは、Googleが提供する各種WebサービスにアクセスするためのAPI群の総称であるとともに、各APIに共通の基本的なプロトコルの定義です。

Google Documentsの機能を利用するには、その中の、以下のAPIを使用します。
スプレッドシートだけは、他の種類のドキュメントと、扱い方が異なるため、別のAPIになっています。


iPhone Applications

Copy & Send

  • ダウンロード終了しました

Copy & Send Lite

  • ダウンロード終了しました

Location Clip

  • ダウンロード終了しました

Export for Google Documents

  • ダウンロード終了しました