クロックに時報を追加する

2010. 05. 31
さて、今度はクロックへの時報を追加を行います。

●サンプルアプリケーションの概要

335

クロックの作成』で作ったクロックアプリケーションを改造して時報を設定するのですが、見た目は何も変わりません。

追加する作業としましては、

1)時報用タイマーの設置

2)時報用サウンドファイルの追加

3)サウンド再生のファイルとフレームワークの追加

4)サウンド再生用のデリゲートの対応

5)サウンド再生メソッドの追加

となります。


●時報用タイマーの設置


・時報用タイマーの宣言

XcodeでClockAppDelegate.hを開き、時報用タイマーの宣言を追加します。
(太字が追加した部分)

#import <UIKit/UIKit.h>

@interface WebAppDelegate : NSObject <UIApplicationDelegate> {
    IBOutlet UILabel *labelDate;    // 日付表示
    IBOutlet UILabel *labelTime;    // 時刻表示
    NSTimer *timerClock;    // 時計更新用タイマー
    NSTimer *timerAnnounce;    // 時報用タイマー
    UIWindow *window;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

349

時計更新用タイマーのtimerClockは単一メソッドなので、アプリケーション起動直後に発動するapplication:didFinishLaunchingWithOptions:内に直接記述していますが、時報用タイマーのtimerAnnounceは日時の取得などの処理があるため別メソッドとして起こしています。


・アプリ起動直後のapplication:didFinishLaunchingWithOptions:でのタイマー呼び出し

ClockAppDelegate.mのapplication:didFinishLaunchingWithOptions:で、時報用タイマーのメソッドsetupTimeAnnounceを呼び出します。
(太字が追加した部分)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch

    timerClock = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateClock:) userInfo:nil repeats:YES];

    [self setupTimeAnnounce];

    [window makeKeyAndVisible];

    return YES;
}

351


・時報用タイマーの実装

呼び出すメソッドを記述ですが、この際呼び出しているapplication:didFinishLaunchingWithOptions:より前にsetupTimeAnnounceを記述してください。
(『呼び出すメソッドが無い』とコンパイルエラーが出ますので)

- (void)setupTimeAnnounce {
    // 時報用のタイマーを生成
    timerAnnounce = [NSTimer scheduledTimerWithTimeInterval:60.0f target:self selector:@selector(playAnnounce:) userInfo:nil repeats:YES];

    // 現在の日時とカレントのカレンダーを取得
    NSDate *date = [NSDate date];
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *cmp = [cal components:NSSecondCalendarUnit fromDate:date];

    // 次の時報の日時を取得
    NSDate *dateAnnounce = [NSDate dateWithTimeIntervalSinceNow:60.0f - [cmp second]];

    // 時報の日時を設定
    [timerAnnounce setFireDate:dateAnnounce];
}

350

時報用タイマーの設定は時計更新用タイマーと同じく、scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:メソッドを使います。

異なる点は、

・60.0秒間隔で発火
・発火時にplayAnnounce:(時報用再生メソッド)を呼び出し

の2点です。

次にタイマーの発火時刻を設定します。

手順は、

1)dateメソッドで現在時刻の取得
2)currentCalendarメソッドで現在のロケールのカレンダーを取得
3)取得した時刻とカレンダーを使用し、components:fromDate:メソッドで日付コンポーネントを生成
4)発火時間を補正(今回の場合、各分の0秒で発火)するため、dateWithTimeIntervalSinceNow:メソッドで差分の時間を追加
5)補正した発火時間をsetFireDate:メソッドで設定

となっています。

date、currentCalendar、components:fromDate:、dateWithTimeIntervalSinceNow:メソッドについては『Foundation(日付と時間)』を参照してください。


・setFireDate:
(NSTimerクラス)

- (void)setFireDate:(NSDate *)date

レシーバで設定されている発火時間を再設定します

このメソッドは通常、リピートタイマーの発火時間の調整に使用します

タイマーの次の発火時間を再設定は比較的高くつく操作ですが、いくつかの状況では効率的です

例えば、不規則な時間間隔で、複数の時刻に動作を繰り返す状況では有効です

1つの実行ループのスケジューリングの中で複数のタイマーオブジェクトを作成・破棄をするより、1つのタイマーの発火時間を調整した方がよりコストを少なくできます

無効になっているタイマーや、発火済みの非リピートタイマーでこのメソッドを呼び出さないでください

ただし、スレッドに常に接続されている潜在的な競合状況を避けるためのタイマーの場合、未発火の非リピートタイマーからこのメソッドを潜在的に呼び出すことができます

date:新しく再設定する発火の日時を指定します
新しい日付が既に過ぎていた場合、このメソッドは現在の時刻を発火時間に設定します


●サウンド再生のファイルとフレームワークの追加

時報用のサウンドファイルは、自作できればそれに越したことはないのですが、ファイルフォーマットやデータフォーマット、コーデックなどがまだ理解できていないので、『基礎からのiPhone SDK 改訂版』のサンプルコードを出版社のサイトからダウンロードして、iPhoneBG2.zipを展開、『SampleCode』 → 『50.04.Clock ( 時報 )』フォルダ下のtime1.cafファイルをコピーして使います。

同ファイルを自分のプロジェクトフォルダにコピーし、そこからプロジェクトのResourcesフォルダにドラッグ&ドロップします。

今回はサウンドの再生に唯一のObjective-Cインターフェイスである、AVAudioPlayerをしようするのでFrameworksを右クリックして『追加』→『既存のフレームワーク』でAVFoundation.frameworkを追加します。

352

『サウンド再生用のデリゲートの対応』の前に、AVAudioPlayerDelegateプロトコルの説明をします。


●AVAudioPlayerDelegateプロトコル

AVAudioPlayerオブジェクトのデリゲートは、AVAudioPlayerDelegateプロトコルを採用しなければなりません。

このプロトコルの全てのメソッドはオプションです。

デリゲートは、サウンド再生の完了やオーディオのデコード、オーディオの中断などに対応します。


・AudioPlayerBeginInterruption:
(AVAudioPlayerDelegateプロトコル)

- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player

電話の呼び出しなどでオーディオプレイヤが中断された時に呼び出されます

中断されると、アプリケーションのオーディオセッションは非アクティブとなり、オーディオプレイヤが一時停止します

中断終了の通知を受け取るまで、オーディオプレイヤを再開することはできません

player:中断されたオーディオプレイヤを指定します


・audioPlayerDecodeErrorDidOccur:error:
(AVAudioPlayerDelegateプロトコル)

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error

オーディオプレイヤの再生中にデコードエラーが発生した時に呼び出されます

player:デコードエラーが発生したオーディオプレイヤを指定します

error:デコードエラー


・audioPlayerDidFinishPlaying:successfully:
(AVAudioPlayerDelegateプロトコル)

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag

サウンドの再生が完了した時に呼び出されます

このメソッドは、オーディオが中断された時には呼び出されません

中断されるとオーディオプレイヤは一時停止し、サウンドの再生は完了しません

player:再生を完了したオーディオプレイヤを指定します

flag:再生が完了した場合はYESを、システムがオーディオデータのデコードをできなかった場合はNOを返します


・audioPlayerEndInterruption:
(AVAudioPlayerDelegateプロトコル)

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player

ユーザが電話の呼び出しを無視するなどで、中断が終了すると呼び出されます

中断が終了すると、アプリケーションは自動的にオーディオセッションを再アクティブ化し、オーディオプレイヤと対話できます

再生を再開するには、playメソッドを呼び出します

player:中断の終了したオーディオプレイヤを指定します


●サウンド再生用のデリゲートの対応

Core Audioの復習』のAVAudioPlayerでも述べていますが、AVAudioPlayerを利用するにはデリゲートに対応(AVAudioPlayerDelegateの採用)しなければなりません。

プロトコルについての詳細は『Objective-C言語のメモ書き(4)』を参照してください。

AVAudioPlayerDelegateプロトコルの場合、全てのメソッドがオプションなので必要なければ実装する必要が無く、ClockAppDelegate.hにAVAudioPlayerDelegateプロトコルを追加するだけで済みます。
(太字が追加した部分)

@interface ClockAppDelegate : NSObject <UIApplicationDelegate, AVAudioPlayerDelegate> {
IBOutlet UILabel *labelDate; // 日付表示
IBOutlet UILabel *labelTime; // 時刻表示
NSTimer *timerClock; // 時計更新用タイマー
NSTimer *timerAnnounce; // 時報用タイマー
UIWindow *window;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

353

今回の場合は、AVAudioPlayerのインスタンス破棄のため、audioPlayerBeginInterruption:メソッドを実装しています。

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)avap successfully:(BOOL)flag {
    // インスタンスを破棄
    [avap release];
}

354

audioPlayerDidFinishPlaying:successfully:メソッドはオーディオプレイヤが再生を完了した時に呼び出されます。


●サウンド再生メソッドの追加

最後に時報を鳴らすplayAnnounce:メソッドを実装します。

時報用のサウンドファイル(time1.caf)を読み込んで再生するので、アプリケーションバンドルを取得し、バンドルからサウンドファイルのパスを取得、URLに変換します。

URLに変換するのは、AVAudioPlayerのサウンドファイル指定がNSURL形式なためです。

そして、通知を受け取るデリゲートの設定をし、サウンドを再生します。

- (void)playAnnounce:(NSTimer *)timer {
    // アプリケーションのバンドルを取得
    NSBundle *bundle = [NSBundle mainBundle];

    // リソースのファイルパスを取得
    NSString *path = [bundle pathForResource:@"time1" ofType:@"caf"];

    // ファイルパスからURLを生成
    NSURL *url = [NSURL fileURLWithPath:path];

    // AVAudioPlayerのインスタンス生成
    AVAudioPlayer *avap = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];

    // デリゲートの設定
    avap.delegate = self;

    // サウンドの再生
    [avap play];
}

355

mainBundleメソッドで現在実行しているアプリケーションのディレクトリ位置を確認し、pathForResource:ofType:メソッドでファイル名と拡張子からファイルを特定します。

mainBundleとpathForResource:ofType:メソッドの詳細については『Foundation(バンドル)』を参照してください。


・fileURLWithPath:
(NSURLクラス)

+ (id)fileURLWithPath:(NSString *)path

指定したパスからファイルURLのNSURLオブジェクトを新規に作成し、初期化して返します

このメソッドは、pathがスラッシュ(/)で終わるディレクトリであることを仮定しています

pathがスラッシュで終わっていない場合、pathがファイルシステムにあるファイルまたはディレクトリかどうかをメソッドが調べます

pathがファイルシステムのディレクトリに存在する場合、メソッドは末尾にスラッシュを付加します

pathがファイルシステムに存在しない場合、ファイルを表しているものと仮定して、メソッドは末尾にスラッシュを付加しません

代替案として、fileURLWithPath:isDirectory:を使って、返されるNSURLオブジェクトがファイルまたはディレクトリを表すかどうかを明示的にすることも検討してください

path:NSURLオブジェクトで表すパスを指定します
指定するパスは、有効なシステムパスにする必要があります
パスがチルダ(~)で始まる場合は、最初にstringByExpandingTildeInPathで展開する必要があります
このパラメータにnilを渡すと例外が発生します


・initWithContentsOfURL:error:
(AVAudioPlayerクラス)

- (id)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError

指定したサウンドファイルを再生するオーディオプレイヤを初期化して返します

成功した場合はAVAudioPlayerオブジェクトを初期化します

戻り値がnilの場合は、outErrorパラメータに含まれている問題を説明するコードを参照してください

url:再生するサウンドファイルのURLを指定します
オーディオデータは、Core Audioがサポートしているフォーマットである必要があります

outError:成功した場合はnilを、失敗した場合はエラーコードが含まれます


・delegate
(AVAudioPlayerクラス)

@property(assign) id<AVAudioPlayerDelegate> delegate

オーディオプレイヤのデリゲートオブジェクトを返します

このオブジェクトは、オーディオプレイヤのデリゲートとして、AVAudioPlayerDelegateプロトコルの通知のターゲットに割り当てられます

これらの通知には、デコードエラーや電話の呼び出しによるオーディオの中断、再生の完了などがあります


・play
(AVAudioPlayerクラス)

- (BOOL)play

非同期のサウンドを再生します

戻り値は、成功した場合はYESを、失敗した場合はNOを返します

もしオーディオプレイヤが事前に再生の準備ができていない場合、このメソッドは暗黙的にprepareToPlayメソッドを呼び出します



参考文献

AVAudioPlayerDelegate Protocol Reference

AVAudioPlayer Class Reference

NSURL Class Reference

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

Core Audioの復習

2010. 05. 29
クロックの作成』で作ったクロックアプリケーションを改造して、アラームを設定するのですが、その前にCore Audioの復習をしたいと思います。

以前書いた『Core Audioテクノロジーの概要』の焼き直しですが、ご容赦ください。


●Core Audioアーキテクチャ


・iPhone OSのオーディオテクノロジー

iPhone OSにおけるオーディオテクノロジーは、基本的にCore Audioアーキテクチャが担い、OpenALもサポートしています。

Core Audioアーキテクチャは、Core Audioファミリのフレームワークで構成されており、各フレームワークが実際の処理を行うサービスを提供するという形になっています。

『Core Audioテクノロジーの概要』でも触れましたが、『Core Audio』はオーディオ全般のアーキテクチャの総称であると同時に、オーディオデータタイプを定義する同名のフレームワークが存在することに注意してください。
(CoreAudio.frameworkが、Core Audioアーキテクチャの中心や親となるフレームワークというわけでもありません)


