WWDC、E3、Objective-C のブロックと変数

WWDC 2012 基調講演が、11日午前10時 (日本時間、翌12日午前2時) に開催されました。Mac Book Air / Pro、iOS 6、OS X Mountain Lion の発表がありましたが、一番の関心は、Retina ディスプレイ MacBook Pro の発表です。iPadiPhone アプリ開発のために、iMac 27 インチを使用してきましたが、Retina ディスプレイ MacBook Pro でも問題なさそうです。所有してる iMac (Mid 2010) 27 インチは、Thunderbolt、USB 3.0 に対応していないので、購入時期も迫ってきています。Retina ディスプレイ iMac が発表されていたら、間違いなく購入していました。もう一年、我慢しようか、悩みどころです。

基調講演は、Apple のサイト

Apple - Apple Events - Apple Special Event March 2012
http://events.apple.com.edgesuite.net/123pibhargjknawdconwecown/event/index.html

で見れます。Podcast でも配信されています。

iTunes - Podcast - Apple Inc.「Apple Keynotes」
http://itunes.apple.com/jp/podcast/apple-keynotes/id275834665
iTunes - Podcast - Apple Inc.「Apple Keynotes (1080p)」
http://itunes.apple.com/jp/podcast/apple-keynotes-1080p/id509310064
iTunes - Podcast - Apple Inc.「Apple Keynotes (HD)」
http://itunes.apple.com/jp/podcast/apple-keynotes-hd/id470664050

1080p、HD 版も配信されています。

E3 も開催されていました。

E3 2012 - GameSpot.com
http://e3.gamespot.com/

上のサイト、左上の赤の背景に白色の文字で E3 2012 と表示されている部分をクリックし、Press Conferences を選ぶとそれぞれの基調講演を見ることができます。また、任天堂の基調講演は

任天堂 E3 2012情報 | E3レポート
http://www.nintendo.co.jp/n10/e3_2012/report/index.html

でも見れます。

以前、[id:KYoshiaki:20120429] iCloud プログラミングで書いた

Creating iOS 5 Apps: Develop and Design

Creating iOS 5 Apps: Develop and Design

[Kindle 版] と復習のために買った

Objective-C Programming: The Big Nerd Ranch Guide (Big Nerd Ranch Guides)

Objective-C Programming: The Big Nerd Ranch Guide (Big Nerd Ranch Guides)

[Kindle 版] を読み終えました。

Blocks とスコープ外の変数について、理解が深まりました。

typedef void (^ArrayEnumerationBlock)(id, NSUInteger, BOOL *);
ArrayEnumerationBlock devowelizer;
NSMutableArray *newStrings = [NSMutableArray array];
devowelizer = ^(id string, NSUInteger i, BOOL *stop) {
NSMutableString *newString = [NSMutableString stringWithString:string];
for (NSString *s in vowels) {
NSRange fullRange = NSMakeRange(0, [newString length]);
[newString replaceOccurrencesOfString:s withString:@"" options:NSCaseInsensitiveSearch range:fullRange];
}
[newStrings addObject:newString];
};
[oldStrings enumerateObjectsUsingBlock:devowelizer];

上のように、block 内で

[newStrings addObject:newString];

とスコープ外の変数 newStrings の内容を変更することができます。これは、メソッドを呼んでいるからです。プロパティで代入する場合も、同じです。

typedef void (^SampleBlock)();
__block NSString *two = [NSString stringWithString:@"two"];
SampleBlock sampleBlock;
FooClass *fooClass;
fooClass = [[FooClass alloc] init];
sampleBlock = ^() {
NSString *three = [NSString stringWithString:@"three"];
fooClass.foo = [NSString stringWithString:@"Orange"];
two = three;
changeValue(8);
};
sampleBlock();

ブロック内で

fooClass.foo = [NSString stringWithString:@"Orange"];

と代入することができます。ここでは、説明しやすいように

self.foo = bar;

とします。

実際には、ドット演算子を使ったプロパティは

