☆Cocoa Touch UIKit勉強(6)
デバイス情報;UIDevice
UIDeviceは、デバイス、すなわちiPadやらiPhoneやらの装置情報を得るクラスである。 iPad/iPhone両用のいわゆる「ユニバーサルアプリ」を作る場合や、 iOSのバージョンによって処理を変える場合に、これらの情報によって処理を分ける。
UIDevice
プロパティ名属性動作
NSString *model RTモデル名
(少なくとも)以下の名称がある。
@"iPad"
@"iPhone"
@"iPod touch"
@"iPhone Simulator"
NSString systemVersion RTデバイスで稼動しているOSのバージョンを取得する
NSString systemName RTデバイスで稼動しているOS名を取得する
NSString uniqueIdentifier RTデバイスのIDを取得する
NSString *localizedModel RTデバイスのローカライズされた文字列でのモデル
NSString *name RT「設定」~「一般」~「情報」で得られる任意の英数字文字列
UIDeviceOrientation orientation Rデバイスの向きを取得する
使うには、先にbeginGeneratingDeviceOrientationNotificationsを呼び出しておく必要がある。
UIDeviceOrientation(enum値)
UIDeviceOrientationUnknown=0 向きが分からない(未初期化時も含む)
UIDeviceOrientationPortrait デバイス縦状態(ホームボタンが下)
UIDeviceOrientationPortraitUpsideDownデバイス縦逆状態(ホームボタンが上)
UIDeviceOrientationLandscapeLeft デバイス左横状態(ホームボタン左)
UIDeviceOrientationLandscapeRight デバイス右横状態(ホームボタン右)
UIDeviceOrientationFaceUp デバイス仰向け
UIDeviceOrientationFaceDown デバイスうつ伏せ
BOOL batteryMonitoringEnabled G=isBatteryMonitoringEnabled バッテリーの残量を監視するかどうかを設定
float batteryLevel Rバッテリー残量を取得する
batteryMonitoringEnabled=YESが必須
0.0=空~1.0=フル充電
UIDeviceBatteryState batteryStateRバッテリーの充電状態を取得する
UIDeviceBatteryState(enum値)
UIDeviceBatteryStateUnplugged 充電中ではない状態
UIDeviceBatteryStateCharging 充電中状態
UIDeviceBatteryStateFull 満タン状態
UIDeviceBatteryStateUnknown 充電状態が不明の状態
batteryMonitoringEnabled=YESが必須
BOOL proximityMonitoringEnabled G=isProximityMonitoringEnabled近接センサー設定
iPhoneのみだと思われる
BOOL proximityState R近接センサーの設定状態を取得する
BOOL generatesDeviceOrientationNotificationsRG=isGeneratingDeviceOrientationNotifications 加速度系が使えるかどうかを取得する
UIUserInterfaceIdiom userInterfaceIdiomRiPhoneかiPadかを調べる
UIUserInterfaceIdiom(enum値)
UIUserInterfaceIdiomPhone iPhone/iPod touch
UIUserInterfaceIdiomPad iPad

メソッド名動作
+(UIDevice *)currentDeviceインスタンスを取得する
-(void)beginGeneratingDeviceOrientationNotifications加速度(回転検出も含む)を利用可能にする
-(void)endGeneratingDeviceOrientationNotifications加速度系の利用を終了する

こんな感じで使う。
    // 実行中のデバイス種別を得る
    NSString *modelname=[[UIDevice currentDevice]model];
    NSLog(@"model=%@",modelname);

画面サイズ;UIScreen
UIScreenは、画面サイズを取得するクラスである。
UIScreen
プロパティ名属性動作
CGRect applicationFrameR ステータスバー領域を含まない画面サイズを返す
CGRect bounds R ステータスバー領域を含む画面サイズを返す
NSArray *availableModesRC サポートされている画面モードを、要素がUIScreenModeの配列で返す
CGFloat scale R 論理座標から表示座標へ変換する際の割合を取得する
UIScreenMode *currentModeT現在の画面モードを返す
UIScreenMode(クラス)
プロパティ名属性動作
CGSize sizeR画像サイズを画素(ピクセル)数で得る
CGFloat pixelAspectRatioR1画素のアスペクト比(縦横比)を得る

    CGRect cr = [[UIScreen mainScreen] applicationFrame];
    CGRect cr = [[UIScreen mainScreen] bounds];