Core Audioアーキテクチャ
    |
    ∟Core Audio系フレームワーク
    |        |
    |        ∟AudioToolbox.framework
    |        |        ∟AudioConverter.h(Audio Converter Services
    |        |        ∟AudioFile.h(Audio File Services
    |        |        ∟AudioFileStream.h(Audio File Stream Services
    |        |        ∟AudioFormat.h(Audio Format Services
    |        |        ∟AudioQueue.h(Audio Queue Services
    |        |        ∟AudioServices.h(Audio Session Services、System Sound Services
    |        |        ∟AudioToolbox.h
    |        |        ∟AUGraph.h(Audio Processing Graph Services
    |        |        ∟ExtendedAudioFile.h(Extended Audio File Services
    |        |
    |        ∟AudioUnit.frameworkAudio Unit Services
    |        |        ∟AUComponent.h(Audio Unit Component Services
    |        |        ∟AudioComponent.h(Audio Component Services
    |        |        ∟AudioOutputUnit.h(Output Audio Unit Services
    |        |        ∟AudioUnit.h
    |        |        ∟AudioUnitParameters.h
    |        |        ∟AudioUnitProperties.h
    |        |
    |        ∟CoreAudio.framework
    |        |        ∟CoreAudioTypes.h
    |        |
    |        ∟AVFoundation.framework
    |                ∟AVAudioPlayer.h(AVAudioPlayerクラス
    |
    ∟OpenAL系フレームワーク
            |
            ∟OpenAL.framework(定位オーディオを提供するクロスプラットフォーム標準)
                    ∟al.h
                    ∟alc.h
                    ∟oalMacOSX_OALExtensions.h
                    ∟oalStaticBufferExtension.h


フレームワークの中で、iPhone OS 2.2で追加されたAVFoundation.frameworkのみObjective-Cのインターフェイスで、OpenALを含め他は全てC言語のインターフェイスです。


Audio Toolboxフレームワーク

Audio Toolboxフレームワークは、録音、再生、ストームの解析のインターフェイスを提供します。

iPhone OSでは、オーディオセッションを管理する追加インターフェイスも提供します。


・Audio Converter Services

Audio Converterオブジェクトは、様々なリニアPCMオーディオフォーマットの変換を行います。

リニアPCMと圧縮フォーマット間の変換をすることができます。

サポートされている変換は以下の通りです。

・PCMのビット深度
・PCMのサンプルレート
・浮動小数点PCMと固定小数点PCMの相互変換
・PCMのインターリーブと非インターリーブの相互変換
・PCMと圧縮フォーマットとの相互変換

1つのオーディオコンバータが2種以上の変換を行う場合があります。


・Audio File Services

ディスクまたはメモリバッファの様々なオーディオデータを、読み込みまたは書き込みを行うCプログラミングインターフェイスです。

Audio File Servicesでは以下のことができます。

・オーディオファイルの生成、初期化、開く、閉じる
・オーディオファイルの読み込みと書き込み
・オーディオファイルの最適化
・ユーザデータとグローバル情報の操作


・Audio File Stream Services

Audio File Stream Servicesは、ストリームのオーディオファイルを解析するインターフェイスを提供します。
(一度に入手できるデータのウィンドウは限定されています)

オーディオファイルストリームは、特性上ランダムアクセスはできません。

ストリームからデータを要求する時、データの先頭がアクセス可能な長さではなかったり、末尾のデータがまだ入手できていない場合があります。

さらに、入手するデータには解析に必要なパケット部分を含んでいる場合もあります。

ストリームのオーディオデータを解析するには、パーサ(解析プログラム)の要求を満たす部分データを覚えていて、残りのデータを待つことができる必要があります。

パーサは必要に応じて解析を保留したり、再開できる必要があります。

パーサを使用するには、ストリームのオーディオファイルを取得して、パーサにデータを渡します。

パーサは完全なオーディオデータのパケットまたは完全なプロパティを受け取ると、コールバック関数を呼び出します。

コールバックでは解析したデータを再生したり、ディスクへ書き込んだりします。

以下に、典型的なオーディオファイルストリームのパーサの処理手順の要点を示します。

1)AudioFileStreamOpen関数を呼び出し、新しいオーディオファイルストリームのパーサを生成します
コールバック関数にオーディオデータとメタデータのポインタを渡します。
(AudioFileStream_PacketsProcとAudioFileStream_PropertyListenerProc)
AudioFileStreamOpen関数で新しいパーサに参照を渡します。

2)ストリームデータを取得します。
AudioFileStreamParseBytes関数を呼び出し、パーサにデータを渡します。
パーサにデータを順次、できれば隙間無く送ります。

a.パーサは利用可能なオーディオデータのバッファを取得すると、オーディオデータのコールバックを呼び出します。
コールバックはデータを再生したり、ファイルに書き込んだりなどの処理を行います。

b.パーサはメタデータを取得すると、プロパティのコールバックを呼び出し、AudioFileStreamGetPropertyInfoとAudioFileStreamGetProoerty関数を呼び出してプロパティ値を入手します。

3)ストリームの解析が終わるとAudioFileStreamClose関数を呼び出し、パーサを閉じて解放します。

Audio File Stream Servicesは以下のオーディオデータタイプをサポートします。

・AIFF
・AIFC
・WAVE
・NeXT
・ADTS
・MPEG Audio Layer 3
・AAC


・Audio Format Services

iPhone OSとMac OS Xの、オーディオフォーマットとコーデックの情報を入手するCインターフェイスです。


・Audio Queue Services

Audio Queue Servicesは、Core Audioの一部であるAudio ToolboxフレームワークのCプログラミングインターフェイスです。

audio queueは、オーディオの録音または再生に使うソフトウェアオブジェクトです。

audio queueの仕事は、

・オーディオハードウェアへの接続
・メモリ管理
・オーディオ圧縮フォーマットに必要なコーデック採用
・再生または録音の仲介

Audio Queue Servicesは、リニアPCMや圧縮フォーマット(例えばApple LosslessとAAC)と、ユーザがインストールしているコーデックの他フォーマットのオーディオの録音と再生を行います。

Audio Queue Servicesは、スケジュール再生と複数のaudio queuesの同期、オーディオとビデオの同期をサポートします。


・Audio Session Services

Audio Session Servicesは、他のアプリケーションの状況によって、アプリケーションのオーディオの動作を管理するCインターフェイスです。

Audio Session Servicesは、iPhone OSアプリケーションでのオーディオの動作を指定できます。

例えば、貴方のアプリケーションでビルトインアプリケーションを無音にしたり、またそれらのオーディオとミックスさせることもできます。

またAudio Session Servicesを使って、電話の呼び出し時などにアプリケーションの動作を中断するよう指定することもできます。


・Audio Unit Processing Graph Services

Audio Unit Processing Graph Servicesは、オーディオユニットの設定を表すインターフェイスを提供するもので、入力と出力を接続、コールバックが使用する入力を提供します。

また、総合的な信号チェーンの一部の論理構造を考慮し、親グラフにサブ(または子)の処理グラフを埋め込むことができます。

(AUGraph型の)オーディオ処理グラフオブジェクトは、オーディオ信号処理ネットワークを完全に作図します。

Audio Unit Processing Graph Servicesは、オーディオユニットのインスタンスの管理にAUGraphOpen関数を呼び出します。

オーディオ処理グラフオブジェクトは、完全な 情報 全てのオーディオユニットのグラフに関する完全な情報を得ます。


グラフには様々なノードオブジェクト(各AUNode型)が有り、それぞれのオーディオユニットまたはサブグラフを表し、追加や削除、連携や修正をすることもできます。

グラフオブジェクトの状態は、描画スレッドと他のスレッドの両方を操作できます。

その結果、グラフの状態に影響する全てのアクティビティは保護され、メッセージングモデル間の呼び出しスレッドとグラフオブジェクトの出力ユニットが呼び出したスレッド(描画スレッド)がロックされます。

グラフオブジェクトは一つのヘッドノード(出力ユニット)を持ちます。

出力ユニットは、グラフの描画操作の開始と終了に使用され、実行されているグラフの状態を安全に操作できるポイントに送り込まれます。


・Extended Audio File Services

Extended Audio File Servicesは、オーディオファイルのアクセスを簡素化し、Audio File ServicesとAudio Converter Servicesを合わせた特徴を持っています。

リニアPCMオーディオファイルと同様に、圧縮ファイルの読み込みと書き込みの統一したインターフェイスを提供します。


・System Sound Services

System Sound Servicesは、短いサウンドの再生とバイブレーションの呼び出しを行うCインターフェイスです。

System Sound Servicesは30秒以下の短いサウンドの再生ができます。

このインターフェイスは、レベル、ポジショニング、タイミング制御を提供しません。

System Sound Servicesは、iPhoneのバイブレーション機能や、iPod touchの(圧電振動子を使用した)短時間の警告音機能を使用することができます。


●Audio Unitフレームワーク

Audio Unitフレームワークは、ビルトインとカスタムのオーディオ処理プラグインと、既知のオーディオユニットを使用するインターフェイスを提供します。

iPhone OSでは、アプリケーションでビルトインのオーディオユニットを使用できます。

Mac OS Xでは、サードパーティ製を含むビルトインまたはカスタムのオーディオユニットを使用できます。

以下に役立つ追加ドキュメントを示します。

・オーディオ処理グラフにオーディオユニットを接続するAPIの説明については、『Audio Toolbox Framework Reference』の『Audio Unit Processing Graph Services Reference』を参照してください。

・iPhone OSのオーディオユニットへのアクセスの情報については『Audio Unit Hosting Guide for iOS』を参照してください。


・Audio Component Services

Audio Component Servicesは、オーディオユニットとオーディオコーデックの検索と開くためのインターフェイスを定義します。

Mac OS X v10.5でコンポーネントインターフェイスのバイナリ互換を保持するには、コンポーネントマネージャーの依存を削除してください。


・Audio Unit Component Services

Audio Unit Component Servicesは、オーディオユニットを使用するためのCインターフェイスを提供します。

オーディオユニットはプラグインを使うオーディオ処理や、オーディオデータの生成を行います。

オーディオユニットを検索、開く、閉じるには『Audio Component Services Reference』で述べている、Audio Component Servicesのコンパニオンインターフェイスを使用してください。

オーディオユニットには『type』、『subtype』、『manufacturer ID』の3組の識別コードが有ります。

詳細は、Audio Component Services ReferenceのAudioComponentDescription構造体を参照してください。


・Output Audio Unit Services

Output Audio Unit Servicesは、Audio UnitフレームワークのCインターフェイスです。

このインターフェイスはI/Oオーディオユニット(多くの場合、出力オーディオユニットと呼ばれる)の開始と停止に使用します。


●Core Audioフレームワーク

Core Audioフレームワーク(Core Audioの他のサービス向けのアンブレラフレームワークではなく、むしろ同等)の他のCore Audioインターフェイスが使用する、データ型と定数を定義します。

このフレームワークには便利な機能を持つ関数が含まれています。


・Core Audio Data Types

Core Audioで使用する全てのデータ型と定数を表しています。

また、これらの型と定数を操作する便利な機能もあります。


●AV Foundationフレームワーク

AV Foundationフレームワークは、iPhone OSアプリケーションでのオーディオの再生と録音を行う、Objective-Cインターフェイスを提供します。

また、アプリケーションのオーディオセッションの設計と管理をする、AVAudioSessionClassを提供します。


・AVAudioPlayerクラス

AVAudioPlayerクラスのインスタンスはオーディオプレイヤと呼ばれ、ファイルまたはメモリからオーディオデータの再生を提供します。

アプリケーションの要求が、ステレオポジションや正確な同期、ネットワークストリームからのキャプチャされたオーディオの再生でない限り、Appleはこのクラスを使用したオーディオの再生を推奨します。

オーディオテクノロジーの概要については『Audio & Video Starting Point』を参照してください。

オーディオプレイヤを使用すると以下のことができます。

・任意の時間のサウンドの再生
・ファイルまたはメモリバッファからのサウンドの再生
・ループ再生
・オーディオプレイヤごとに1サウンドで、複数同時再生
・再生中の各サウンドの相対的な再生レベルの制御
・サウンドファイルの特定の位置へのシーク、アプリケーションによる速い巻き戻しと早送り機能のサポート
・再生レベルメータに使用できるデータの取得

AVAudioPlayerクラスは、iPhone OSが使用するオーディオフォーマットのサウンドを再生できます。

(例えば、電話の呼び出し時など)処理の中断や、サウンドの再生終了時のユーザインターフェイスの更新には、デリゲートを使用します。

AVAudioPlayerクラスのデリゲートメソッドについては、『AVAudioPlayerDelegate Protocol Reference』を参照してください。

このクラスは、サウンドのタイムラインの再生位置や、ボリュームやループなど再生のオプションへのアクセスといったサウンドについての情報を管理に、Objective-Cで宣言したプロパティの機能を使用します。

また、プロパティ(再生)をテストで使う際は、必ず再生中に行ってください。

再生のための適切なオーディオセッションを設定するには、『AVAudioSession Class Reference』と『AVAudioSession Delegate Protocol Reference』を参照してください。


・AVAudioRecorderクラス

AVAudioRecorderクラスのインスタンスはオーディオレコーダと呼ばれ、アプリケーションのオーディオの録音機能を提供します。

オーディオレコーダを使用すると以下のことができます。

・ユーザが停止するまでの録音
・指定された時間の録音
・録音の一時停止と再開
・入力レベルメータに使用できるデータの取得

オーディオレコーダでの録音の中断や完了、デコードエラーへの対応には、デリゲートオブジェクトを使用します。

ビット深度やビットレート、サンプルレート変更の品質など、オプションを含む録音の設定は辞書で構成します。

録音のための適切なオーディオセッションを設定するには、『AVAudioSession Class Reference』と『AVAudioSession Delegate Protocol Reference』を参照してください。


●AVAudioSessionクラス

AVAudioSessionクラスのインスタンスはオーディオセッションと呼ばれ、シングルトンオブジェクトを採用し、アプリケーションにオーディオコンテキストを設定します。

このクラスを使用すると以下のことができます。

・アプリケーションのオーディオセッションを有効または無効にします
・オーディオセッションのカテゴリを設定
・オーディオハードウェアのサンプルレートとI/Oバッファ時間の指定

iPhone OS 3.0以降では、Objective-CでAudio Session Servicesの代替手段を提供します。

オーディオセッションの詳細については、『Audio Session Programming Guide』を参照してください。



参考文献

iOSテクノロジーの概要

Core Audioの概要

Audio Toolbox Framework Reference

Audio Converter Services Reference

Audio File Services Reference

Audio File Stream Services Reference

Audio Format Services Reference

Audio Queue Services Reference

Audio Session Services Reference

Audio Unit Processing Graph Services Reference

Extended Audio File Services

System Sound Services Reference

Audio Unit Framework Reference

Audio Component Services Reference

Audio Unit Component Services Reference

Output Audio Unit Services Reference

Core Audio Framework Reference

Core Audio Data Types Reference

AV Foundation Framework Reference

AVAudioPlayer Class Reference

AVAudioRecorder Class Reference

AVAudioSession Class Reference

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

日付フォーマットのパターン

2010. 05. 26
前回の『クロックでカレンダーを指定する』で出てきた『Unicode Technical Standard #35/Locale Data Markup Language/Appendices/Date Format Patterns』を訳してみます。

●付録F:日付フォーマットのパターン

日付パターンの文字列の文字は、カレンダーの日付と時刻のデータを特定の文字列で置き換え、カレンダーの書式用のデータを生成するものです。

後述する文字は、指定したロケールのフォーマットに適した形式を示すために使用されます。

以下に例を示します。

パターン結果(特定のロケール)
yyyy.MM.dd G 'at' HH:mm:ss zzz1996.07.10 AD at 15:08:56 PDT
EEE, MMM d, ''yyWed, July 10, '96
h:mm a12:08 PM
hh 'o''clock' a, zzzz12 o'clock PM, Pacific Daylight Time
K:mm a, z0:00 PM, PST
yyyyy.MMMM.dd GGG hh:mm aaa01996.July.10 AD 12:08 PM

文字は複数回使用されることがあります。

例えば、年の書式で y を使用する場合、『yy』では『99』となり、また『yyyy』とすると『1999』となります。

ほとんどの数値フィールドは、文字数がフィールドの幅を指定することになります。

例えば、時間の書式で h を使用する場合、『h』では『5』となりますが、『hh』とすると『05』となります。

いくつかの文字は数値の指定に関わらず、省略または完全な形式で使用する必要がありますが、下表のように他の選択肢がある場合もあります。

注:後方互換性のため月と曜日に関しては、5文字を指定した場合に短い形式になります。


フィールド文字列 数値 説明
紀元G1AD現在の日付の紀元を文字列に置き換えます
y1..n1996
Y1..n1997ISO年間週数カレンダーで使われる(年間週数の)年。
通常の年とは異なります。
u1..n4601拡張した年。
これはカレンダーシステムの年を一桁の数字で指定し、全て
の上(過去)の範囲を網羅します。
例えばユリウス暦の場合、年数は正の値で、BCEまたはCE
を併記します。
ユリウス暦に拡張した年の値を割り当てる場合、正の値は
CEに、負の値はBCEになり、0年はBCE 1年になります。
M1..29月は1または2の場合は数字、3は省略した名前、4は完全な
名前、5は短縮した名前になります。
3Sept
4September
5S
w1..227年間週数
W13月間週数
d1..21日はその月の日を示します
D1..3345年間日数
F12  月内における週の日を示します。
例えば、7月第2週の水曜日など。
(曜日に関係なく、1~7日は1、8~14日は2という結果に
なります) 
g1..n2451334ユリウス通日。
ユリウス通日は通常の暦とは2つの異なる考えに基づいてい
ます。
まず起点となるのが紀元前4713年1月1日GMTですが、深夜
0時ではなく、昼の12時になっています。
次に各地域のタイムゾーンに依存せず、GMTを基準として
計算しています。
日付に関連する全ての分野で扱えるような単一の数値として
考えられています。
(原文では『Modified Julian day』とあり、修正ユリウス
日(MJD)を指しているようにも見えますが、説明や左項の
例などからユリウス通日(AJD)と思われます。
『修正ユリウス日』ではなく『ユリウス日への変換』と解釈
するようです。従って説明も直訳すると矛盾する点もあるの
で『Wikipedia/ユリウス通日』を参考に解釈しています)
曜日 E1..23曜日は3は省略した名前、4は完全な名前、5は短縮した名前
になります。
(1~2の数値表現の場合)日曜は常に1です。
3Tues
4Tuesday
5T
e1..22ローカルの曜日は、(1~2の)数値表示以外は『E』と同じ
です。
数値表示はローカルで週の始まる曜日に依存します。
例では、週の初日が月曜の場合を示しています。
3Tues
4Tuesday
5T
期間a1AMAMまたはPM
h1..211時(1~12)
H1..213時(0~23)
K1..20時(0~11)
k1..224時(1~24)
m1..259分は1または2桁で示し、0で補完されます
s1..212秒は1または2桁で示し、0で補完されます
S1..n3456小数点以下の秒は、指定桁数に丸められます。
(例は『12.34567』秒の場合)
A1..n69540000日間ミリ秒数(例は19時間19分を表しています)。
この領域は他の時間帯領域を含まず、全ての時間関連の領域
を合成し、正確に動作します。
(つまり、秒や分、時という単位領域も含めて数えて示すと
いう意味です)
この値はDST(夏時間)への移行日のような不連続の時間
も表します。
DSTに入る日は前方にジャンプし、DSTが終わる日は後方
にジャンプします。
これはローカルタイムの値に影響されるので、取得する際
には注意が必要です。
時間帯 z1PT時間帯は、1は省略した壁時間(設定されているローカルの
時間帯)、2は長い壁時間、3は省略したタイムゾーン、4は
完全なタイムゾーンの名前になります。
設定されている時間帯に名前が無い場合、利用可能な代わり
のデータを使用します。
(この設定値は言語環境とタイムゾーンの設定地域によって
表現が異なります。日本語環境でタイムゾーンが日本の
場合、1~3は『JST』、4で『日本標準時』となります)
2Pacific
Time
3PDT
4Pacific
Daylight
Time
Z1GMT
-08:00
1はGMT(グリニッジ標準時)を使った書式、2はRFC 822
(電子メールに関する規約)の書式になります
(RFC 822のタイムゾーン表記に関しては塚本牧生さんの
サイト『Walrus,Digit.』の『Walrus,Digit./Perlメモ/
RFC#822形式の日時の解析
』を参照してください)
2-800


●AM/PM

国によっては、慣習として日付が24時間フォーマットのみの場合もあり、amとpmの文字列を異なる文字列でローカライズして表す必要があります。

24時間フォーマットの場合使用することはありませんが、テストや例外処理のために必要な場合があります。


●紀元

グレゴリオ暦では『BC』と『AD』の2値だけあります。

これらの値は他の言語の場合に変換することができ、スペイン語の場合は『a.C.』と『d.C.』のようになりますが、グレゴリオ暦では他に紀元はありません。

他のカレンダーには異なる紀元の番号があります。

指定するカレンダーによって、紀元名を変換する必要があります。


●年間週数

年間週数の計算の値は1~53の範囲になります。

週の『1』は1年の最初の週で、その年の最小の数の日にちが含まれています。

1年は1~52週(場合によっては53週)になります。

例えば、1998年1月1日は木曜日でした。

もし週の最初の日が月曜で、最小の日にちが4日の場合(この条件は多くの国の基準としてISO 8601に反映されています)、週の『1』は1997年12月29日から始まり、1998年1月4日で終わりとなります。

しかし、週の最初の日を日曜とした場合、1998年の週の『1』は1998年1月4日から始まって1998年1月10日に終わることになり、1998年の最初の3日間は1998年の『53』週となります。

月間週数も同様に計算されます。


●週の要素

・firstDay

カレンダーの目的のため、週の最初の(頭となる)日を表します。

何故なら、カレンダー間で日にちを変える命令をした場合、この値をキーワードとして使い、例えば『日曜、月曜、・・・』といった値を現在使われているローカライズの名前に置き換えるからです。

・miniDays(Minimal Days in First Week)

年間週数または月間週数で最初の週を求める、最小日にちです。

例えば、最初の週の定義を『最小の日を1日』としてそれを含む週とする場合が、この値は『1』となります。

もし最初の週を『完全に7日間を含む週』と定義したい場合は、この値を『7』とします。

・weekendStart、weekendEnd

週末の開始または終了の曜日と時間を示します。

firstDayと同様に、キーワードの代わりに番号が使用されます。



参考文献

Unicode Technical Standard #35/Locale Data Markup Language/Appendices/Date Format Patterns

Wikipedia/ユリウス暦

Wikipedia/紀元

Wikipedia/ユリウス通日

Wikipedia/夏時間

Wikipedia/グリニッジ標準時

通信用語の基礎知識/RFC 822

arslab's commo/?/julian day

Walrus,Digit./Perlメモ/RFC#822形式の日時の解析

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

クロックでカレンダーを指定する

2010. 05. 25
クロックの作成』で作ったクロックアプリケーションを改造して、カレンダーを設定してみます。

まずNSCalendarクラスについてなのですが、日本語の実例は多いものの概要説明が乏しく、意味不明な訳になってしまったので軽く流すようにしてください。

●NSCalendarクラス

カレンダーは、年の分割や長さ、開始時間といったシステムの計算をし、情報をカプセル化します。

カレンダーとカレンダーの計算のサポート、例えば指定したカレンダーユニットと指定した絶対的な時間に追加したユニットとの範囲を決定する際の情報を提供します。

カレンダーでは、日、週、曜日、月、年を数字で表す際、一般的に1を基礎をとしますが、カレンダー固有の例外があります。

順序を表す数字は1から始まります。

このAPIで表されるいくつかのカレンダーは、基本的な単位の概念として年/月/週/日などを持っています。

例えば、1年を12個の月単位の代わりに、4つの四半期単位で表す事もできます。

カレンダーの計算には、NSDateオブジェクトを連携して使います。

例えば、あるカレンダーと他のカレンダー間で日付を分解して変換する際、最初のカレンダーから使う日付の要素を分解し、その後2つ目のカレンダーを分解して使う必要があります。

NSDateは絶対基準と基準日(参照点)の日付と時刻を提供し、カレンダーの計算やユーザへの表示用に特定のカレンダーに利用することができます。

2つのNSCalendarメソッド、dateFromComponents:とdateByAddingComponents:toDate:options:は、指定されたNSDateComponentsオブジェクトのパラメータから求められたカレンダーの要素を計算し、日付オブジェクトを返します。

貴方が必要とする(または選択できる)多くの要素を提供する事ができます。

不完全な情報で絶対時刻を計算した場合、カレンダーは通常デフォルト値として0と1を選びますが、これはカレンダー特有の選択です。

矛盾する情報を提供する場合は、特定カレンダーの曖昧さ回避を実行してください(これは一つ以上のパラメータを無視して呼び出します)。

関連メソッド(components:fromDate:とcomponents:fromDate:toDate:options:)は、指定した要素をビットマスクパラメータで計算し、NSDateComponentsオブジェクトを返します。

ビットマスクはNSCalendarUnit定数で構成されています。

NSCalendarには、『toll-free bridged』の対象としてCore FoundationのCFCalendar型があります。

これはFoudationオブジェクトを橋渡ししてCore Foundationの型に変換し、関数やメソッドで呼び出せることを意味します。

例えば、NSCalendar *パラメータをメソッドで参照する場合、CFCalendarRefに渡し、CFCalendarRefパラメータとして関数で参照でき、NSCalendarインスタンスに渡す事もできます。

日付型の変換に関する詳細は、『Introduction to Carbon-Cocoa Integration Guide』を参照してください。


●クロックアプリケーションの改造

341

前回同様、クロックアプリケーションのuodateClock:メソッドを改造して、日付表示を和暦にします。
(太字が元のupdateClock:メソッドから追加・修正した部分)

- (void)updateClock:(NSTimer *)theTimer {
    // 現在の日時の取得とフォーマッタの生成
    NSDate *date = [NSDate date];
    NSDateFormatter *form = [[NSDateFormatter alloc] init];

    // 和暦のNSCalendarを生成
    NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSJapaneseCalendar];

    // NSDateFormatterに和暦をセット
    [form setCalendar:cal];


    // 日付の文字列をラベルにセット
    [form setDateFormat:@"GG yy-MM-dd EEE HH:mm"];
    labelDate.text = [form stringFromDate:date];

    // 時刻の文字列をラベルにセット
    [form setDateStyle:NSDateFormatterNoStyle];
    [form setTimeStyle:NSDateFormatterFullStyle];
    labelTime.text = [form stringFromDate:date];

    // インスタンスを破棄
    [cal release];
    [form release];
}


・initWithCalendarIdentifier:
(NSCalendarクラス)

- (id)initWithCalendarIdentifier:(NSString *)string

新規生成されたNSCalendarオブジェクトを、指定された識別子のカレンダーで初期化します

戻り値は初期化されたカレンダー、または識別子が不明な場合はnilを返します
(例えば、認識できない文字列や、現在のOSのバージョンでサポートしていないカレンダーを指定した場合)

string:新しいカレンダーの識別子を指定します


・NSLocale Calendar Keys
(NSLocaleクラス)

NSCalendarインスタンスの識別子定数で、NSLocale.hで定義されています

NSString * const NSGregorianCalendar;
NSString * const NSBuddhistCalendar;
NSString * const NSChineseCalendar;
NSString * const NSHebrewCalendar;
NSString * const NSIslamicCalendar;
NSString * const NSIslamicCivilCalendar;
NSString * const NSJapaneseCalendar;

これらの識別子を使用してNSCalendarオブジェクトの初期化をする場合は、initWithCalendarIdentifier:メソッドを使用してください

・NSGregorianCalendar
グレゴリオ暦の識別子です

343

・NSBuddhistCalendar
仏滅紀元(仏暦)の識別子です

344

・NSChineseCalendar
中国暦(未サポート)の識別子です
注:中国暦はMac OS X v10.4~10.5ではサポートしていません
たとえこの定数を使用してカレンダーを作成しても、オブジェクトが正常に機能しません
(iPhone Simulator 3.1.3で試した時はグレゴリオ暦と同じ結果になりました)

・NSHebrewCalendar
ユダヤ暦の識別子です

345

・NSIslamicCalendar
ヒジュラ暦(イスラム暦)の識別子です

346

・NSIslamicCivilCalendar
イスラム市民歴の識別子です
(太陰暦であるヒジュラ暦は、1年約354日であることから季節とずれるため、現代ではグレゴリオ暦が併用されていると『Wikipedia/ヒジュラ歴』には解説されているのですが、試してみるとグレゴリオ暦ともヒジュラ暦とも異なるため、どういう暦なのかよく分かりません)

347

・NSJapaneseCalendar
日本の暦(和暦)の識別子です

348


・setCalendar:
(NSDateFormatterクラス)

- (void)setCalendar:(NSCalendar *)calendar

レシーバのカレンダーを設定します

calendar:レシーバのカレンダーを指定します


・setDateFormat:
(NSDateFormatterクラス)

- (void)setDateFormat:(NSString *)string

レシーバの日付フォーマット(書式)を設定します

string:レシーバの日付フォーマットを指定します
Data Formatting Programming Guide for Cocoa』の日付フォーマットの許可する変換指定のリストを参照してください
(Mac OS 10.4以降はUnicodeのLocale Data Markup Languageを使用しているということで、『Unicode Technical Standard #35/Locale Data Markup Language/Appendices/Date Format Patterns』にリンクが張られています)



参考文献

NSCalendar Class Reference

NSLocale Class Reference

NSDateFormatter Class Reference

Wikipedia/グレゴリオ暦

Wikipedia/仏滅紀元

Wikipedia/中国暦

Wikipedia/ユダヤ暦

Wikipedia/ヒジュラ歴

Wikipedia/和暦

Unicode Technical Standard #35/Locale Data Markup Language/Appendices/Date Format Patterns

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

クロックでロケールを指定する

2010. 05. 24
クロックの作成』で作ったクロックアプリケーションを改造して、ロケールを設定してみます。

338

ラベルを更新するupdateClock:メソッドに追加・修正を加えます。
(太字が追加・修正した部分)

- (void)updateClock:(NSTimer *)theTimer {
    // 現在の日時の取得とフォーマッタの生成
    NSDate *date = [NSDate date];
    NSDateFormatter *form = [[NSDateFormatter alloc] init];

    // ロケール情報を生成(英語(イギリス)を指定)
    NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];

    // NSDateFormatterにロケール情報をセット
    [form setLocale:locale];

    // 日付の文字列をラベルにセット
    [form setDateStyle:NSDateFormatterFullStyle];
    [form setTimeStyle:NSDateFormatterNoStyle];
    labelDate.text = [form stringFromDate:date];

    // 時刻の文字列をラベルにセット
    [form setDateStyle:NSDateFormatterNoStyle];
    [form setTimeStyle:NSDateFormatterFullStyle];
    labelTime.text = [form stringFromDate:date];

    // インスタンスを破棄
    [locale release];
    [form release];
}

336

時刻の表示スタイルをNSDateFormatterMidiumStyleからNSDateFormatterFullStyleに変えてみました。

元の日本語環境ですと下図のような表示になります。

337


・initWithLocaleIdentifier:
(NSLocaleクラス)

- (id)initWithLocaleIdentifier:(NSString *)string

指定したロケール識別子を使ってレシーバを初期化します

string:新しいロケールの識別子を指定します


・setLocale:
(NSDateFormatterクラス)

- (void)setLocale:(NSLocale *)locale

レシーバのロケールを設定します

locale:レシーバのロケールを指定します


ロケール識別子については『言語環境の書式』を参照してください。


●OSの環境設定に無いロケール識別子の場合

(実機で試していませんが)iPhone Simulatorにおいて、『設定』→『一般』→『言語環境』の一覧に無いロケール識別子を設定しても表示できるようです。

ただし、『クロックのメソッド』の『NSDateFormatterStyle』の項目でも説明していますが、OSのバージョンなどによって表記に違いが出るので注意が必要です。

例えば言語環境設定で、iPhone Simulatorの3.1.3には無いが3.2にはある『ルーマニア語(モルドバ)』のロケール識別子を設定してみます。

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"ro_MD"];

iPhone Simulatorの3.1.3(iPhone)では

339

iPhone Simulatorの3.2(iPad)では

340

と、NSDateFormatterFullStyleのタイムゾーンの表記が異なります。



参考文献

NSLocale Class Reference

NSDateFormatter Class Reference

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

クロックのメソッド

2010. 05. 24
基礎からのiPhone SDK 改訂版』の『クロックの作成』のメソッドを説明します。

●タイマーのメソッド

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch

    timerClock = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateClock:) userInfo:nil repeats:YES];

    [window makeKeyAndVisible];

    return YES;
}

scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:メソッドは『Foundation(タイマー)』で紹介済みでした。

このメソッドは実行ループの中にNSTimerオブジェクトを作成するもので、タイマーの内容は下記のようになっています。

・1.0秒間隔で発火
・self(Clock App Delegate自身)にメッセージを送信
・発火時にupdateClock:メソッドを呼び出し
・メソッドに渡す引数は無し
・リピートはON

発火時のメソッド呼び出しを行う引数は、SEL型という特別な型が使用されています。

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats

SEL型はobjc.hで下記のように定義されています。

typedef struct objc_selector *SEL;

『Objective-C プログラミング言語/Objective-C のランタイム関数とデータ構造体/Objective-C データ型/クラス定義データ構造体/SEL』によると、SEL型はメソッドセレクタを表す構造体で、メセッドセレクタとはメソッドの名前をマップされたC文字列に登録されたものとなっています。

これだけではよく分かりませんが『Mac OS X Cocoaプログラミング(私が持っているのは古い版ですが、参考文献には新しい版を紹介しています)』によると、アプリケーションをコンパイルすると、メソッドは(コンパイラが自動生成する)セレクタテーブルにインデックス付けされるとあります。

つまり各メソッドに番号を割り振り、(コンパイル後にアプリケーション内部で)メソッドを呼び出す時はメソッド名ではなく、割り振ったインデックス番号で呼び出しているということです。

このインデックス番号とメソッドの対応表(objc_selector構造体)が、セレクタテーブルまたはメソッドセレクタと呼ばれるものです。

『@selector()』は『詳解 Objective-C 2.0』によるとコンパイラ指示子で、()内で指定したメソッドにコンパイラが自動で割り振るインデックス番号に置き換えると解釈できます。


●日時の取得と表示のメソッド

- (void)updateClock:(NSTimer *)theTimer {
    // 現在の日時の取得とフォーマッタの生成
    NSDate *date = [NSDate date];
    NSDateFormatter *form = [[NSDateFormatter alloc] init];

    // 日付の文字列をラベルにセット
    [form setDateStyle:NSDateFormatterFullStyle];
    [form setTimeStyle:NSDateFormatterNoStyle];
    labelDate.text = [form stringFromDate:date];

    // 時刻の文字列をラベルにセット
    [form setDateStyle:NSDateFormatterNoStyle];
    [form setTimeStyle:NSDateFormatterMediumStyle];
    labelTime.text = [form stringFromDate:date];

    [form release];
}

※2010.5.24訂正
NSDateFormatterオブジェクトのformを解放する記述が抜けていました。
お詫びして訂正させていただきます。

・現在の日時の取得

ちょっと紛らわしいですが、NSDate型のdateオブジェクトにdateメソッドで取得した現在の日時を入れています。

dateメソッドは『Foundation(日付と時間)』で紹介しています。

ここで取得している現在日時(NSDateオブジェクト)の中身は『クロックの使用しているクラス』の説明していますが、2001年1月1日0時0分0秒(GMT)からの経過秒数になっています。

NSDateのdateメソッドは生成と初期化を兼ねていますが、NSDateFormatterには生成メソッドが無いのでallocで生成し、initメソッドで初期化しています。


・init
(NSDateFormatterクラス)

- (id)init

NSDateFormatterインスタンスを初期化して返します

NSDateFormatterインスタンスを、ロケール、タイムゾーン、カレンダーと動作に適したデフォルト値の設定で初期化します。

10.4-スタイルのdate formatterでは多くの新しい属性が設定可能で、ロケールを含む、タイムゾーン、カレンダー、フォーマット文字列、2桁年表示の相互変換、不確定のコンポーネントに提供するデフォルトの日付と、また月名のような様々な文字列にアクセスできます。

しかし、個々の設定を変更することは推奨されません。

代わりに、適したスタイル定数とsetTimeStyle:、setDateStyle:を使ってフォーマットを指定子、確立されているデフォルト設定での初期化を勧めます。
(これらはシステム環境設定の『言語環境』で設定されます。NSDateFormatterStyleを参照)

特別な考慮事項

Mac OS X 10.4で動作させる場合、クラスのデフォルト動作ではNSDateFormatterBehavior10_4が設定されないので、新しいインスタンスに引数NSDateFormatterBehavior10_4を渡したsetFormatterBehavior:メッセージを送信する必要があります。


・setDateStyle:
(NSDateFormatterクラス)

- (void)setDateStyle:(NSDateFormatterStyle)style

レシーバの日付のスタイルを設定します

style:レシーバの日付スタイルを指定します
指定可能な値はNSDateFormatterStyleを参照してください


・setTimeStyle:
(NSDateFormatterクラス)

- (void)setTimeStyle:(NSDateFormatterStyle)style

レシーバの時刻のスタイルを設定します

style:レシーバの時刻スタイルを指定します
指定可能な値はNSDateFormatterStyleを参照してください


・NSDateFormatterStyle
(NSDateFormatterクラス)

日付と時刻のフォーマットスタイルを、予め定義されている以下の定数で指定します。
NSDateFormatter.hで定義されています。

enum {    // date and time format styles
    NSDateFormatterNoStyle = kCFDateFormatterNoStyle,
    NSDateFormatterShortStyle = kCFDateFormatterShortStyle,
    NSDateFormatterMediumStyle = kCFDateFormatterMediumStyle,
    NSDateFormatterLongStyle = kCFDateFormatterLongStyle,
    NSDateFormatterFullStyle = kCFDateFormatterFullStyle
};
typedef NSUInteger NSDateFormatterStyle;

・NSDateFormatterNoStyle
スタイルを指定しません

・NSDateFormatterShortStyle
短いスタイルで、通常は『11/23/37』や『3:30pm』のような数値のみの指定になります

・NSDateFormatterMediumStyle
中間のスタイルで、通常は『Nov 23, 1937』のような簡略化したテキストの指定になります

・NSDateFormatterLongStyle
長いスタイルで、通常は『November 23, 1937』や『3:30:32pm』のような省略しないテキストの指定になります

・NSDateFormatterFullStyle
完全な詳細を示すフルのスタイルで、『Tuesday, April 12, 1952 AD』や『3:20:42pm PST』のような指定になります

日付と時刻のスタイルのフォーマットはOSのバージョンとユーザの設定が優先され、ロケールに依存するために(ユーザ環境によって設計者の意図を)正確に表現できない場合があります。

(設計者の意図通りの)正確な形式が必要な場合は、これらの定数を使用しないでください。


・stringFromDate:
(NSDateFormatterクラス)

- (NSString *)stringFromDate:(NSDate *)date

レシーバの現在の設定を使用したフォーマットで、指定した日付を文字列で表して返します

date:文字列に表す日付を指定します



参考文献

NSTimer Class Reference

NSDateFormatter Class Reference

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

Mac OS X Cocoaプログラミング 第三版Mac OS X Cocoaプログラミング 第三版
(2009/11/01)
Aaron Hillegass、アーロン ヒレガス 他

商品詳細を見る

詳解 Objective-C 2.0 第3版詳解 Objective-C 2.0 第3版
(2011/12/28)
荻原 剛志

商品詳細を見る

クロックの使用しているクラス

2010. 05. 23
前回作った『基礎からのiPhone SDK 改訂版』の『クロックの作成』に関して、内容を掘り下げたいと思います。

NSObject
    |
    ∟NSDate
    |
    ∟NSFormatter
    |        ∟NSDateFormatter
    |
    ∟NSTimer


●NSTimerクラス

NSTimerクラスは、単純なタイマーやタイマーオブジェクトの生成に使用します。

タイマーは一定時間間隔で待機し、発火すると指定したメッセージをターゲットオブジェクトへ送信します。

例えば、ウィンドウにメッセージを送信するNSTimerオブジェクトを生成し、一定時間間隔で更新を伝えることができます。

タイマーは実行ループと連携して動きます。

タイマーを効果的に利用するには、実行ループの動作を理解している必要があります。
(『NSRunLoop』と『Threading Programming Guide』を参照)

特に、実行ループがタイマーを保持している場合、実行ループに追加したタイマーを後で解放するよう注意してください。

タイマーはリアルタイムの構造ではなく、実行ループモードの時のみ追加したタイマーが実行され、タイマーの発火時間が経過したかチェックをして、過ぎていれば発火します。

通常、実行ループの管理する様々な入力ソースの原因により、タイマーの有効な時間間隔の限界は50~100msecです。

もしタイマーの発火時間間隔より実行ループモードのタイマーの監視期間が長い場合は、実行ループがタイマーをチェックする次の時間まで発火しません。

従って、実際に発火可能な時間間隔で、タイマーの発火時間をスケジュールすることが重要です。

NSTimerオブジェクトには、『toll-free bridged』の対象としてCore FoundationのCFRunLoopTimerRef型があります。

これはFoudationオブジェクトを橋渡ししてCore Foundationの型に変換し、関数やメソッドで呼び出せることを意味します。

例えば、NSTimer *パラメータをメソッドで参照する際、CFRunLoopTimerRefに渡し、CFRunLoopTimerRefパラメータとして関数で参照でき、(コンパイラの警告を抑えるために型変換をして)NSTimerインスタンスに渡すこともできます。

型変換に関する詳細は『Introduction to Carbon-Cocoa Integration Guide』を、Core Foundationについては『CFRunLoopTimer Reference』を参照してください。

リピート対非リピートタイマー

タイマー生成時に、リピートか非リピートかを指定します。

非リピートタイマーの場合、発火は1回のみで自動的に無効になり、以降のタイマーからの発火を防ぎます。

リピートタイマーは対照的に、同じ実行ループ上で自身を再スケジュールして発火します。

リピートタイマーは実際の発火時間と異なり、常に発火時間を自身でスケジュールします。

例えば、タイマー自身が常に5秒間隔で発火するスケジュールを立てても、実際には本来の5秒間隔よりも遅延した間隔で発火します。

発火時間が遅延し、発火時間のスケジュールが1回以上過ぎても、再スケジュールされた次の発火時間でのタイマーの発火は1回のみです。

実行ループでのタイマーのスケジューリング

実行ループ内に複数の実行ループモードが追加されていても、1回の実行ループで登録できるタイマーオブジェクトは1つだけです。

タイマーを生成するには以下の3通りがあります。

・scheduledTimerWithTimeInterval:invocation:repeats:またはscheduledTimerWithTimeInterval:target:selector:userInfo:repeats:クラスメソッドを使用し、デフォルトモードで現在の実行ループにタイマーとスケジュールを生成する。

・timerWithTimeInterval:invocation:repeats:またはtimerWithTimeInterval:target:selector:userInfo:repeats:クラスメソッドを使用して、タイマーオブジェクトの生成と実行ループ外でスケジューリングをする。
(後で、NSRunLoopオブジェクトに対応するaddTimer:forMode:メソッドでタイマーを追加生成し、実行ループで手動で呼び出す必要があります)

・initWithFireDate:interval:target:selector:userInfo:repeats:メソッドを使用して、タイマーの生成と初期化をする。
(生成後、NSRunLoopオブジェクトに対応するaddTimer:forMode:メソッドでタイマーを追加生成し、実行ループで手動で呼び出す必要があります)

実行ループでスケジュールされるのは一度だけで、指定した間隔でタイマーが発火すると次回まで無効になります。

非リピートタイマーは、発火後すぐに自身でタイマーオブジェクトを無効にします。

しかしリピートタイマーは、invalidateメソッドを呼び出してタイマーオブジェクトを無効にする必要があります。

現在の実行ループからタイマーを除去するにはこのメソッドを呼び出せばいいのですが、タイマーを組み込んだ同じスレッドからinvalidateメソッドを常に呼び出す必要があります。

タイマーの無効化は直後のみ使用不可にするためのもので、実行ループで長く作用しません。

invalidateメソッドが戻る直前か少し後の時点で、実行ループはタイマーを除去・解放します。

一度無効にしたタイマーオブジェクトは再利用することはできません。


●NSDateクラス

NSDateオブジェクトは時間の1点を表します。

NSDateはクラスクラスタで、1つのパブリックスーパークラスであり、時間に関する値とプログラムインターフェイスの指定を宣言します。
(クラスクラスタやパブリックスーパークラスに関しては『Cocoa Fundamentals Guide/Cocoaオブジェクト/クラスクラスタ』を参照してください)

NSDateを使って生成したオブジェクトはdateオブジェクトと呼ばれます。

これは不変オブジェクトです。

クラスクラスタという性質のため、NSDateクラスが返すオブジェクトは抽象クラスのインスタンスではなく、プライベートサブクラスのインスタンスになります。

たとえdateオブジェクトのクラスがプライベートであってもインターフェイスはパブリックであり、抽象スーパークラスであるNSDateによって宣言されています。

一般的に、dateオブジェクトをインスタンス化する際には、最適なdate~クラスメソッドが呼び出されます。

NSDateは抽象クラスで、日時の生成、比較、表示や、期間の計算などの機能を提供します。

NSDateはプログラムインターフェイスを通して現在の最適なdateオブジェクトを要求して返します。

NSDateは、不変の時点から現在までの時間を表す、軽量なdateオブジェクトを返します。

このクラスは、任意の暦を表す基礎を提供するように設計されています。

NSDateの唯一の原始的なメソッドはtimeIntervalSinceReferenceDateで、他の全てのNSDateインターフェイスメソッドの基礎を提供します。

このメソッドは2001年1月1日(GMT)を基準とした参照時間を返します。

生成した日付を表す文字列を含み、dateFromString:メソッドやstringFromDate:メソッドを使って、NSdateFormatterのインスタンスの解析に使用してください。
(詳細は『Date Formatting Programming Guide for Cocoa』の『Date Formatters』を参照してください)

NSDateのモデルは1582年10月でユリウス暦からグレゴリオ暦に変更されていて、暦の計算を連携して行うNSCalenderへの変換時に適用されます。

注:ただし、いくつかのロケールではグレゴリオ暦の採用時期が異なっており、例えばイギリスでは1752年9月まで切り替えられていませんでした。

NSDateには、『toll-free bridged』の対象としてCocoa FoundationのCFDate型があります。

これはFoudationオブジェクトを橋渡ししてCore Foundationの型に変換し、関数やメソッドで呼び出せることを意味します。

例えば、NSDate *パラメータをメソッドで参照する際、CFDateRefに渡し、CFDateRefパラメータとして関数で参照でき、(コンパイラの警告を抑えるために型変換をして)NSDateインスタンスに渡すこともできます。

サブクラス化の注意

NSDateのサブクラス化の主な理由は、特定の暦のシステムを操作するのに便利なメソッドのクラスを生成することです。

しかし、例えば日付と時刻の細かい時間の断片を取得するなど、他の理由でNSDateクラスのカスタム化する場合もあります。

メソッドのオーバーライド

プライベートまたはパブリックな、動作の異なるNSDateのサブクラスを作る場合、以下の事を行う必要があります。

・(絶対参照日に関連付けした)日付と時刻の値を保持に適したインスタンス変数の宣言

・正しい日付と時刻の値に基づいたインスタンス変数を提供する、timeIntervalSinceReferenceDateインスタンスメソッドのオーバーライド

・initWithTimeIntervalSinceReferenceDate:をオーバーライドした、指定された初期化メソッド

暦のシステムを表すサブクラスを生成する場合、この暦の単位に分割した過去と未来の期間のメソッドを定義する必要があります。

何故なら、NSDateクラスはNSCopyingとNSCodingのプロトコルを採用しており、サブクラスはこれらのプロトコルを全てのメソッドで実装する必要があるためです。

特別な考慮事項

サブクラスはNSDateの使う絶対参照日(2001年1月1日 GMT)と異なる参照日を使う事ができます。

その場合はメソッドを実装する際に、timeIntervalSinceReferenceDateとinitWithTimeIntervalSinceReferenceDate:を使って絶対参照日を設定します。

この参照日は、メソッドのタイトルの中で参照できる絶対参照日です。

これらのメソッド内で絶対参照日を使用しない場合、生成したサブクラスのNSDateオブジェクトとプライベートサブクラスのNSDateオブジェクトの比較は動作しません。


●NSDateFormatterクラス

NSDateFormatterのインスタンスはNSDate(とNSCalendarDate)オブジェクトの表す文字列を生成し、NSDateオブジェクトの中の日付と時刻を変換して表します。

日付と時刻を、プリセットフォーマットスタイルまたはカスタムフォーマット文字列で柔軟に表現する事ができます。

一般的には、フォーマットスタイル(timeStyledateStyleNSDateFormatterStyleを参照)の使用より、ユーザの好みを反映したスタイルを提供するカスタムフォーマットの文字列の使用を推奨します。

フォーマットスタイルはロケール設定を反映します。

フォーマッタの動作とOSのバージョン

Mac OS X v10.4以降は、NSDateFormatterに2つの動作モード(または動作)があります。

新旧の全動作の説明は、DateFormatter Programming Guide for Cocoaを参照してください。

iPhone OSでの注意:iPhone OSがサポートしているのは、10.4+の動作のみです。
10.0-スタイルのメソッドとフォーマットの文字列はiPhone OSで利用できません。

デフォルトでは、Mac OS X v10.4でもNSDateFormatterのインスタンスは、Mac OS X v10.0から10.3と同じ動作をします。

Mac OS X v10.5以降は、NSDateFormatterのデフォルトは10.4+の動作になります。

(後方互換性のために)古いスタイルのdate formatterを生成する場合は、フォーマッタの初期化にinitWithDateFormat:allowNaturalLanguage:を使います。

新しい動作を使用する場合は、formatterの初期化にinitを使います。

必要な場合、デフォルトのクラスの動作をsetDefaultFormatterBehavior:を使って設定でき、引数にNSDateFormatterBehavior10_4を渡したsetFormatterBehavior:を使ってインスタンスの動作を設定できます。

デフォルトでは、10.4-スタイルのformatterはNSDateオブジェクト(Mac OS X v10.4以前の場合、date formattersはNSCalendarDateオブジェクト)を返します。

この動作はsetGeneratesCalendarDates:を使って変更できますが、(特にMac OS X v10.6以降でのNSCalendarDateは)強く勧めません。



参考文献

NSTimer Class Reference

NSDate Class Reference

NSDateFormatter Class Reference

Cocoa Fundamentals Guide/Cocoaオブジェクト/クラスクラスタ

Wikipedia/グレゴリオ暦

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

クロックの作成

2010. 05. 21
(つい言語環境の話を先にしてしまいましたが)『基礎からのiPhone SDK 改訂版』の本書では日時情報関連のクラスの紹介があって、アプリの制作、改良という流れになっていますが、ウェブブラウザの時と同じく『アプリ制作 → 中身の紹介』とした方が分かり易いかと思うので、先にアプリを作ります。


●サンプルアプリケーションの概要

335

パーツは背景画像と日時を示すラベルが2つのみで、現在日時を取得して表示するだけのシンプルなデジタル時計です。


●プロジェクトの作成

Window-based Applicationテンプレートで、プロジェクト名を『Clock』とします。

321


●nibファイルの編集

・背景画像の設定

今回の背景画像はステータスバー分を考慮して320 x 460ピクセルとし、Background.pngとして用意しました。

Background.pngファイルをプロジェクトのフォルダに入れ、XcodeのResourcesに追加します。

322

次にnibファイル MainWindow.xibをダブルクリックしてInterface Builderを起動します。

Libraryウィンドウからドラッグ&ドロップで、背景画像となるImage VIewと、日付と時刻を表示するLabelを2つ設置します。

LibraryウィンドウからImage Viewをドラッグ&ドロップでViewウィンドウに配置し、InspectorウィンドウのImageでBackground.pngを選択します。

323

・時刻ラベルの設定

本書ではLabelは画面上部に配置していますが、ここでは画面下部に配置します。

Libraryウィンドウからドラッグ&ドロップでLabelを置き、ドラッグでサイズや位置を決めますが、マウス操作では幾分不正確な面もありますので、きっちり設定する場合はInspectorのSizeで確認・補正すると良いでしょう。

ここでは320 x 40の矩形を下端に配置しています。

324

Attributesパネルで文字や背景の設定をします。

LabelのText欄はデフォルトで『Label』と入っていますが、そのまま残しておくとアプリケーション起動時に時刻が表示されるまでの間『Label』と表示されてしまうので、各種設定が済んだら削除しておきましょう。

Layoutはセンタリングし、Fontは好みの種類・サイズにします。
(ここではTimesNewRomanのBold Italic、サイズ24)

Viewは、Backgroundで背景色をWhiteの半透明(90だとアレなので62%に設定)にしました。

325

・日付ラベルの設定

時刻ラベルに重ならないように、320 x 30の矩形をすぐ上に配置します。

326

LabelとViewの設定は、フォントサイズを18にした以外は同じです。

327

これでパーツのレイアウトは完了です。

328

・アウトレットの宣言

Xcodeに戻ってClockAppDelegate.hを開き、時刻・日付ラベルのアウトレットを設定します。
(太字が追加した部分)

#import <UIKit/UIKit.h>

@interface WebAppDelegate : NSObject <UIApplicationDelegate> {
    IBOutlet UILabel *labelDate;    // 日付表示
    IBOutlet UILabel *labelTime;    // 時刻表示

    UIWindow *window;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

329

・アウトレットの接続

ファイルを保存し、Interface BuilderのDocumentウィンドウでClock App Delegateを選択し、InspectorウィンドウのConnectionsパネルのアウトレットをViewウィンドウのラベルに接続します。

330

331

これでインターフェイスの作成は終了です。


●タイマーの作成

・タイマーの宣言

一定時間間隔で、現在時刻を取得しラベルに出力するタイマーを作成します。
(本書では時報用タイマーのオブジェクト宣言も一緒に行っていますが、すぐには利用しないので後で改めて宣言します)

XcodeでClockAppDelegate.hを開き、タイマーオブジェクトを宣言します。
(太字が追加した部分)

#import <UIKit/UIKit.h>

@interface WebAppDelegate : NSObject <UIApplicationDelegate> {
    IBOutlet UILabel *labelDate;    // 日付表示
    IBOutlet UILabel *labelTime;    // 時刻表示
    NSTimer *timerClock;    // 時計更新用タイマー
    UIWindow *window;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

332

・タイマーの実装

例によって、本書ではapplicationDidFinishLaunching:メソッドですが、application:didFinishLaunchingWithOptions:メソッドを使っています。

アプリケーションの起動処理完了後、1秒間隔で作動し、タイマー内部でupdateClock:メソッドを呼び出し、アプリケーション終了まで繰り返します。
(太字が追加した部分)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch

    timerClock = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateClock:) userInfo:nil repeats:YES];

    [window makeKeyAndVisible];

    return YES;
}

333


●日時の取得と表示

最後に現在の日時の取得と表示を行うupdateClock:メソッドを実装します。

- (void)updateClock:(NSTimer *)theTimer {
    // 現在の日時の取得とフォーマッタの生成
    NSDate *date = [NSDate date];
    NSDateFormatter *form = [[NSDateFormatter alloc] init];

    // 日付の文字列をラベルにセット
    [form setDateStyle:NSDateFormatterFullStyle];
    [form setTimeStyle:NSDateFormatterNoStyle];
    labelDate.text = [form stringFromDate:date];

    // 時刻の文字列をラベルにセット
    [form setDateStyle:NSDateFormatterNoStyle];
    [form setTimeStyle:NSDateFormatterMediumStyle];
    labelTime.text = [form stringFromDate:date];

    [form release];
}

※2010.5.24訂正
NSDateFormatterオブジェクトのformを解放する記述が抜けていました。
お詫びして訂正させていただきます。

334

現在の日時をNSDateクラスのdateメソッドで取得し、ラベルに表示するフォーマット(書式)をNSDateFormatterクラスのオブジェクトformで設定し、ラベルに出力しています。


●ビルドと実行

ビルドして実行するとあることに気付きます。

335

環境設定で書式を日本に設定していると、ラベル表示も日本語になります。

Times New Romanフォントは日本語に対応していませんので、非対応の文字はデフォルトの『ヒラギノ角ゴ Pro N W6』に置き換えられています。

本書ではこの後ロケールの変更やアラームの設定などありますが、ここまでの分を解説してから機能の追加を追って説明します。



参考文献

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

言語環境の書式

2010. 05. 21
●書式

iPhone OSの『設定』→『一般』→『言語環境』から設定できる『書式』は下図の通りです。

316

iPhone Simulator 3.1.3は下図のようになります。

318

iPhone Simulator 3.2(iPad)では下図のようになります。

320

英語やドイツ語などは国を選択するサブテーブルがありますが、キャプチャは端折っています。
(下表には全部入れています)

ロケール識別子は、nakamura001さんのサイト『強火で進め』の『[iPhoneプログラミング]iPhoneの言語設定関連の情報取得についての解説』のコードをお借りして1個1個調べました。
(ブログの字数制限の都合上、『○』をセンタリングできなかったのはご容赦ください)

言語ロケール識別子iPhone
デバイス
Simulator
3.1.3
Simulator
3.2
アイスランド語(アイスランド)is_IS
アイルランド語(アイルランド)ga_IE
アゼルバイ
ジャン語
アゼルバイジャン(キリル文字)az-Cyrl_AZ  
アゼルバイジャン(ラテン文字)az-Latn_AZ  
アッサム語(インド)as_IN  
アフリカ
ーンス語
ナミビアaf_NA
南アフリカaf_ZA
アムハラ語(エチオピア)am_ET  
アラビア語アラブ首長国連邦ar_AE
アルジェリアar_DZ
イエメンar_YE
イラクar_IQ
エジプトar_EG
オマーンar_OM
カタールar_QA
クウェートar_KW
サウジアラビアar_SA
シリアar_SY
スーダンar_SD
チュニジアar_TN
バーレーンar_BH
モロッコar_MA
ヨルダンar_JO
リビアar_LY
レバノンar_LB
アルバニア語(アルバニア)sq_AL  
アルメニア語アルメニアhy_AM  
アルメニア(改訂版)hy_AM_REVISED  
イタリア語イタリアit_IT
スイスit_CH
インドネシア語(インドネシア)id_ID
ウェールズ語(イギリス)cy_GB
ウクライナ語(ウクライナ)uk_UA
ウズベク語アフガニスタン(アラビア文字)uz-Arab_AF  
ウズベキスタン(キリル文字)uz-Cyrl_UZ  
ウズベキスタン(ラテン文字)uz-Latn_UZ  
ウルドゥー語インドur_IN
パキスタンur_PK
エストニア語(エストニア)et_EE
エスペラント語eo  
オランダ語オランダnl_NL
ベルギーnl_BE
オリヤー語(インド)or_IN  
オロモ語エチオピアom_ET
ケニアom_KE
カザフ語(カザフスタン)kk_KZ  
カタロニア語(スペイン)ca_ES
ガリシア語(スペイン)gl_ES
カンナダ語(インド)kn_IN  
ギリシャ語キプロスel_CY
ギリシャel_GR
グジャラート語(インド)gu_IN
クメール語(カンボジア)km_KH  
グリーンランド語(グリーンランド)kl_GL  
グルジア語(グルジア)ka_GE  
クロアチア語(クロアチア)hr_HR
コーンウォール語(イギリス)kw_GB
コンカニ語(インド)kok_IN
シンハラ語(スリランカ)si_LK  
スウェーデン語スウェーデンsv_SE
フィンランドsv_FI
スペイン語アメリカ合衆国es_US
アルゼンチンes_AR
ウルグアイes_UY
エクアドルes_EC
エルサルバドルes_SV
グアテマラes_GT
コスタリカes_CR
コロンビアes_CO
スペインes_ES
チリes_CL
ドミニカ共和国es_DO
ニカラグアes_NI
パナマes_PA
パラグアイes_PY
プエルトリコes_PR
ベネズエラes_VE
ペルーes_PE
ボリビアes_BO
ホンジュラスes_HN
メキシコes_MX
スロバキア語(スロバキア)sk_SK
スロベニア語(スロベニア)sl_SI 
スワヒリ語ケニアsw_KE
タンザニアsw_TZ
セルビア語セルビア(キリル文字)sr-Cyrl_RS
セルビア(ラテン文字)sr-Latn_RS
ボスニア・ヘルツェゴビナ
(キリル文字)
sr-Cyrl_BA
ボスニア・ヘルツェゴビナ
(ラテン文字)
sr-Latn_BA
モンテネグロ(キリル文字)sr-Cyrl_ME
モンテネグロ(ラテン文字)sr-Latn_ME
ソマリ語エチオピアso_ET
ケニアso_KE
ジブチso_DJ
ソマリアso_SO
タイ語(タイ)th_TH@calendar
=gregorian
タミール語(インド)ta_IN
チェコ語(チェコ共和国)cs_CZ
ティグリニア語エチオピアti_ET  
エリトリアti_ER  
テルグ語(インド)te_IN  
デンマーク語(デンマーク)da_DK
ドイツ語オーストリアde_AT
スイスde_CH
ドイツde_DE
ベルギーde_BE
リヒテンシュタインde_LI
ルクセンブルグde_LU
トルコ語(トルコ)tr_TR
ネパール語インドne_IN  
ネパールne_NP  
ノルウェー語(ニーノシュク)(ノルウェー)nn_NO  
ノルウェー語(ブークモール)(ノルウェー)nb_NO
ハウサ語(ナイジェリア(ラテン文字))ha-Latn_NG  
パシュトゥー語(アフガニスタン)ps_AF  
バスク語(スペイン)eu_ES
ハワイ語(アメリカ合衆国)haw_US
ハンガリー語(ハンガリー)hu_HU
パンジャブ語インドpa_IN
パキスタン(アラビア文字)pa-Arab_PK
ヒンディー語(インド)hi_IN
フィンランド語(フィンランド)fi_FI
フェロー語(フェロー諸島)fo_FO  
フランス語カナダfr_CA
スイスfr_CH
セネガルfr_SN
フランスfr_FR
ベルギーfr_BE
モナコfr_MC
ルクセンブルグfr_LU
ブルガリア語(ブルガリア)bg_BG
ベトナム語(ベトナム)vi_VN
ヘブライ語(イスラエル)he_IL
ベラルーシ語(ベラルーシ)be_BY  
ペルシア語アフガニスタン(アラビア文字)fa_AF  
イランfa_IR  
ベンガル語インドbn_IN  
バングラデシュbn_BD  
ポーランド語(ポーランド)pl_PL
ポルトガル語ブラジルpt_BR
ポルトガルpt_PT
マケドニア語(マケドニア)mk_MK
マラーティー語(インド)mr_IN
マラヤーラム語(インド)ml_IN  
マルタ語(マルタ)mt_MT
マレー語ブルネイms_BN
マレーシアms_MY
マン島語(イギリス)gv_GB
ラトビア語(ラトビア)lv_LV
リトアニア語(リトアニア)lt_LT
ルーマニア語モルドバro_MD  
ルーマニアro_RO
ロシア語ウクライナru_UA
ロシアru_RU
英語アイルランドen_IE
アメリカ合衆国en_US
アメリカ領ヴァージン諸島en_VI
イギリスen_GB
インドen_IN
オーストラリアen_AU
カナダen_CA
ジャマイカen_JM
シンガポールen_SG
ジンバブエen_ZW
トリニダード・トバゴen_TT
ナミビアen_NA
ニュージーランドen_NZ
パキスタンen_PK
フィリピンen_PH
ベリーズen_BZ
ベルギーen_BE
ボツワナen_BW
マーシャル諸島共和国en_MH
マルタen_MT
中華人民共和国
香港特別行政区
en_HK
南アフリカen_ZA
韓国語(大韓民国)ko_KR
四川イ語(中国)ii_CN  
中国語シンガポールzh_SG
台湾zh_TW
中華人民共和国
マカオ特別行政区
zh_MO
中華人民共和国
マカオ特別行政区(簡体字)
zh-Hans_MO
中華人民共和国
香港特別行政区
zh_HK
中華人民共和国
香港特別行政区(簡体字)
zh-Hans_HK
中国zh_CN
日本ja_JP

『言語』とはカバーしている傾向が異なりますが、『書式』もデバイス、Simulatorのバージョンで対応言語が異なりますのでご注意ください。



参考文献

Wikipedia/IETF言語タグ

TUTORIALS POINT/Language Codes: ISO 639

強火で進め/[iPhoneプログラミング]iPhoneの言語設定関連の情報取得についての解説

NSLocale Class Reference

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

言語環境の言語

2010. 05. 21
そもそもiPhone OSの『設定』における『言語』と『書式』の守備範囲がどうなっているのか判然としていなかったのですが、nakamura001さんのサイト『強火で進め』の『[iPhoneプログラミング]iPhoneの言語設定関連の情報取得についての解説』でなんとなく見えてきました。

『言語』はホーム画面の表記やローカライズファイルを持つアプリへ渡す設定で、『書式』は日時や電話番号を表示する書式の設定ということです。

ただし上記サイトによると、『書式設定は言語設定より強い』ようなので注意が必要です。


●動作確認環境

現在、私が使用している環境はXcode 3.2.2 and iPhone SDK 3.2、今年4月3日に公開されたBuild10M2148で、正式リリースされているものでは現時点で最新版です。

デバイスのiPhoneのOSは3.1.3(7E18)、iPhone SimulatorもiPhone用は3.1.3で、3.2はiPad用となっています。

この説明を前置きした理由は、各言語環境に差異があるためです。

デバイスはiPhone実機の、SimulatorはMac OSの環境を拾っているせいかとも思ったのですが、それだとSimulatorの3.1.3と3.2の違いが説明できないので、取り敢えず現状を報告します。


●言語

iPhone OSの『設定』→『一般』→『言語環境』から設定できる『言語』は、Script.hで定義されている言語全てに対応しているわけではありませんが、実機デバイスとiPhone Simulatorで対応する言語が一部異なるので注意が必要です。

iPhoneデバイスの言語は下図の通りです。

315

iPhone Simulator 3.1.3は下図のようになります。

317

iPhone Simulator 3.2(iPad)では下図のようになります。

319

上半分ぐらいは分からなくもないですが、下の方はどの言語か分からないので困っていましたが、冒頭にも紹介したnakamura001さんのサイトの『[iPhoneプログラミング]iPhoneの言語設定関連の情報取得についての解説』に言語を取得するコードが載っていましたので、ありがたくお借りしてことなきを得ました。

一覧表にすると下表のようになります。

言語言語コードiPhone
デバイス
Simulator
3.1.3
Simulator
3.2
日本語ja
英語en
フランス語fr
ドイツ語de
オランダ語nl
イタリア語it
スペイン語es
ポルトガル語pt 
ポルトガル語(ポルトガル)pt-PT 
デンマーク語da 
フィンランド語fi 
ノルウェー語(ブークモール)nb 
スウェーデン語sv 
韓国語ko 
中国語(簡体字)Zh-Hans
中国語(繁体字)Zh-Hant 
ロシア語ru
ポーランド語pl 
トルコ語tr 
ウクライナ語uk 
アラビア語ar 
クロアチア語hr 
チェコ語cs 
ギリシャ語el 
ヘブライ語he 
ルーマニア語ro 
スロバキア語sk 
タイ語th 
インドネシア語id 
マレー語ms  

しかし取得したコードの一部(ポルトガル語(ポルトガル)と中国語2種)は、ISO 639の規定とは異なります。
(『国名コード』との組み合わせでもありません)

取得に使ったメソッドpreferredLanguagesを見てみると、IETF BCP 474という(ISO 639を取り込んでいる別の)規定の識別子を得ているようです。



参考文献

Wikipedia/IETF言語タグ

TUTORIALS POINT/Language Codes: ISO 639

強火で進め/[iPhoneプログラミング]iPhoneの言語設定関連の情報取得についての解説

NSLocale Class Reference

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る






bose_soundlink_revolve
Calendar
04 | 2010/05 | 06
Sun Mon Tue Wed Thu Fri Sat
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

bose_soundlink_revolve
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR