iPhone のファイル共有を試してみた

iPhone のファイル共有。iTunes の App タブの一番下に出てくるやつで、iTunes を介してファイルを iPhone のアプリケーションとやり取りできる機能。
ちょっと必要になりそうだったので簡単に確認してみた。

Xcode 4 での方法はこちらで説明しています。(2011/03/17 updated

ファイル共有を試してみる

とりあえず、何も考えずに View-based Application でアプリケーションを作成。名前は myDocShareTest。で、まずは何もせずにビルドして実機で試す。もちろん画面は真っ白。iTunes で「同期」をしてみるけど、iTunes のファイル共有にもアプリケーションは出てこない。

ここで Xcode に戻って「info.plistにUIFileSharingEnabledを追加してYES」とすれば良いのだけど、info.plist を開いてアイテムを加えても UIFileSharingEnabled という名前は出てこない。それでも名前に UIFileSharingEnabled を入れて return を押すと info.plist に Application supports iTunes file sharing という項目ができあがるので、これをチェックする(ON にする)。(最初から Application supports iTunes file sharing を選択して ON でも良い。)

この状態でセーブして再度ビルドと実行&実機で確認。実機の画面はもちろん真っ白なのでそのままアプリを終了。iTunes で「同期」をして「ファイル共有」を確認してみると、今度は myDocShareTest が出て来た。で、「追加…」ボタンで画像ファイルを追加する事もできた。

というわけで、info.plist に Application supports iTunes file sharing を作ってチェックすればファイル共有はできるようになる。超簡単!

アプリケーションからファイル共有のフォルダにアクセスするには?

それではアプリからどうやってファイルにアクセスするのか?
ファイル共有に出てくるフォルダはアプリの Document フォルダ。なので、NSDocumentDirectory を探してそこにあるファイルを読み込めば OK。こんな感じ。

	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

で、得られた Document フォルダへのパスにファイル名をくっ付けて、そのファイルにアクセスすれば OK。

というわけで、さっき iTunes のファイル共有に写真ファイル(carImage.png)をドラッグ&ドロップでコピーしたので、それを読み込んで UIImageView に表示する簡単なサンプルを作ってみた。

myDocShareTestViewController.h はこんな感じ。

#import <UIKit/UIKit.h>

@interface myDocShareTestViewController : UIViewController {
	IBOutlet UIButton *button1;
	IBOutlet UIImageView *image1;
}

- (IBAction)button1Clicked:(id)sender;

@end

myDocShareTestViewController.m には1つだけメソッドを加えた。

- (IBAction)button1Clicked:(id)sender
{
	//	ドキュメントフォルダへのパスを得る
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

	//	パスがあれば
	if ([paths count]>0) {
		//	最初のがドキュメントフォルダへのパス
		NSString *userDocumentsPath = [paths objectAtIndex:0];
		
		//	ドキュメントフォルダの中のリストを得る
		NSError *error = nil;
		NSArray *array = [[NSFileManager defaultManager]
						  contentsOfDirectoryAtPath:userDocumentsPath error:&error];

		//	ドキュメントフォルダの中身を得られれば
		if (array) {

			//	見つかったファイルの中から
			for (NSString *filename in array) {
				//	拡張子が png を探して
				if ([[filename pathExtension] isEqualToString:@"png"]) {
					//	ドキュメントフォルダのパスとファイルの名前を繋げたパスを作る
					NSString *imageFilePath = [userDocumentsPath stringByAppendingPathComponent:filename];

					//	そのパスから UIImage を作る
					UIImage *image = [UIImage imageWithContentsOfFile:imageFilePath];
					
					//	UIImage できたら
					if (image) {
						//	UIImageView にセット
						image1.image = image;
						//	おしまい!
						return;
					}
				}
			}
		}
	}
}

思い切り決めうちで、メモリとかエラー処理とか考え無し!(考えられない…)

で、InterfaceBuilder で UIImageView 置いて outlet を image1 と繋げる。他に UIButton も置いて action を button1Clicked と繋げる。
これでビルドと実行してボタンをタップすれば、ファイル共有でコピーした画像が表示される。

なんか物凄くあっさりとアクセスできるのね。


で、ファイルの書き出しも同じ場所にファイルを書き出せば OK。
例えば NSDictionary を用意して xml で書き出すならこんな感じ。

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *userDocumentsPath = [paths objectAtIndex:0];
NSString *exportFilename = @"exportedFile.xml";
NSString *exportFilePath = [userDocumentsPath stringByAppendingPathComponent:exportFilename];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"Object1", @"Key1", @"Object2", @"key2", nil];
[dictionary writeToFile: exportFilePath atomically:YES];

exportFilename が書き出す時のファイル名。
これを実行すれば、ファイル共有で exportedFile.xml が見える。

ファイルを選択して「保存先…」で保存して、エディタで開けばちゃんと Dictionary が xml になってる。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Key1</key>
	<string>Object1</string>
	<key>key2</key>
	<string>Object2</string>
</dict>
</plist>

というわけで、iPhone でのファイル共有を介したインポートとエクスポート、超簡単!