メソッド名動作
+(UIScreen *)mainScreen メイン画面のインスタンスを取得する
+(NSArray *)screens つながっている画面情報を配列で取得する

scaleはちょっとわかりにくいが、レティナディスプレイ対応が主な目的だと思う。 説明には以下のように書いてある(かなり意訳)。 UIDeviceには機種取得のプロパティがあるけど、それで機種判別して画面サイズや持っているデバイスなどを決め打ちしてはいけない ということだ。
今はiPhoneでもレティナディスプレイがあるし、将来大小画面のiPadが出てくる可能性もある。 というか、実際iPhone/iPod touch5では画面サイズが変わった。 新機種が出たときは出たときでバージョンアップをすればいいのかもしれないが、 最初から考慮しておくに越したことはない。 とか言いながら、自作アプリでもできてないんだけど(^_^;)

screensというメソッドがあるが、「iOSデバイスは1画面だけじゃないのか?」と思うかもしれない。 確かにデバイスが直接持つのは1画面だけなのだが、iPadではVGAモニタに出力できるアダプタが発売されている。 実はこのアダプタの先の画面は内蔵画面とは別のスクリーンだと認識される。マルチスクリーンなのだ。 内蔵スクリーンのデータをハード的に垂れ流している(スキャンコンバートしている)わけではない。 「VGA出力は対応ソフトのみ」というのはそういう理由である。 なぜアップルがそういう構造にしたのかは不明であるが。
ということは、VGA出力対応させるには、ソフト側にもそれなりの処理の追加が必要となる。 基本的な方法は以下の通りらしい。
  1. つながっているスクリーンを[UIScreen screens]がNSArrayで取得する
  2. そこから使いたいUIScreenModeを取得する
  3. 外部出力用UIScreenを取得する
  4. 取得したUIScreenのcurrentModeに2.で取得した内容を設定する
  5. 表示させたいコンテンツを作成する
  6. 外部出力させるためにUIWindowを作る
  7. 6.に表示させたいコンテンツをaddSubView: する
  8. window.screen に3.のUIScreenを設定する
  9. windowの基礎的な設定を行う
// ↓画面情報を得るプログラム

NSMutableString *str = [[NSMutableString alloc] init]; // 表示用可変文字列を用意
UIScreenMode *current = nil; // 設定されるスクリーンモードを得る変数を用意
int i,j; // カウンター

// 画面情報を配列に入れる(複数画面の場合、画面別)
NSArray *scrn;
[scrn initWithArray:[UIScreen screens]];

NSEnumerator *enumerator1 = [scrn objectEnumerator]; // 列挙を用意
i=0;
while (id sc = [enumerator1 nextObject]) {
    // それぞれの画面の持つ画面モードを配列に入れる
    NSArray *scrn2;
    [scrn2 initWithArray:[sc availableModes]];
    NSEnumerator *enumerator2 = [scrn2 objectEnumerator]; // 列挙を用意

    // checking each screen mode in screen.
    j=0;
    UIScreenMode *curMode;
    while (curMode = [enumerator2 nextObject]) {
        // 
        // get information of screen.
        NSString *sstr = [NSString stringWithFormat:@"画面:%i, モード:%i, 幅:%f,高さ:%f,アスペクト比:%f ---"
                                                    , i
                                                    , j++
                                                    , current.size.width
                                                    , current.size.height
                                                    , current.pixelAspectRatio];
        [str appendString:sstr]; // 文字列結合

        // 一番幅広の画面を探す
        if (curMode.size.width > current.size.width) {
            current = curMode;
        }
    }
    i++;
}
// ↓表示する部分

    // スクリーンオブジェクトの作成
    UIScreen *another = [scrn objectAtIndex:1];
    another.currentMode = current; // ここの場合、一番幅広画面を設定
    CGSize size = current.size;
    uvc = [[UIViewController alloc] init];

    // 新規ウインドウの作成してコンテントビューを置く
    CGRect frame;
    frame=CGRectMake(0.0f,0.0f,size.width,size.height); // 画面幅
    UIWindow *window = [[UIWindow alloc] initWithContentRect:frame];
    UIView   *uvc    = [[[UIView  alloc] initWithFrame:frame] autorelease];
    window.screen = another; // カレント画面を変更
    [window setContentView:uvc];
    // テキストビューを乗せる(全画面)
    UITextView *tv = [[UITextView alloc] initWithFrame:frame];
    [uvc addSubview:tv];
    // 表示文字列設定
    tv.text = str;
    [tv release];

    // ウインドウの表示
    [window orderFront:self];


