[iOS 8] Location Notification を使って領域観測で通知する

Location Notification

iOS 8 から Location Notification という新しいユーザー通知が定義されました。Location Notification とは、位置情報を使った領域観測でユーザーに情報を通知する機能のことです。これまで同様の機能を実装するためには Core Location フレームワークの CLLocationManager や CLLocationManagerDelegate などを使って実装していましたが、iOS 8 では UILocalNotification を使って簡単に実装できるようになりました。

ということで、Location Notification を実装する手順を解説したいと思います。

2014/11/14 更新
サンプルアプリを GitHub で公開しました!ぜひ参考にしてください。
suwa-yuki/LocationNotificationSample

プロジェクトの設定

Location Notification を使うためには Core Location フレームワーク が必要です。まずは何も考えずにプロジェクトの設定から追加しましょう。

location_notification01

位置情報の許可

さて、実装です。まず Location Notification を使うには、ユーザーに位置情報の利用を許可してもらう必要があります。AppDelegate などでリクエストする処理を実装します。

import UIKit
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
                            
    var window: UIWindow?
    var manager: CLLocationManager!
    
    // MARK: - UIApplicationDelegate

    func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
        
        let settings = UIUserNotificationSettings(forTypes: .Alert | .Sound | .Badge, categories: nil)
        application.registerUserNotificationSettings(settings)
        
        self.manager = CLLocationManager()
        self.manager.delegate = self;
        self.manager.requestAlwaysAuthorization()
        
        return true
    }
    
    // MARK: - CLLocationManagerDelegate
    
    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch status {
        case .Authorized, .AuthorizedWhenInUse:
            println("位置情報利用可")
            // Local Notificationを実行
            self.notification()
        default:
            println("位置情報利用不可")
        }
    }

}

なお、iOS 8 より CLAuthorizationStatus.AuthorizedWhenInUse という位置情報の許可の種類が増えました。CLAuthorizationStatus.AuthorizedWhenInUse が設定されている場合は、標準位置情報サービスと iBeacon のレンジング(距離観測) のみ利用可能です。iOS 7 までの実装方法で利用している場合は常に許可されているステータスになります。

この通知で表示されるメッセージは Info.plist でカスタマイズ可能です。NSLocationWhenInUseUsageDescription というキーを追加し、値にメッセージを設定します。なお、アプリ起動時のみ許可したい場合は NSLocationWhenInUseUsageDescription というキーを追加し、requestWhenInUseAuthorization() を呼ぶようにします。

location_notification02

実行すると、次のようなアラートが表示されます。

location_notification03

この位置情報の許可設定は設定の中にあるアプリ設定からアクセス可能です。

location_notification04

2014/11/18 追記
Local Notification は When In Use (アプリ利用時のみ許可) または Always (常に許可) のどちらのステータスでも受け取れます(UILocalNotification.h ヘッダ内に "in order to use region-triggered notifications, applications must have "when-in-use" authorization through CoreLocation." という記載があります)。情報を提供くださいましたkoogawaさん、ありがとうございました!

Location Notification の実装

Location Notification で通知するには UILocalNotification を利用します。

func notification() {
    
    println("scheduled notification")
    
    let coordinate = CLLocationCoordinate2DMake(35.697239, 139.774719)
    let radius = 100.0
    let identifier = "sample"
    
    let notification = UILocalNotification()
    notification.alertBody = "たどり着いた!"
    notification.regionTriggersOnce = true
    notification.region = CLCircularRegion(circularRegionWithCenter: coordinate, radius: radius, identifier: identifier)
    
    UIApplication.sharedApplication().scheduleLocalNotification(notification)
    
}

regionTriggersOnce はリージョン(領域)に入った時に繰り返し呼ぶか、という設定です。true の場合はリージョンに入った時に1度だけ通知され、false の場合はリージョンに入るたびに通知されます。region には開始対象のリージョンを指定します。ちなみに fireDate と一緒に指定するとエラーで強制終了します。

実行すると、次のように通知されます。

location_notification05

まとめ

UILocalNotification から通知できるようになったことで、ジオフェンシングから通知を送るような処理はより簡単になりました。一方で、位置情報のプライバシー許可の種類は増えているので注意して実装しましょう。

参考