2011年10月12日水曜日

GData Objective-C Client を XCode 4 に追加する

iPhoneプロジェクトにライブラリを追加する
1.
libGDataTouchStaticLib.a を project target -> Build Phases -> Link Binary With Libraries で追加する。




2.
必要に応じて以下のライブラリも追加する。*1
Security.framework
SystemConfiguration.framework

3.
project target -> Build Settings -> Linking -> Other Linker Flags に 以下の3つのフラグを追加する。
-ObjC
-lxml2
-all_load




4.
project target -> Build Settings -> Search Paths -> Header Search Pathsに、次の2つのパスを追加する。
/usr/include/libxml2
$(SRCROOT)/gdataClient/Source/build/Release-$(PLATFORM_NAME)/Headers




5.
適当なファイルに #import "GData.h" を追加してビルドが通れば完了。

*1
BuildingTheLibrary Adding the Google Data API Objective-C Client Library to a Project によると、OAuth 2 を利用する場合必要らしい。
BuildingTheLibrary Adding the Google Data API Objective-C Client Library to a Project

2011年5月26日木曜日

アルバムに保存されている写真データを取得する 2

ALAssetsGroup から ALAsset を取得する

メソッド:*1
Tasks → Enumerating Assets
- enumerateAssetsUsingBlock:

→ パラメータに group の asset を取得する処理を block で記述する。

    ALAssetsGroupEnumerationResultsBlock assetsEnumerationBlock = ^(ALAsset *result, NSUInteger index, BOOL *stop)
    {
        if (result) {
        // asset の取得に成功した場合
            [assets addObject:result];
        }
    };

    [assetsGroup enumerateAssetsUsingBlock:assetsEnumerationBlock];

--------------------

asset を取得する際にフィルタリングができる*2

メソッド:
Tasks → Filtering
- setAssetsFilter:

設定できるフィルタは以下の3種類
allAssets
allPhotos
allVideos

    // 写真を取得するフィルタを設定する
    ALAssetsFilter *onlyPhotosFilter = [ALAssetsFilter allPhotos];
    [assetsGroup setAssetsFilter:onlyPhotosFilter];
    // ALAssetsGroup から ALAsset を取得するメソッドを呼び出す
    [assetsGroup enumerateAssetsUsingBlock:assetsEnumerationBlock];

参照:
*1
ALAssetsGroup Class Reference
*2
ALAssetsFilter Class Reference

wwwdc2010 Session421/iOS/MyImagePicker/

2011年5月21日土曜日

アルバムに保存されている写真データを取得する 1

ALAssetsLibrary から ALAssetsGroup を取得する

メソッド:*1
Enumerating Assets
- enumerateGroupsWithTypes:usingBlock:failureBlock:

→ Aseets group を Type of Asset から指定する。
→ usingBlock: パラメータに assets group を取得する処理を block で記述する。
→ failureBlock: データのアクセスに失敗したときの処理を blocks で記述する。
-----------------------

サンプルソース*2
NSUInteger groupTypes = ALAssetsGroupAlbum | ALAssetsGroupEvent | ALAssetsGroupFaces;
[assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:listGroupBlock failureBlock:failureBlock];
サンプルでは group type の絞り込みを行っているが、現時点(2011.05)時点では「ALAssetsGroupAll」を指定しないと取得ができない。