フォント;UIFont
フォントを作るのはUIFontクラス。ただし、これは「フォントの属性を作るだけ」なので、 実際の表示文字列それを適応するのはUITextViewなどのクラスである。
UIFont
プロパティ名属性内容
NSString *familyNameRTフォントファミリ名
NSString *fontName RTフォント名
CGFloat pointSize R ポイント数(復号属性の時はその合成値)
CGFloat capHeight R 大文字の文字高さ(ポイント数)
CGFloat lineHeight R テキスト行の高さ(ポイント数)
CGFloat ascender R ベースラインから最も上に出るフォントのy座標
CGFloat descender R ベースラインから最も下に出るフォントのy座標
CGFloat xHeight R "x"(小文字)の高さ(ポイント数)
iOS6で使えるフォンについてはここ参照。 X-BASIC for iOSで調べたもの。

メソッド名動作
+(UIFont*)fontWithName: (CGFloat)size:指定名称、サイズを返すUIFont *font = [UIFont fontWithName:@"フォント名" size:20];
+(CGFloat)systemFontSize標準サイズを返すUIFont *font =[UIFont systemFontOfSize:[UIFont systemFontSize]];
+(UIFont*)systemFontOfSize: (CGFloat)fontSize指定サイズの標準フォントを返すUIFont *font = [UIFont systemFontOfSize:20];
+(UIFont*)boldSystemFontOfSize: (CGFloat)fontSize指定サイズの太字フォントを返すUIFont *font = [UIFont boldSystemFontOfSize:20];
+(UIFont*)italicSystemFontOfSize: (CGFloat)fontSize指定サイズの斜体フォントを返すUIFont *font = [UIFont italicSystemFontOfSize:20];
+(CGFloat)smallSystemFontSize標準サイズよりも小さめのサイズを返すUIFont *font =[UIFont systemFontOfSize:[UIFont smallSystemFontSize]];
+(CGFloat)labelFontSizeラベルで使用される標準的なサイズを返すUIFont *font =[UIFont systemFontOfSize:[UIFont labelFontSize]];
+(CGFloat)buttonFontSizeボタンで使用される標準的なサイズを返すUIFont *font =[UIFont systemFontOfSize:[UIFont buttonFontSize]];
+(NSArray*)familyNames使用できるフォントファミリー名を返すNSArray *arr = [UIFont familyNames];


色;UIColor
色を作るのはUIColorクラス。ただし、これは「色情報を作るだけ」なので、 実際の表示にそれを適応するのはUITextView/UIViewなどのクラスである。
UIColorは全てクラスメソッドなので、UIColorを引数をする場合、必ず[UIColor ~]と記述する必要がある。
UIColor
メソッド名動作
+(UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha色を合成する
+(UIColor *)colorWithPatternImage:(UIImage *)image画像から色を取得する
+(UIColor *)blackColor
+(UIColor *)darkGrayColor
+(UIColor *)lightGrayColor
+(UIColor *)whiteColor
+(UIColor *)grayColor
+(UIColor *)redColor
+(UIColor *)greenColor
+(UIColor *)blueColor
+(UIColor *)cyanColor
+(UIColor *)yellowColor
+(UIColor *)magentaColor
+(UIColor *)orangeColor
+(UIColor *)purpleColor
+(UIColor *)brownColor
+(UIColor *)clearColor
定義済みの色を得る
+(UIColor *)lightTextColor
+(UIColor *)darkTextColor
+(UIColor *)groupTableViewBackgroundColor
+(UIColor *)viewFlipsideBackgroundColor
+(UIColor *)scrollViewTexturedBackgroundColor
定義済みのパターンを得る


加速度計;UIAccelerometer/UIAcceleration
加速度計はiPadやiPhoneに内蔵されている。1つしかないデバイスなので「共有」と書かれている。 要するに、クラスインスタンスを確保したプログラムがその利用権を得る事になる。
UIAccelerometer
メソッド名動作
+(UIAccelerometer *)sharedAccelerometer(共有)加速度計オブジェクトを返す

プロパティ名属性内容
id <UIAccelerometerDelegate> delegateSデリゲートを設定する
NSTimeInterval updateInterval 加速度計からデリゲートへのデータ送信間隔を設定する

UIAcceleration
プロパティ名属性内容
NSTimeInterval timestampR加速イベントが発生した相対時間
UIAccelerationValue xRx軸の値
UIAccelerationValue yRy軸の値
UIAccelerationValue zRz軸の値
UIAccelerationValueはdouble型。x,y,zの各軸の方向は

デバイスをポートレイト方向に立てて、左(-)右(+)がx、上(+)下(-)がy、前(+)奥(-)がz軸となる。

UIAccelerometerのデリゲートは UIAccelerometerDelegateプロトコルに準拠している必要がある。設定した周期でこのデリゲートメソッドが呼び出される。
メソッド名動作
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration 最新の加速で度データを得る
// 加速度センサーを有効にする。
// 更新頻度は秒15回
    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0 / 15.0];
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];
// setUpdateInterval/setDelegateはプロパティへのsetter。

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    NSLog(@"x:%f y:%f z:%f",acceleration.x y:acceleration.y z:acceleration.z);
}

