指定した時間が来たらプログラムを呼び出すには Local Notification を使います。 アプリが起動していなくても、通知を受け取って アプリを起動することができます。
ViewController.swiftに追加するコード(赤字部分) |
import UIKit class ViewController: UIViewController { @IBAction func tapButton(sender: AnyObject) { let app = UIApplication.sharedApplication() app.cancelAllLocalNotifications(); app.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil)) let date = NSDate().dateByAddingTimeInterval(NSTimeInterval(5.0)) let notification = UILocalNotification() notification.alertBody = "Time has reached" notification.alertAction = "OK" notification.soundName = UILocalNotificationDefaultSoundName notification.timeZone = NSTimeZone.defaultTimeZone() notification.fireDate = date app.scheduleLocalNotification(notification) } override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
AppDelegate.swiftに追加するコード(赤字部分) |
import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) { let alert: UIAlertController = UIAlertController(title:"Local Notify", message: notification.alertBody, preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title:"Cancel",style:UIAlertActionStyle.Cancel,handler:nil)) self.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil) } func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { return true } func applicationWillResignActive(application: UIApplication) { } func applicationDidEnterBackground(application: UIApplication) { } func applicationWillEnterForeground(application: UIApplication) { } func applicationDidBecomeActive(application: UIApplication) { } func applicationWillTerminate(application: UIApplication) { } } |
--> |
--> |
ViewController.swift(myLabel変数の宣言は増えたが、自分で追加するコードなし) |
import UIKit class ViewController: UIViewController { @IBOutlet weak var myLabel: UILabel! @IBAction func tapButton(sender: AnyObject) { let app = UIApplication.sharedApplication() app.cancelAllLocalNotifications(); app.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil)) let date = NSDate().dateByAddingTimeInterval(NSTimeInterval(5.0)) let notification = UILocalNotification() notification.alertBody = "Time has reached" notification.alertAction = "OK" notification.soundName = UILocalNotificationDefaultSoundName notification.timeZone = NSTimeZone.defaultTimeZone() notification.fireDate = date app.scheduleLocalNotification(notification) } override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
AppDelegate.swiftに追加するコード(緑字部分) |
import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) { let vc: ViewController = self.window!.rootViewController as! ViewController vc.myLabel.text = notification.alertBody let alert: UIAlertController = UIAlertController(title:"Local Notify", message: notification.alertBody, preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title:"Cancel",style:UIAlertActionStyle.Cancel,handler:nil)) self.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil) } func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { return true } func applicationWillResignActive(application: UIApplication) { } func applicationDidEnterBackground(application: UIApplication) { } func applicationWillEnterForeground(application: UIApplication) { } func applicationDidBecomeActive(application: UIApplication) { } func applicationWillTerminate(application: UIApplication) { } } |
アプリが非アクティブな状態のときに Local Notification が通知されると AppDelegateのapplication:didFinishLaunchingWithOptions: 経由で起動されます。 このときに、起動オプションの中にLocalNotificationの情報があれば そこから情報を取り出します。
この段階ではまだ self.window.rootViewController などが生成されていないので、 取り出した通知情報は AppDelegate の変数に保持します。
ViewController.swif(マゼンタ色の部分を追加) |
import UIKit class ViewController: UIViewController { @IBOutlet weak var myLabel: UILabel! @IBAction func tapButton(sender: AnyObject) { let app = UIApplication.sharedApplication() app.cancelAllLocalNotifications(); app.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil)) let date = NSDate().dateByAddingTimeInterval(NSTimeInterval(5.0)) let notification = UILocalNotification() notification.alertBody = "Time has reached" notification.alertAction = "OK" notification.soundName = UILocalNotificationDefaultSoundName notification.timeZone = NSTimeZone.defaultTimeZone() notification.fireDate = date app.scheduleLocalNotification(notification) } override func viewDidLoad() { super.viewDidLoad() let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate if let msg = appDelegate.notifiedMessage { myLabel.text = msg } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
AppDelegate.swiftに追加するコード(マゼンダ色の字部分) |
import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? var notifiedMessage: String? func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) { let vc: ViewController = self.window!.rootViewController as! ViewController vc.myLabel.text = notification.alertBody let alert: UIAlertController = UIAlertController(title:"Local Notify", message: notification.alertBody, preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title:"Cancel",style:UIAlertActionStyle.Cancel,handler:nil)) self.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil) } func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { if let option = launchOptions { let notification = option[UIApplicationLaunchOptionsLocalNotificationKey] as! UILocalNotification? notifiedMessage = notification?.alertBody } return true } func applicationWillResignActive(application: UIApplication) { } func applicationDidEnterBackground(application: UIApplication) { } func applicationWillEnterForeground(application: UIApplication) { } func applicationDidBecomeActive(application: UIApplication) { } func applicationWillTerminate(application: UIApplication) { } } |
上記の例では、現在時刻から数秒後に通知を設定していました。 特定の日時にローカル通知が来るように設定してみます。
ViewController.swiftの変更点(水色の字部分)(黄色の文字部分はなくても動きます) |
import UIKit class ViewController: UIViewController { @IBOutlet weak var myDatePicker: UIDatePicker! @IBOutlet weak var myLabel: UILabel! @IBAction func tapButton(sender: AnyObject) { let app = UIApplication.sharedApplication() app.cancelAllLocalNotifications(); app.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil)) let date = myDatePicker.date print(date) let format = NSDateFormatter() format.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" format.timeZone = NSTimeZone(abbreviation: "JST") print(format.stringFromDate(date)) let notification = UILocalNotification() notification.alertBody = "Time has reached" notification.alertAction = "OK" notification.soundName = UILocalNotificationDefaultSoundName notification.timeZone = NSTimeZone.defaultTimeZone() notification.fireDate = date app.scheduleLocalNotification(notification) } override func viewDidLoad() { super.viewDidLoad() let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate if let msg = appDelegate.notifiedMessage { myLabel.text = msg } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |