##はじめに
カレンダーアプリのスケジュールなどプライベート情報はiOSで管理されていて、アプリからのアクセスは制限されています。
そーいう場合のコーディングについて、自分的ベストプラクティスを書いてみます。
コードはSwiftで書いてます。
##やりたいUX
- 初回起動時に、カレンダにアクセスするための許諾UIを表示することはしたくない。(少なくとも私は、これをやられると使う気が少し失せるw)
- カレンダに書き込みする操作を はじめてしたとき、許諾を得るUIを表示する。 (ユーザが行ったアクションに対してカレンダアクセスの許諾表示がでるので、自然に感じるはず!っと思っています。)
- 項番2のところで、許諾をもらえたら、すぐにイベントを書き込む。
- 許諾をもらえなかったときは(二度目以降も)、OS標準の設定アプリでの設定が必要なことを伝える。
- 二度目以降は、すぐに項番3, 4の処理を行う(イベントを書き込みなど)
##コーディング
- UXの項番2は、
EKEventStore.authorizationStatusForEntityType()
とeventStore.requestAccessToEntityType()
で実現します。 - UXの項番3をするために、許可してもらえたら 再度
registEvent()
を呼びなおして処理しています。(UXの項番5と同様) - UXの項番4をするために、UIAlertControllerを表示しています。
- 上記2つのUI表示は、main_queueで実行しなくてはならないので、
dispatch_async()
を使っています。 - Eventの開始時刻と終了時刻は、必ず 終了時刻>開始時刻でないとダメなので必要に応じて入替てます。
- イベントをエディットできる標準UIがあるので、
EKEventEditViewController()
で表示します。
ViewController.swift
let eventStore = EKEventStore()
@IBAction func registEvent() {
if EKEventStore.authorizationStatusForEntityType(.Event) != .Authorized {
eventStore.requestAccessToEntityType(.Event, completion: { granted,_ in
dispatch_async(dispatch_get_main_queue(), { _ in
if granted {
self.registEvent()
}
else {
let alert = UIAlertController(title: "Alert", message: "Please set Settings app > Privacy > Calendars", preferredStyle: .Alert )
alert.addAction( UIAlertAction(title: "OK", style: .Cancel, handler: nil) )
self.presentViewController(alert, animated: true, completion: nil)
}
})
return
})
return
}
let event = EKEvent(eventStore: eventStore)
if let st = date[0] { // date[0],[1]にDateが二つ入っています。
event.startDate = st
if let ed = date[1] {
event.endDate = ed
if ed.compare(st) == .OrderedAscending { // st > ed
event.startDate = ed
event.endDate = st
}
}
else {
event.endDate = st
}
}
let ec = EKEventEditViewController()
ec.eventStore = eventStore
ec.event = event
ec.editViewDelegate = self
self.presentViewController(ec, animated: true, completion: nil)
}
func eventEditViewController( controller: EKEventEditViewController, didCompleteWithAction action: EKEventEditViewAction) {
switch action {
case .Saved :
do {
try eventStore.saveEvent(controller.event!, span: .ThisEvent)
} catch let error {
print(error)
}
default:
break
}
controller.dismissViewControllerAnimated(true, completion: nil)
}
読んでいただき、ありがとうございました。