The Objective-C Programming Language: Declared Properties
https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW1
▼ Declared Properties
▼ Property Declaration and Implementation
Property Declaration
Key-Value Coding Programming Guide: Key-Value Coding Fundamentals
https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/BasicPrinciples.html#//apple_ref/doc/uid/20002170-BA
▼Key-Value Coding Fundamentals
Dot Syntax and Key-Value Coding

を利用しているので

[self setFoo:bar];

または

[self setValue:bar forKey:@"foo"];

と同一です。故にメソッドを使っているので、block 内で代入できます。

foo = bar;

は、block 内で使えないので注意してください。foo が Objective-C のオブジェクト、または int、double などのスカラー型いずれの場合でも、__block を宣言しない限り、ブロック内では代入できません。

sample(bar);

上のような C の関数は、ブロック内で使えます。

結局、Cの関数、Objective-C の method は、ブロック内で使うことができます。また、プロパティを使ったドット表記も、実際には method を使っているので、ブロック内で使えます。ブロック内でスコープ外の変数に = (イコール) を使った代入は、__block を宣言しないと使えません。

サンプルとして zip ファイルを公開します。

VowelMovement.zip
http://kyoshiaki.sakura.ne.jp/osx/Sample/VowelMovement.zip
Creating iOS 5 Apps: Develop and Design

Creating iOS 5 Apps: Develop and Design

[Kindle 版] で見つけた面白い Blocks の使い方のサンプルも下記 URL で公開します。

Weights.zip
http://kyoshiaki.sakura.ne.jp/osx/Sample/Weights.zip

サンプルは、[ Creating iOS 5 Apps: Develop and Design ] [Kindle 版] のソースから、面白い使い方の箇所を抜き出して修正したものです。

//
//	Weights.m
//
- (void)processWeightEntryUsingBlock:(void (^)(NSNumber*)) block
{
NSLog(@"Weights.entries: %@", self.entries);
for (NSNumber* entry in self.entries) {
block(entry);
}
}
//
//	States.m
//
-(void)doStates
{
NSMutableArray *array;
array = [NSMutableArray array];
[self.weights processWeightEntryUsingBlock:^(NSNumber *number) {
int value;
NSNumber *num;
value = [number intValue];
num = [NSNumber numberWithInt:value*2];
[array addObject:num];
}];
NSLog(@"processWeightEntryUsingBlock: %@", array);
}

iOS 5 iCloud プログラミング

ニンテンドーDSi ウェア ‘プチコンmkII’ で、もう一つ取り組んでいるプログラムがあります。しかし、ちょっと一段落して iOS の iCloud について調べてみました。

最初に、新しくなった Xcode 4 の復習のため

Start Developing iOS Apps Today: Introduction
https://developer.apple.com/library/ios/#referencelibrary/GettingStarted/RoadMapiOS/Introduction/Introduction.html
Your Second iOS App: Storyboards: About Creating Your Second iOS App
https://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/SecondiOSAppTutorial/Introduction/Introduction.html
Your Third iOS App: iCloud: About Your Third iOS App
https://developer.apple.com/library/ios/#documentation/General/Conceptual/iCloud101/Introduction/Introduction.html

の3つの例題を試してみました。最終目的の iCloud プログラミングの理解に、3番目の Your Third iOS App が一番参考になります。iCloud は Simulator では動作しないので注意してください。

私自身、あくまでも趣味の範囲なので、iCloud の理解も UIDocument を基準にすることにしました。

iCloud に、どんなファイルが保存されているか調べるには OS X 上では

OS X (iCloud)
~/Library/Mobile Docunents

の上記フォルダで確認することができます。このフォルダの中身を変更すると問題が起こる確率が高いので、やめたほうがいいと思います。

また、iPhoneiPadiPod touch 上の

設定.app
iCloud  > ストレージとバックアップ > ストレージを管理 > 書類およびデータ

から、アプリを選択すると iCloud 内のファイルが表示されます。

右上に ‘編集’ ボタンがあるので iCloud 内のファイルを削除する時は、こちらを使うと良いと思います。

後、OS X、iOS 開発書籍の著者として有名な木下誠さんの iOS 技術情報誌アプリ

HMDT BOOKS
カテゴリ: ブック
販売業者: HMDT Co., Ltd.
http://itunes.apple.com/jp/app/hmdt-books/id500860946?mt=8
HMDT
http://hmdt.jp/