usingBlock:listGroupBlock の実装は次のとおり。
ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) {
        
    if (group) {
        // group を配列に格納する
        [groups addObject:group];
    } else {
        // group を 数え終わったあとの処理を行う ex) データの表示
        [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
    }
};


参照:
*1
ALAssetsLibrary Class Reference
*2
wwwdc2010 Session421/iOS/MyImagePicker/

2011年5月16日月曜日

Assets Library Framework

Assets Library Framework
写真アプリから写真や動画にアクセスするためのフレームワーク

主なクラス
ALAsset
ALAssetRepresentation
ALAssetsFilter
ALAssetsGroup
ALAssetsLibrary

以下の英文は、ライブラリのヘッダファイルに書いてあるのを転載した。

ALAssetsLibrary.h
This class represents the set of all videos and photos that are under the control of the Photos application.
This includes those that are in the saved photos album and those coming from iTunes.
It is used to retrieve the list of all asset groups and to save images and videos into the Saved Photos album.
memo:
アルバムやiTunes に保存されているデータを持っている
asset group のデータやアルバムに保存さている写真や動画を読み出せる
-------------

ALAssetsGroup.h
An ALAssetsGroup is a ordered set of assets.
The order of its elements is the order that the user sees in the Photos application.
Groups are synced via iTunes, created to hold the users saved photos, or created during camera import.
None of the groups can be directly modified using this API. Only the saved photos group can be indirectly modified
by saving images or videos using the ALAssetsLibrary class.
memo:
ALAssetsGroup は、assets の順序集合(ordered set)である
そのひとつひとつの要素は、アプリ(例えば写真アルバムアプリのアルバムのこと?)から見える情報の単位
このAPI からデータをいいじることはできない。出来るのは ALAssetsLibrary class
-------------

ALAssetsFilter.h
This class encapsulates filtering criteria to be used when retrieving assets from a group.
memo:
assets group をフィルタリングする
すべての assets とか、写真だけとか、動画だけとか
-------------

ALAsset.h
An ALAsset represents a photo or a video managed by the Photos application.
Assets can have multiple representations, like a photo which has been shot in RAW and JPG.
Furthermore, representations of the same asset may have different dimensions.
memo:
ALAsset とは、アプリが扱うひとつひとつの写真、動画を表す
asset は、複数の represention を扱うことができる。例えば、ひとつの写真の RAW*1 と JPG
同じ asset の 表現(represention::RAW とか JPG などの画像データのこと?) が異なる特徴(dimensions)をもつこともある
-------------

ALAssetRepresentation.h
An ALAssetRepresentation encapsulates one of the representations of a given ALAsset.
For example: in the case of a camera shooting RAW + JPEG, the resulting asset will have two representations,
one for the RAW file and one for the JPEG file.
memo:
ALAsset から得られるひとつの representation を含む
RAW と JPG のふたつのデータを持つ画像の場合、asset はふたつの representation をもつ
-------------

*1
RAW画像(ローがぞう)は、デジタルカメラなどにおける完成状態にされていない画像データのこと

参考:
Assets Library Framework Reference

2011年4月9日土曜日

アルバム一覧をサムネイル画像で表示したい

-やりたいこと
Picasaアルバムのように、アルバム一覧をサムネイル画像で表示したい

-利用したライブラリ
Three20 1.0.4

Three20 の TTThumbsViewController を使えば、写真一覧をサムネイルで表示→任意の写真をクリック→写真を表示する は、簡単に実装できる。しかし、ここでは、「写真一覧」の前に、Picasaアルバム のようなアルバム一覧のサムネイルを表示したい。

-実装したい処理の手順
--before--
1
写真一覧をサムネイルで表示
2
任意の写真をクリック
3
写真の表示

--after--
1
アルバム一覧をサムネイルで表示

2
選択したアルバムが持つ写真をサムネイルで一覧表示
3
任意の写真をクリック
4
写真の表示

-------------------------------------
-Three20UI.xcodeproj でどんな実装をしているのか確認する

--任意の写真を選択したあとに呼び出されるメソッド
---メソッド名
- (void)thumbsTableViewCell:(TTThumbsTableViewCell*)cell didSelectPhoto:(id)photo;
---定義ファイル名
TTThumbsTableViewCellDelegate.h

--上記の関数を実装しているファイル名
TTThumbsViewController.m

- (void)thumbsTableViewCell:didSelectPhoto: メソッドはデリゲートメソッドなので、自分のメソッド内でこのメソッドをデリゲートすればいいのかなと考えたが、次の処理(写真一覧をサムネイルで表示する)では Three20 に処理を任せるので、superクラス(TTThumbsViewController)の処理も残しておきたい。というわけで、オーバーライドするのが正解。
-------------------------------------
-実装例

MyViewController.m
- (void)picasaWebDataSourceFetchAlbumCompleted:(PhotoSet *)dataSource{

 MyThumbsViewController *thumbs = [[MyThumbsViewController alloc] initForPhotoSource:dataSource 
                withPicasaWebDataSource:self.picasaDataSource];

 [self.navigationController pushViewController:thumbs animated:YES]; // この後、Three20 の処理に移る
}


MyThumbsViewController.m
- (void)thumbsTableViewCell:(TTThumbsTableViewCell*)cell didSelectPhoto:(id)photo {
 // 自分のメソッド内で thumbsTableViewCell:didSelectPhoto: をオーバーライドして処理を Three20 から自分の実装に処理を戻す
 
 NSInteger index = photo.index; // 選択したアルバムのインデックスを取得しておく
 [self.picasaDataSource fetchSelectedAlbum:index]; // Picasa Web Albums Data API の fetch 処理を呼び出す
}

この後、TTThumbsViewController で初期化したオブジェクトを pushViewController: メソッドの引数に設定する。そして、選択したアルバムがもつ写真一覧をサムネイルで表示する処理を Three20 でやってもらう

MyThumbsViewController.m
- (void)picasaWebDataSourceFetchAlbumPhotosCompleted:(PhotoSet *)dataSource{
 TTThumbsViewController *thumbs = [[TTThumbsViewController alloc] init];
 thumbs.photoSource = dataSource;
 
 [self.navigationController pushViewController:thumbs animated:YES];
 
}

2011年3月10日木曜日

インスタンス変数へのアクセス

appleのサンプルで使用される構造体ポインタ演算子( または、アロー演算子: -> )についてのメモ。

プロパティへのアクセス方法
ドット構文を使うと、構造体の要素にアクセスするときと同じパターンを使ってプロパティにアクセスできます。*1

ドット構文は単なる「シンタックスシュガー」であり、コンパイラによってアクセサメソッドの呼び出しに変換されます(そのため実際にはインスタンス変数に直接的にアクセスするわけではありません)。*1

以下のような理解でいいのか?
- プロパティには直接アクセス出来ない。
- しかし、構造体ポインタ演算子(->)を使うと、アクセサメソッドを経由しないで直接インスタンス変数にアクセスすることが出来る。

インスタンス変数がレシーバでないオブジェクトに属する場合は、オブジェクトの型を静的な型定義によってコンパイラに明示しなければなりません。静的に型定義したオブジェクトのインスタンス変数を参照するには、構造体ポインタ演算子(->)を使用します。*2

参照:
*1
objective-c 2.0 プログラミング言語 -> プロパティ -> 概要 -> プロパティへのアクセス
*2
objective-c 2.0 プログラミング言語 -> クラスの定義 -> クラス実装 -> インスタンス変数の有効範囲

2011年2月28日月曜日

ユニットテストフレームワークを使う

OCMock のサイト

プロジェクトへの追加方法
stackoverflow / OCMock for iPhone (iOS4, XCode 3.2.3)

ただし、以下のように文字だけで説明している。
Delete ocmock.framework, the copy file phase, and any search path linking to ocmock header.

check out the latest version from ocmock svn repo : http://svn.mulle-kybernetik.com/OCMock/trunk

ダウンロード元は、svn の他に OCMock のサイト にも .dmg ファイルのダウンロードリンクがある。

Build the OCMockPhoneSim target

1.
ダウンロードしたフォルダ内にある OCMock.xcodeproj を開く。

2.
画像のように概要を設定する。




Copy the libOCMock.a and Headers folder in your project folder
OCMock プロジェクトフォルダ内の、 build -> Release-iphonesimulator フォルダの中身(Headers フォルダとlibOCMock.a)を自分のプロジェクトへコピーする。

add the libOCMock.a to your framework and add a link to the headers folder in your target library search path.
1.
プロジェクトへ追加する。
グループとファイル -> Frameworks を右クリック
Frameworks -> 追加 -> 既存のフレームワーク -> (その他を追加 ボタンを押下) 先ほどビルドした libOCMock.a を追加する。

2.
ヘッダ検索パスと他のリンカフラグを設定する。
グループとファイル -> (新しく追加したテスト)ターゲット -> (Unit Test Bundle)名 -> 情報を見る をクリックする。

3.
ヘッダ検索パスは、Headersフォルダへのパスを設定する。
ex) $(SRCROOT)/OCMock/Headers