モーション;CMMotionManager
CMMotionManager は本体の向きの取得するクラスである。 3軸加速度計の値を取得している。 画面の回転も内部ではこれを使っているはずである。
先の加速度計とモーションは基本的に同じ・・・だと思う。 データの受信仕方がデリゲートかブロックによる直接指定かの違いだけだと思う。 私はこちら側しか使ったことが無い。

説明よりプログラムを載せる。
#import <CoreMotion/CoreMotion.h>

enum { // データ源番号(dno)
    MOTION_DEGREE   =0, // 角度
    MOTION_VELOCITY,    // 角速度
    MOTION_EULER,       // オイラー角
};

@interface MotionControl : NSObject
{
    CMMotionManager     *motionManager;
    NSOperationQueue    *opQueueMotion;

    BOOL                fpause;     // サンプリング一時停止フラグ
    NSUInteger          dno;        // データ源番号
}

-(id)init
{
    self=[super init];
    if (self!=nil) {
        // CMMotionManager生成
        opQueueMotion=nil; // サンプリングはまだ開始しない
        motionManager  =[[CMMotionManager alloc]init];
    }
    return(self);
}

-(void)dealloc
{
    [motionManager stopDeviceMotionUpdates];

    [opQueueMotion release];
    [motionManager release];
}
-(void)startSampling:(NSTimeInterval)interval
// サンプリング処理設定
{
    opQueueMotion = [[NSOperationQueue alloc]init];
    
    // デバイスモーション取得間隔 [sec]
    motionManager.deviceMotionUpdateInterval = interval; // サンプリング間隔(秒)
    
    // デバイスモーション取得
    [motionManager startDeviceMotionUpdatesToQueue:opQueueMotion
            withHandler:^(CMDeviceMotion *data, NSError *error) {
                dispatch_async(dispatch_get_main_queue(),
                    ^{
                        if (!fpause) {
                            CMRotationRate xyz;
                            CMAcceleration axyz;
                            switch (dno) {
                                case MOTION_DEGREE: 
                                    // 角度
                                    axyz=data.gravity; // CMDeviceMotionはクラス,CMAccelerationは構造体なので取り出しが必要
                                    { /// 数値変換 : -90〜90度
                                    axyz.x*=90.0;
                                    axyz.y*=90.0;
                                    axyz.z*=90.0;
                                    }
                                    ~データ保存はここで~
                                    // 本来CMAcceleration*だが、内容が同じなので型キャストで渡す
                                    break;
                                case MOTION_VELOCITY:
                                    // 角速度(ラジアン/秒)
                                    xyz=data.rotationRate; // CMDeviceMotionはクラス,CMRotationRateは構造体なので取り出しが必要
                                    ~データ保存はここで~
                                    break;
                                case MOTION_EULER:
                                    // オイラー角
                                    xyz.x=data.attitude.roll;   // ロール角(ラジアン)
                                    xyz.y=data.attitude.pitch;  // ピッチ角(ラジアン)
                                    xyz.z=data.attitude.yaw;    // ヨー角(ラジアン)
                                    { /// 数値変換 : -90〜90度
                                    xyz.x*=(180.0/M_PI); // 本当はf=90*x*2/π
                                    xyz.y*=(180.0/M_PI);
                                    xyz.z*=(180.0/M_PI);
                                    }
                                    ~データ保存はここで~
                                    break;
                            }
                        } // 一時停止中は無視
                    } // ^{
                ); // dispatch_async
            } // withHandler
     ];
}
なお、当然のことながらこれは実機でしか実行出来ない。というか、実機出ないとデータが更新されないので デバッグにならない。
コンパス;CLLocationManager
CLLocationManagerは電子コンパスを扱うクラスである。
正確には地磁気の強さを計測しているようである。
以下のようなことが出来る。 iPod touchには電子コンパスがない。これがiPhoneとiPod touchの電話以外の一番の違いである。 従って、利用前にはメソッドにより「使えるか」確認しておく必要がある。
また、重要なことだが、利用出来るハードでも、 ユーザーには位置情報取得サービスを使うかどうかの選択権がある (位置情報を使うアプリでは、利用前に必ず確認を求めてくる)。 利用するときは、位置情報サービスを利用するかどうかをユーザーに確認するプロンプトを出す。 許可しない場合は、CLLocationManagerオブジェクトは以降の呼び出しで、適切なエラーをデリゲートに報告する。

CLLocationManagerのサービスを利用するときには、プロパティによる設定が必要である。 CLLocationManagerは不要なときは関連回路の電源を切る。 また、精度を下げれば省電力になる(こともある)。

という前書きを下後で、使い方の実際。 まずは、クラス宣言。
#import <CoreLocation/CoreLocation.h>

@interface Compass : NSObject
<CLLocationManagerDelegate>
{
    // データ取得
    CLLocationManager   *locationManager;
}
以下の初期化処理はメインスレッドで実行しなければならない。 そうしないと、後のデリゲートが呼び出されない
-(BOOL)startMain
// 方位情報初期化
{
    NSLog(@"startMain");
    
    locationManager=[[CLLocationManager alloc]init];
    locationManager.delegate=self;
    
    // 真北を基準にしたヘディングを取得する位置情報サービスを開始する(らしい)
    locationManager.distanceFilter=1000;
    locationManager.desiredAccuracy=kCLLocationAccuracyKilometer;
    [locationManager startUpdatingLocation];
    
    // ヘディングの更新を開始する(らしい)
    NSLog(@"方位取得開始");
    locationManager.headingFilter=1; // これ以上の角度変化があった時にイベントが発生する
    [locationManager startUpdatingHeading];
    //
    if ([CLLocationManager headingAvailable] && [CLLocationManager locationServicesEnabled]) {
        // 方位情報初期化
        // メインスレッドでないとだめらしい
        [self performSelectorOnMainThread:@selector(startMain) withObject:nil waitUntilDone:YES];
    } else {
        NSLog(@"方位取得が使えない");
        return (YES);
    }
    return (NO);
}
終了処理。
-(void)end
{
    if (locationManager!=nil) {
        [locationManager stopUpdatingHeading];
        [locationManager release];
        locationManager=nil;
    }
}
以下はデリゲート。
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"方位取得エラー:%@",error);
    // データは記録しない
}

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
// 方位情報取得(デリゲート)
{
    NSLog(@"取得時間:%@",manager.location.timestamp);
    
    if (newHeading.headingAccuracy<0) {
        NSLog(@"正しい値が取得できていない");
        // なので、記録しない
    } else {
        // 方角としての真北に対するする向き(度単位)
        NSLog(@"角度:%f", newHeading.trueHeading);
        // 磁北に対するする向き(度単位)
        NSLog(@"磁北角度:%f", newHeading.magneticHeading);
        //
        // X軸の磁束密度(マイクロテスラ単位)
        NSLog(@"X軸の磁束密度:%f", newHeading.x);
        // Y軸の磁束密度(マイクロテスラ単位)
        NSLog(@"Y軸の磁束密度:%f", newHeading.y);
        // Z軸の磁束密度(マイクロテスラ単位)
        NSLog(@"Z軸の磁束密度:%f", newHeading.z);
        //
        ~ここでデータ保存をする~
    }
}
なお、当然のことながらこれも実機でしか実行出来ない。というか、実機出ないとデータが更新されないので デバッグにならない。

ドキュメントからもう少し訳文。
位置情報取得には2つのオプションがある。 startUpdatingLocationメソッドと呼ぶことによって、標準的な場所サービスを始める。 このサービスは、場所イベントの供給がきめが細かい制御を必要とするアプリケーションのために最適である。 desiredAccuracyとdistanceFilterプロパティーによって、いつ新規のイベントを供給するかを決定する。 これは、高精度の位置情報または定期的な情報更新が必要とされる場所での ナビゲーションをはじめとするアプリケーションに最適である。 しかし、長い間位置情報取得ハードを動かすため、電力を食う。

定期的な位置情報イベントを必要としないなら、startMonitoringSignificantLocationChangesを使う方が良い。 このメソッドは、ユーザーの初期値と優位な位置移動だけを必要とする、ほとんどのアプリケーションに向いている。 これは、携帯電話網のセルが変更されるときだけ新規イベントを送るので省電力である(従って3G版だけの機能)。

どの位置情報サービスを利用するにしても、その情報はデリゲートを通じてアプリに報告される。 初期位置を返すのには数秒かかるので、ロケーションマネージャーはまずは直前に蓄えられた位置情報を集め、 利用可能になったら、その更新情報を届ける。そのため、位置情報オブジェクトのタイムスタンプを調べることが推奨される。 両方の位置情報取得サービスが許可されるなら、どちらも同じデリゲートを使って通知する。

iOS4.0以降では、複数の地理的領域の境界を定義している「領域管理サービス」を使うことが出来る。 startMonitoringForRegion: desiredAccuracy:メソッドで領域を登録すると、 ロケーションマネージャーはそこの境界線をまたいだかを追跡し、移動をデリゲートに通知する。 これは、ユーザに目的地に接近したことを知らせるか、他の関連した情報を提供するため、 地域監視に使うかもしれない。
ロケーションマネージャーに登録した領域は、アプリケーション起動中保持される。 アプリケーションが走っていない間に領域通過が発生するなら、 システムはイベントを処理できるよう、バックグラウンドでアプリを起床(wakeup)または起動する。 再起動後、構成済みの全ての領域が、ロケーションマネージャーのmonitoredRegionsプロパティー利用可能となる。 この領域監視サービスは、他の位置情報サービスとは独立して動く。 ただし、全てのデバイスでサポートされているわけではない(WiFi版iPadは無理やね)。 領域監視機能が使える・使うかどうかはregionMonitoringAvailable と regionMonitoringEnabledで決定する。

以下、細かいクラスの説明。
CLLocationManager
メソッド名動作
-(void)startUpdatingHeading現在方角情報更新開始
-(void)startUpdatingLocation現在位置情報更新開始
-(void)stopUpdatingHeading方角更新停止
-(void)stopUpdatingLocation位置情報更新停止
-(void)stopMonitoringForRegion:(CLRegion *)region指定領域の監視停止
-(void)stopMonitoringSignificantLocationChanges重要位置監視の停止
-(void)startMonitoringForRegion:(CLRegion *)region desiredAccuracy:(CLLocationAccuracy)accuracy領域通過監視を開始する
-(void)startMonitoringSignificantLocationChanges重要位置変化に基づく最新情報更新を開始する
+(BOOL)headingAvailable方角情報を得られるかどうか
+(BOOL)locationServicesEnabledこのデバイス上で位置情報サービスが利用可能かどうか
+(BOOL)regionMonitoringAvailable領域監視サービスが利用可能かどうか
+(BOOL)regionMonitoringEnabled領域監視が現在有効かどうか
+(BOOL)significantLocationChangeMonitoringAvailable 重要な位置変化追跡が利用できるかどうか
プロパティ名属性内容
id <CLLocationManagerDelegate> delegateSデリゲートを設定する
CLLocationAccuracy desiredAccuracy S位置情報の精度を設定する
CLLocationAccuracy distanceFilter S位置情報更新最小距離(m単位)
CLHeading *heading R最も最近の方角
CLLocationDegrees headingFilter S方角情報の更新最小角度(度単位)
CLDeviceOrientation headingOrientationS方角値を計算するときのデバイスの回転方向
CLDeviceOrientation(enum値)
CLDeviceOrientationPortrait ポートレイト方向;ホームボタン下
CLDeviceOrientationPortraitUpsideDown上下逆ポートレイト方向;ホームボタン上
CLDeviceOrientationLandscapeLeft ランドスケープ;ホームボタンは右
CLDeviceOrientationLandscapeRight ランドスケープ;ホームボタンは左
CLDeviceOrientationFaceUp 画面が上(仰向け)
CLDeviceOrientationFaceDown 画面が下(うつぶせ)
CLDeviceOrientationUnknown 方向不明
CLLocation *location R最も最近取得された位置情報
CLLocationDistance maximumRegionMonitoringDistanceR 領域を設定することが出来る最大境界距離
NSSet *monitoredRegions R全ロケーションマネージャーオブジェクトで監視される共有領域設定
NSString *purpose Cロケーションサービスを使用する理由(アプリケーションが設定する)

CLLocationManagerのデリゲートは CLLocationManagerDelegateプロトコルで実装する。
メソッド名動作
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError*)error 位置情報が返せない
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading*)newHeading 方角情報の更新を受信した
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation*)newLocation
 fromLocation:(CLLocation *)oldLocation
新位置情報が有効である
-(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region
 withError:(NSError *)error
領域監視でエラーが発生した
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion*)region 指定領域内に入った
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region 指定領域から出た

CLLocation はCLLocationManagerオブジェクトによって生成される位置情報オブジェクトである。
プロパティ名属性内容
CLLocationAccuracy horizontalAccuracyR場所の位置誤差範囲円半径(m単位;緯度と経度は円の中心を示す)
CLLocationAccuracy verticalAccuracy R場所の高さ誤差範囲(±m)
CLLocationDistance altitude Rメートルで測定される高度
CLLocationDirection course Rデバイス移動方向
CLLocationSpeed speed R瞬間速度(m/秒)
CLLocationCoordinate2D coordinate R測地系情報
NSDate *timestamp R位置情報のタイムスタンプ
メソッド名動作
-(CLLocationDistance)distanceFromLocation:(const CLLocation *)location2点間の距離(m)
-(id)initWithLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude 緯度・経度を持って位置情報オブジェクトを初期化する
-(id)initWithCoordinate:(CLLocationCoordinate2D)coordinate
 altitude:(CLLocationDistance)altitude
 horizontalAccuracy:(CLLocationAccuracy)hAccuracy
 verticalAccuracy:(CLLocationAccuracy)vAccuracy
course:(CLLocationDirection)course
speed:(CLLocationSpeed)speed
timestamp:(NSDate *)timestamp
timestamp:(NSDate *)timestamp



位置情報オブジェクトの初期化

CLHeading は方角を示すクラスである。
プロパティ名属性内容
CLHeadingComponentValue xR地磁気情報x軸
CLHeadingComponentValue yR地磁気情報y軸
CLHeadingComponentValue zR地磁気情報z軸
NSDate *timestampR取得データのタイムスタンプ
CLLocationDirection trueHeadingR真北からの相対方向(度単位)
CLLocationDirection headingAccuracyR方角情報と真の地軸方向の最大誤差(度単位)
CLLocationDirection magneticHeadingR地磁気北からの相対方向(度単位)
「地磁気上の北」はコンパスが示す北、「真北」は北極点の方向。詳しくは書かないが、地球の地軸=自転回転軸と磁極はずれているのである。

CLRegion は領域を設定するためのクラスである。
プロパティ名属性内容
CLLocationCoordinate2D centerR領域の中心
CLLocationDistance radiusR領域の半径(m単位)
NSString *identifierR領域オブジェクトのID
メソッド名動作
-(BOOL)containsCoordinate:(CLLocationCoordinate2D)coordinate領域が指定座標を含むか
-(id)initCircularRegionWithCenter:(CLLocationCoordinate2D)center radius:(CLLocationDistance)radius identifier:(NSString *)identifier 円で示される領域の初期化


なお、 CLLocation系で使うデータ型は以下のように定義されている。
型名実定義内容
CLLocationAccuracy double座標値の正確さをm単位で示す
CLLocationDegrees double度で示される緯度または経度
CLLocationDirection double真北からの角度で示される方向
CLLocationDistance double距離(m単位)
CLLocationSpeed double速度(m/秒)
CLLocationCoordinate2D 構造体WGS84測地系(アメリカの測地系)を使用している地理座標を含む構造体
GPSの使う測地系がこれ