HMDT JOURNAL Vol.001
第1回 iCoud(1) iCoud とは
\170
HMDT JOURNAL Vol.002
第2回 iCoud(2) NSUbiquitousKeyValueStore
\170
HMDT JOURNAL Vol.003
第3回 iCoud(3) ファイルベースの同期
\170
HMDT JOURNAL Vol.004
第4回 iCoud(4) ドキュメントベースの同期
\170

も参考になると思います。貴重な情報源で、書籍のように邪魔にならないので、毎回購入しています。

まず最初に、Document-Based App を理解しないといけないので

Document-Based App Programming Guide for iOS: Creating a Custom Document Object
http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/DocumentBasedAppPGiOS/CreateCustomDocument/CreateCustomDocument.html#//apple_ref/doc/uid/TP40011149-CH8-SW1
▼Creating a Custom Document Object
Loading Document Data
Supplying a Snapshot of Document Data
Storing Document Data in a File Package

上の説明に出てくるソースから、Document-Based App を作りました。

また、ドキュメントデータをそれぞれ NSData、NSFileWrapper のどちらかで保存する方法も学びました。

NSURL の

+ URLWithString:
+ fileURLWithPath:

の違いに注意してください。

また、Document Type の宣言方法は、

Document-Based App Programming Guide for iOS: Document-Based Application Preflight
http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/DocumentBasedAppPGiOS/DocumentImplPreflight/DocumentImplPreflight.html#//apple_ref/doc/uid/TP40011149-CH3-SW2
▼Document-Based Application Preflight
▼Creating and Configuring the Project
Declare a Document Type

上記 URL のページが参考になります。

UTI の種類は

Uniform Type Identifiers Reference: Introduction to Uniform Type Identifiers Reference
http://developer.apple.com/library/ios/#documentation/Miscellaneous/Reference/UTIRef/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009258-SW1

を参照してください。

ここまで、Document-Based App の理解が進むと iCloud に取り掛かるのに充分だと思います。

iCloud について

Document-Based App Programming Guide for iOS: Designing a Document-Based Application
http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/DocumentBasedAppPGiOS/DocumentArchitectureiniOS/DocumentArchitectureiniOS.html#//apple_ref/doc/uid/TP40011149-CH2-SW7
▼Designing a Document-Based Application
▼A Document in iOS
 		A Document in iCloud Storage

を読んでから、もう一度

Your Third iOS App: iCloud: About Your Third iOS App
https://developer.apple.com/library/ios/#documentation/General/Conceptual/iCloud101/Introduction/Introduction.html

のソースと

Document-Based App Programming Guide for iOS: Managing the Life Cycle of a Document
http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/DocumentBasedAppPGiOS/ManageDocumentLifeCycle/ManageDocumentLifeCycle.html#//apple_ref/doc/uid/TP40011149-CH4-SW1
▼Managing the Life Cycle of a Document
▼Creating a New Document
▼Opening and Closing a Document

を参考に理解を深めると良いと思います。

Version Conflicts については

iiOS App Programming Guide: iCloud Storage
https://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/iCloud/iCloud.html#//apple_ref/doc/uid/TP40007072-CH5-SW1
▼iCloud Storage
▼Using iCloud Document Storage
Choosing a Strategy to Respond to Version Conflicts

が参考になります。

また、iCoud と Local 間の Documents の移動は

Document-Based App Programming Guide for iOS: Managing the Life Cycle of a Document
http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/DocumentBasedAppPGiOS/ManageDocumentLifeCycle/ManageDocumentLifeCycle.html#//apple_ref/doc/uid/TP40011149-CH4-SW1
▼Managing the Life Cycle of a Document
▼Moving Documents to and from iCloud Storage

に説明されています。HMDT JOURNAL Vol.001 ~ Vol.004 も参考になります。

Your Third iOS App: iCloud: About Your Third iOS App
https://developer.apple.com/library/ios/#documentation/General/Conceptual/iCloud101/Introduction/Introduction.html

のソースを読んでいると Blocks