リンカフラグ は次を設定する。
-all_load

---------
xcode のセットアップはapple のユニットテストのページ等を参考にするみたい。
Unit Testing Applications

2011年2月24日木曜日

アルバムの一覧をサムネイルで表示する

Contains the URL of a thumbnail of a photo or album cover.

<media:thumbnail> エレメントにあるURLを利用してアルバムを一覧表示できる。

参照:
Picasa Web Albums elements reference -> Media RSS (media namespace) element reference -> media:thumbnail

GDataObject の基本

GDataObject についての説明を picasa の場合で考えてみる。
Servers respond to client GData requests with feeds that include lists of entries.

Each feed and entry is composed of elements. Elements represent either standard Atom XML elements, or custom-defined GData elements.

Feeds, entries, and elements are derived from GDataObject, the base class that implements XML parsing and generation.

おおよそのイメージはこんな感じなのだろうか。



参照:
gdata-objectivec-client -> Wiki -> GDataObjeCIntroduction -> Google Data APIs Basics

2011年2月2日水曜日

オブジェクトの所有権の取得 retain

受け取ったオブジェクトを破棄したくない場合もあります。たとえば、インスタンス変数にオブジェクトをキャッシュする必要がある場合です。
このような場合は、オブジェクトが不要かどうかを知っているのは自分だけであるため使用中にオブジェクトが破棄されないことを保証する機能が必要となります。これは、retainメッセージを使って行います。

 – (void)setMainSprocket:(Sprocket *)newSprocket {
 if (mainSprocket != newSprocket) { // 古いインスタンス変数を確実に解放するための判定を行う
 [mainSprocket release];
 mainSprocket = [newSprocket retain]; // 参照カウンタが1増える
    }
 }

---------------
参照
Cocoaメモリ管理プログラミングガイド オブジェクトの所有権の取得

2011年1月15日土曜日

ファイルを素早く開く(定義、実装にジャンプする)

ファイルを素早く開く(定義、実装にジャンプする)ショートカット
⌘ + shift + d

2011年1月7日金曜日

キーボードをしまう

キーボードをしまうには、現在ファーストレスポンダになっているテキストベースビューのresignFirstResponderメソッドを呼び出します。
Text Viewがファーストレスポンダの状態でなくなると、現在の編集セッションは終了し、そのことがデリゲートに通知されます。
そして、キーボードが消えます。つまり、myTextFieldという変数が、現在ファーストレスポンダになっているUITextFieldオブジェクトを指す場合、キーボードをしまうには以下のコードを実行するだけです。
[myTextField resignFirstResponder];
---------------------------------
以下のような状態の場合、












「LogIn」ボタンを押下した時、キーボードが隠れるようにするためにはログインアクション実行後、テキストフィールド(この場合は、ID と PASSWARD を入力するフィールド)のresignFirstResponderメソッドを呼び出す。

参照:
iPhone アプリケーションプログラミングガイド テキストとWeb->キーボードの管理->キーボードをしまう

2010年12月23日木曜日

three20 をプロジェクトに追加する

1.
プロジェクトフォルダ内に three20 フォルダを置く

2.
スクリプト実行

python ./src/scripts/ttmodule.py -p (プロジェクトフォルダへのパス)/(プロジェクト名).xcodeproj -c Debug -c Release Three20

python ./src/scripts/ttmodule.py -p (プロジェクトフォルダへのパス)/(プロジェクト名).xcodeproj Three20 // " -c Debug -c Release " オプションを付けると、他のライブラリを追加したときにリンクエラーが出るので使用をやめた

3.
ヘッダ検索パスに追加
(three20 フォルダへのパス)/three20/Build/Products/three20

4.
他のリンカフラグに、 -all_load を追加する(私の場合、すでに -ObjC -lxml2 が追加されているのでこれで3つ追加されていることになる)。
---------------------
git のthree20 のページを参照する。
色々説明がかいてあるので。