Blocks Programming Topics: Introduction
https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html
A Short Practical Guide to Blocks
https://developer.apple.com/library/ios/#featuredarticles/Short_Practical_Guide_Blocks/_index.html
Building with Blocks in C and Objective-C
https://developer.apple.com/library/mac/#featuredarticles/BuildingWithBlocks/_index.html

や GCD

Concurrency Programming Guide: Introduction
https://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html

の理解も必要になってくると思います。

手っ取り早く理解したい場合は

Introducing Blocks and Grand Central Dispatch
https://developer.apple.com/library/mac/#featuredarticles/BlocksGCD/_index.html

が参考になります。

私自身、なかなか理解できない部分もあるので 、書籍

Creating iOS 5 Apps: Develop and Design

Creating iOS 5 Apps: Develop and Design

Creating iOS 5 Apps: Develop and Design [Kindle Edition]
Rich Warren (Author)
Kindle Price:
$21.99

を Amazon で購入し、iPadKindle で読んでいる途中です。iOS 5 になって変わった基本的な Objective-C の機能についての説明もあるので、今まで iOS 開発を行ってきた人にもお勧めの本です。

米Apple、アンテナ問題の記者会見、Xcode オーガナイザ による Application Data の管理、iTunes のファイル共有

Apple、アンテナ問題の記者会見のビデオを公開

アップル - QuickTime - 7月16日の記者会見
http://www.apple.com/jp/apple-events/july-2010/
アップル - スマートフォンのアンテナ性能
http://www.apple.com/jp/antenna/
アップル - アンテナ設計・試験室
http://www.apple.com/jp/antenna/testing-lab.html

個人的な意見ですが、iPhone 4 の外部アンテナが剥き出しで目視できることが問題なんだと思います。いろいろなウェブサイトから判断すると、性能的には欠陥というほどではないような気がします。

Statement by Apple on White iPhone 4
http://www.apple.com/pr/library/2010/07/23iphonestatement.html
アップル - iPhone 4 - ケースプログラム
http://www.apple.com/jp/iphone/case-program/

iPhone 4 ホワイト モデル発売が延期になったようですね!
2010年9月30日までに iPhone 4 を購入した方への iPhone 4 Bumper、または特定の他社製ケース無償配布の受付も始まったようです。

前回紹介したように iPhoneRSS リーダー iYKRSS を iPad に移植しました。

iPad Programming Guide: Starting Your Project
http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/StartingYourProject/StartingYourProject.html#//apple_ref/doc/uid/TP40009370-CH9-SW3
▼Creating a Universal Application
Adding Runtime Checks for Newer Symbols
Using Runtime Checks to Create Conditional Code Paths

上記ページを参考にして iPhoneiPad 両方で動作する Universal Application を作成しようと思ったのですが、ソースが複雑になりそうだったので、iPhone 用 iYKRSS を iPad 用に iYKRSSHD というプロジェクト名で新規作成しました。

iPad Programming Guide: Views and View Controllers
http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/UserInterface/UserInterface.html#//apple_ref/doc/uid/TP40009370-CH3-SW7
▼Views and View Controllers
▼Using Popovers to Display Content

上記ページを参考に popover を使用しました。一例が下図です。

ModalView を中央に表示するのに UIViewController の modalPresentationStyle に UIModalPresentationFormSheet を設定し、下記ソースのように利用しました。

- (IBAction)toolbarItemAddTapped:(id)sender
{
EditController *content;
if (self.gEditController == nil) {
content = [[[EditController alloc] initWithNibName:@"EditController" bundle:nil] autorelease];
content.gRootController = self;
content.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
content.modalPresentationStyle = UIModalPresentationFormSheet;
//		content.modalPresentationStyle = UIModalPresentationPageSheet;
self.gEditController = content;
}
[giYKRSSHDViewController presentModalViewController:gEditController animated:YES];
}

UIModalPresentationFormSheet の実行結果が下図です。

他の部分は iPhoneRSS リーダー iYKRSS とほとんど同じなので、難なく作成することができました。

RSS リーダーに登録したフィードなどのデータをファイルに保存するには、plist、NSKeyedArchiver、CoreData の3通りあります。

拙作 iYKRSS、iYKRSSHDでは CoreData を使うほど本格的なデータベースは必要ないし、plist を使うほど単純ではないので、NSKeyedArchiver を利用しています。

iYKRSS、iYKRSSHD で保存されるデータ構造は同一で同じファイル名 RSSArchive.iYKRSS です。ファイル RSSArchive.iYKRSS は、各々アプリケーションごとに作成される ‘アプリケーション’ フォルダの Documents フォルダに保存されています。

  • plist
Property List Programming Guide: Introduction to Property Lists
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/PropertyLists/Introduction/Introduction.html#//apple_ref/doc/uid/10000048i
  • NSKeyedArchiver
Archives and Serializations Programming Guide: Introduction
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Archiving/Archiving.html#//apple_ref/doc/uid/10000047i
  • CoreData
Core Data Programming Guide: Introduction to Core Data Programming Guide
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html#//apple_ref/doc/uid/TP40001075

iPhone 用 iYKRSS の RSS フィードデータファイル RSSArchive.iYKRSS を iPad 用 iYKRSSHD の Document フォルダに移動すれば iYKRSS の RSS フィードを iYKRSSHD で引き継ぐことができ便利です。iYKRSSHD 上で最初からフィードの URL を入力する必要もありません。

幸いにも Xcode でビルドしてデバイスにインストールしたアプリケーションの Application Data (Documents フォルダのデータも含む) は、Xcode のオーガナイザを使って読み書きすることができます。

オーガナイザは Xcode のメニュー(上図) ‘ウインドウ/オーガナイザ’ (下図) で開くことができます。

iOS Development Guide: Running Applications
http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/120-Running_Applications/running_applications.html#//apple_ref/doc/uid/TP40007959-CH6-SW4
▼Running Applications
Managing Application Data

上記URL が参考になります。

簡単に説明すると iPhoneiPad などのデバイスを USB で Mac に接続し、 Xcode のオーガナイザを開き、デバイス名をクリックします。’Summary タブ/ Applications’ のダウンロードしたいアプリを選び、三角を開くと ‘Application Data’ という名前が表示されます。右側にあらわれたダウンロードボタン(上図の赤枠部分)をクリックして保存してください。Finder 上にフォルダが作成されます。(下図参照) Documents フォルダに RSSArchive.iYKRSS を見つけることができます。



データを元に戻した時はダウンロードしてできたフォルダの中のデータを変更して、オーガナイザのダウンロードしたいアプリ名にフォルダをドラッグ・ドロップ (下図参照)することで変更できます。即ちファイルなどのデータを iPhoneiPad に書き込むことができます。

オーガナイザを使わずに iTunes のファイル共有を使って Documents フォルダのデータを読み書きすることもできます。

iOS Application Programming Guide: Implementing Standard Application Behaviors
http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StandardBehaviors/StandardBehaviors.html#//apple_ref/doc/uid/TP40007072-CH4-SW10
▼ Implementing Standard Application Behaviors
▼ Files and the File System
Sharing Files with the User

上記 URL が参考になります。

iTunes のファイル共有に Documents フォルダを表示させたい場合は、info.plist に UIFileSharingEnabled キー Boolean 型 YES を追加するだけです。

UIFileSharingEnabled キーは、メニュー ‘表示/Property List Type/Default File for Type’ で None を選ぶと入力しやすいと思います。

ただし、注意する必要があります。UIFileSharingEnabled を追加する前に、デバイス iPhoneiPad 上にアプリケーションがあると、ビルドしてインストールするだけでは、iTunes 上のファイル共有に表示されません。デバイスからアプリケーションを一度、削除して再インストールすると iTunes 上で同期した後、ファイル共有に表示されます。

上図を例にすると、iTunes 上のファイル共有/App から iYKRSSHD を選択すると Documnets フォルダにあるすべてのファイルが表示されます。この場合、RSSArchive.iYKRSS という名前のファイルが一つあります。ファイル RSSArchive.iYKRSS をウインドウの外にドラッグ・ドロップすればファイルを取り出すことができます。逆に Finder からファイルを iYKRSSHDD の書類と表示されているテーブルにドラッグ・ドロップすると Documents フォルダに書き込むことができます。