three20 gitページ
↑ページにヘルプを見ろと書いてる
python ./src/scripts/ttmodule.py -h

ヘルプに以下のような記述
Add the Three20 project settings to the Debug and Release configurations.
  This includes adding the header search path and linker flags.
  > ttmodule.py -p path/to/myApp.xcodeproj -c Debug -c Release
→ヘッダ検索パスとリンカフラグを追加すると書いてある

2010年12月2日木曜日

GDA のクラス関係

Google Data APIs Objective-c Client Library (GDA) の、picasa 関連のクラス関係図をxcode で一部可視化してみる。






GDataFeedPhotoBase と GDataEntryPhotoBase のスーパークラスは共に、GDataObject クラスである。

--------
xcode でクラス図を作成する。
設計 -> クラスモデル -> クイックモデル

2010年12月1日水曜日

UIImage でURL の画像を表示する。

  NSString *path = @"http://*******/************/**.jpg"; // URL
NSURL* url = [NSURL URLWithString:path];
NSData* data = [NSData dataWithContentsOfURL:url];
photo = [[UIImageView alloc] initWithImage:[[UIImage alloc] initWithData:data]];
[self.view photo];

2010年11月15日月曜日

プロパティに関するコーディングルール

Google Objective-c スタイルガイド 日本語訳 の、プロパティについて以下を参考にする。

文字列には copy を使うこと
NSStringプロパティには、必ず copy 属性を宣言するべきです。

これは論理的には、NSString のセッタには必ず、retain の代わりに copy を使わなければならない、というルールに従ったものです。

アトミック性
プロパティにはオーバーヘッドがあることを認識しておいてください。デフォルトでは、同期のセッタとゲッタはすべてアトミックになります。そのため、セットとゲットの呼び出しには同期オーバーヘッドがかなりあります。アトミック性が必要ないなら、プロパティを nonatomic と宣言しておいてください。

Delegate パターンについても以下を参考にする。
Delegate パターン
Delegate オブジェクトを retain するべきではない。

<-- 追記 -->
命名規則
プロパティに対応するインスタンス変数名は、アンダースコア(_)で終わらなければなりません。プロパティ名は、対応するインスタンス変数名から最後のアンダースコア(_)を取り除いたものにするべきです。

@interface MyClass : NSObject {
@private
NSString *name_;
}
@property(copy, nonatomic) NSString *name;
@end

@implementation MyClass
@synthesize name = name_; // インスタンス名を隠蔽できる。
@end
// ------------------------------------
NSLog("%@", self.name);

-(void) dealloc{
self.name = nil;
[super dealloc];
}

参考
Google Objective-c スタイルガイド 日本語訳

2010年11月13日土曜日

プロパティ

目的*1
■ プロパティ宣言により、アクセサメソッドの動作方法の明瞭で明示的な仕様を指定できます。
■ コンパイラは、宣言で指定された仕様に従ってアクセサメソッドを合成できます。これは、コードの記述と保守が少量で済むことを意味します。
■ プロパティは構文上は識別子として表現され、範囲付きであるため、コンパイラは宣言されていないプロパティの使用を検出できます。
■ あるクラスによって宣言されたプロパティの実行時のイントロスペクション。
-----------------------------------

イントロスペクション(リフレクション)*2
通常、プログラムのソースコードがコンパイルされると、プログラムの構造などの情報は低レベルコード(アセンブリ言語など)に変換される過程で失われてしまう。リフレクションをサポートする場合、そのような情報は生成されるコードの中にメタデータとして保存される。

宣言属性
iPhone 開発で主に使用される属性をまとめた。
プロパティ属性 説明
assign setterで単純代入を使用することを指定する
retain 代入時にオブジェクトに対してretain を呼び出す必要があることを指定する
copy 代入にオブジェクトのコピーを使用することを指定する
nonatomic 合成されるアクセサが非アトミックになるように指定する

retain*3
クライアントオブジェクト側において、プログラム上の有効範囲を超えた後も受け取ったオブジェクトを保持する必要がある場合は、受け取ったオブジェクトを保持できます。それには、retainメッセージを送信します。

nonatomic*4
nonatomic属性の影響は環境によって異なります。デフォルトでは、合成されるアクセサはすべてアトミックです。マネージドメモリ環境では、アトミックな動作を保証するにはロックを使用する必要があります。また、返されるオブジェクトは保持され自動解放されます。このようなアクセサが頻繁に呼び出されると、アトミックな動作はパフォーマンスに重大な影響をもたらすことがあります。ガベージコレクトされる環境では、ほとんどの合成メソッドはこうしたオーバーヘッドなし
でアトミックになります。
アトミックな実装の目的は堅牢なアクセサを提供することであり、コードの正確性を保証することではないことを理解することが重要です。「アトミック」とは、プロパティへのアクセスがスレッドセーフであるという意味ですが、単にクラス内のすべてのプロパティをアトミックにするだけでそのクラス(一般にはオブジェクトグラフ)が「スレッドセーフ」になるということではありません。スレッドの安全性を個々のアクセサメソッドのレベルで表現することはできません。

参照

*1
Objective-C 2.0 プログラミング言語

*2
イントロスペクション(リフレクション)

*3
Cocoa Fundamentals Guide / cocoaオブジェクトのライフサイクル

*4
objective-c 2.0 プログラミング言語 / パフォーマンスとスレッド

2010年11月12日金曜日

参照カウンタ

objective-c のメモリ管理方法。
基本原則
「alloc」または「new」で始まる名前のメソッドや、「copy」を含む名前のメソッド(たとえば、alloc、newObject、mutableCopy)を使用してオブジェクトを作成した場合、またはオブジェクトにretainメッセージを送信した場合は、そのオブジェクトの所有権を取得できます。
その場合は、releaseまたはautoreleaseを使用してオブジェクトの所有権を放棄する責任が
あります。それ以外の方法でオブジェクトを受け取った場合は、そのオブジェクトを解放してはなりません。

メッセージ 保持カウント
alloc 1にする
copy 1にする
new 1にする
retain 1つ増える
release 1つ減る
autorelease 1つ減る(ただし、任意のタイミング)


参考
Cocoaメモリ管理プログラミングガイド

2010年11月10日水曜日

戻る/進む(unDo/reDo)

戻る/進む を行うショートカット

戻る
⌘ + option + ←

進む
⌘ + option + →

2010年11月9日火曜日

Dropbox に gitレポジトリを作成する

1.
Dropbox フォルダ内に gitレポジトリ用のフォルダを作成する。
cd ~/Dropbox
mkdir repository

2.
上記フォルダ内に、[プロジェクト名].git というフォルダを作成して init する。
cd repository
mkdir ProjectName.git
cd ProjectName.git
git --bare init

--bare
Create a bare repository. If GIT_DIR environment is not set, it is set to the current working directory. *1

裸のリポジトリ(bare repository)
裸のリポジトリとは、通常 .git の拡張子を持つ ディレクトリ で、 リビジョン管理下にあるチェックアウトしたファイルをローカルに持たないディレクトリです。 通常 .git サブディレクトリ に隠れている git の管理ファイル全てが repository.git ディレクトリに直接存在し、 他のファイルは存在せず、チェックアウトもされていません。 通常、公開リポジトリを出版する人は、裸のリポジトリを作成します。*2

3.
既存のソースを追加するためには、そのプロジェクト上で以下のコマンドを実行する。
cd ~/develop/OldProject
git init
git add . // 全てのファイルを追加する
git commit -m "(コメント入力)"
git push ~/Dropbox/repository/ProjectName.git master
git remote add origin ~/Dropbox/repository/ProjectName.git

4.
ファイルを更新した後、以下のように更新したファイルの addとcommitを行い、さらに ローカルレポジトリ(既存プロジェクト)をリモートレポジトリ(Dropbox に作成したレポジトリ)へ push する。
git add ~/develop/OldProject/oldfile.h // 変更を全て含む場合、git add --a
git commit -m "(コメント入力)"
git push ~/Dropbox/repository/ProjectName.git master //git push origin master でも可

参考:
*1
git-init(1) Manual Page

*2
Chapter11. GIT用語集 裸のレポジトリ