The following code works, no problem at all.
let eventStore = EKEventStore()
eventStore.requestAccessToEntityType(.Event, completion: { (granted, error) in
if granted == false { return }
let e = EKEvent(eventStore: eventStore)
e.title = self.event!.title
let meh = self.event!.commencement
print("\(meh)")
e.startDate = meh
e.location = self.event!.venue.contact.address.assembleAddress()
let bleh = NSDate(timeInterval: Double(60*24*60*60), sinceDate: self.event!.commencement)
print("\(bleh)")
e.endDate = bleh
e.calendar = eventStore.defaultCalendarForNewEvents
e.URL = self.event!.marketingURL
e.addAlarm(EKAlarm(absoluteDate: self.event!.commencement.dateByAddingTimeInterval(Double(-60*60*24*7))))
do {
try eventStore.saveEvent(e, span: .ThisEvent, commit: true)
} catch let error as NSError {
print("error \(error)")
}
})
When I change the end date to 8 hours ahead of the commence date, the event is not created, or for a fleeting moment it is there, then the network activity indicator spins and it is removed.
let eventStore = EKEventStore()
eventStore.requestAccessToEntityType(.Event, completion: { (granted, error) in
if granted == false { return }
let e = EKEvent(eventStore: eventStore)
e.title = self.event!.title
let meh = self.event!.commencement
print("\(meh)")
e.startDate = meh
e.location = self.event!.venue.contact.address.assembleAddress()
let bleh = NSDate(timeInterval: Double(8*60*60), sinceDate: self.event!.commencement)
print("\(bleh)")
e.endDate = bleh
e.calendar = eventStore.defaultCalendarForNewEvents
e.URL = self.event!.marketingURL
e.addAlarm(EKAlarm(absoluteDate: self.event!.commencement.dateByAddingTimeInterval(Double(-60*60*24*7))))
do {
try eventStore.saveEvent(e, span: .ThisEvent, commit: true)
} catch let error as NSError {
print("error \(error)")
}
})
No error is printed. What's going on ?
The date is in the past. Make sure the date is in the future.
Related
I'm trying to copy specific events from all calendars to the target calendar. Unfortunately my events are not saving in target calendar.
Simply my code in steps:
Check permissions (success)
Load calendars (success)
Load events (success)
Save events (failed)
I'm sure there are events to save from terminal which prints "Trying to save" couple of times.
And it looks like code pass through "try self.eventStore.save(event, span: .thisEvent)" and exits function there without calling "Saved" or entering catch clause.
There is a source code:
import UIKit
import EventKit
class ViewController: UIViewController{
#IBOutlet weak var status: UILabel!
var calendars: [EKCalendar]?
var targetCalendar: EKCalendar?
var targetCalendarEvents: [EKEvent]?
let eventStore = EKEventStore()
let targetCalendarName = "TargetCalendarName"
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
DispatchQueue.main.async{
self.status.text = "Idle"
}
checkCalendarAuthorizationStatus()
}
func checkCalendarAuthorizationStatus() {
let status = EKEventStore.authorizationStatus(for: EKEntityType.event)
switch (status) {
case EKAuthorizationStatus.notDetermined:
// This happens on first-run
requestAccessToCalendar()
case EKAuthorizationStatus.authorized:
// Things are in line with being able to show the calendars in the table view
loadCalendars()
loadEvents()
case EKAuthorizationStatus.restricted, EKAuthorizationStatus.denied:
// We need to help them give us permission
print("Missing permissions [00]")
}
}
func requestAccessToCalendar() {
eventStore.requestAccess(to: EKEntityType.event, completion: {
(accessGranted: Bool, error: Error?) in
if accessGranted == true {
DispatchQueue.main.async(execute: {
self.loadCalendars()
self.loadEvents()
})
} else {
print("Missing permissions [01]")
}
})
}
func loadEvents(){
print("Loading..")
DispatchQueue.main.async{
self.status.text = "Loading"
}
let eventStore = EKEventStore()
var initialized = false
//Two months
let dateTo = NSDate(timeIntervalSinceNow: +30*24*3600 * 2)
for calendar in self.calendars! {
let predicate = eventStore.predicateForEvents(withStart: Date() as Date as Date, end: dateTo as Date, calendars: [calendar])
let events = eventStore.events(matching: predicate)
if calendar.title == targetCalendarName {
print("Initialized")
targetCalendar = calendar
targetCalendarEvents = events
initialized = true
}
}
if(!initialized){
print("Not Initialized")
} else {
for calendar in self.calendars! {
let predicate = eventStore.predicateForEvents(withStart: Date() as Date as Date, end: dateTo as Date, calendars: [calendar])
let events = eventStore.events(matching: predicate)
if calendar.title != targetCalendarName && calendar.title != "Contacts" {
//print("Loaded Calendar \(calendar.title)")
print("Loaded Calendar")
for event in events {
if(!(event.location?.isEmpty)!){
//print("Event \(event.location ?? "Missing Location") \(event.startDate) \(event.endDate)")
addEventToTarget(eventToAdd: event)
}
}
}
}
}
DispatchQueue.main.async {
self.status.text = "Done"
}
print("Done")
}
func loadCalendars() {
self.calendars = eventStore.calendars(for: EKEntityType.event)
}
func addEventToTarget(eventToAdd: EKEvent){
eventStore.requestAccess(to: .event) { (granted, error) in
for event in self.targetCalendarEvents! {
if(!(event.location?.isEmpty)!){
if(
eventToAdd.title == event.title &&
eventToAdd.startDate == event.startDate &&
eventToAdd.endDate == event.endDate
){
print("Possible duplicate - skipping")
return
}
}
}
if (granted) && (error == nil) {
let event:EKEvent = EKEvent(eventStore: self.eventStore)
event.title = eventToAdd.title
event.startDate = eventToAdd.startDate
event.endDate = eventToAdd.endDate
event.notes = ""
event.location = eventToAdd.location
event.calendar = self.targetCalendar
//print("Trying to save \(event.title) \(String(describing: event.location))")
print("Trying to save")
do {
try self.eventStore.save(event, span: .thisEvent)
print("Saved \(event.title) \(String(describing: event.location)) in \(event.calendar.title)")
} catch {
print("failed to save event with error : \(error as NSError)")
}
}
else{
print("failed to save event with error : \(String(describing: error)) or access not granted")
}
}
}
}
TargetCalendarName is correct calendar name
Sometimes there are events which saves successfully but only couple of them (2-5) for hundreds which should save. I don't have a clue why.
So 5 for 200 is not enough for me.
Thanks to #matt for proposing a solution.
Now I'm saving events ONCE (previously I was requesting access for every event which is very bad), so I request access to eventStore once and can save events succesfully.
func saveEvents(){
eventStore.requestAccess(to: .event) { (granted, error) in
if (granted) && (error == nil) {
for event in self.eventsToCopy {
print("Trying to save")
do {
try self.eventStore.save(event, span: .thisEvent)
print("Saved \(event.title) \(String(describing: event.location)) in \(event.calendar.title)")
} catch {
print("failed to save event with error : \(error as NSError)")
}
}
}
else{
print("failed to save event with error : \(String(describing: error)) or access not granted")
}
}
}
This is the way I am adding all the events in to my calendar, those events are coming from table view. I have a problem with deleting a specific even from the calendar when the row on the table view gets deleted. The code that I am trying seems not to find and identifier in the calendar. Can you please let me know what I am missing here
ADD TO CALENDAR
let eventStore : EKEventStore = EKEventStore()
// 'EKEntityTypeReminder' or 'EKEntityTypeEvent'
eventStore.requestAccess(to: .event) { (granted, error) in
if (granted) && (error == nil) {
print("granted \(granted)")
print("error \(error)")
let event:EKEvent = EKEvent(eventStore: eventStore)
event.title = "Test Title"
event.startDate = Date()
event.endDate = Date()
event.notes = "This is a note"
event.calendar = eventStore.defaultCalendarForNewEvents
do {
try eventStore.save(event, span: .thisEvent)
} catch let error as NSError {
print("failed to save event with error : \(error)")
}
print("Saved Event")
}
else{
print("failed to save event with error : \(error) or access not granted")
}
}
DELETE FROM CALENDAR
func deleteEvent(_ storedEventID: String)
{
eventStore.requestAccess(to: .event, completion: { (granted, error) in
if (granted) && (error == nil)
{
if let calendarEvent_toDelete = self.eventStore.event(withIdentifier: storedEventID){
//recurring event
if calendarEvent_toDelete.recurrenceRules?.isEmpty == false
{
let alert = UIAlertController(title: "Repeating Event", message:
"This is a repeating event.", preferredStyle: UIAlertControllerStyle.alert)
//delete this event only
let thisEvent_Action = UIAlertAction(title: "Delete this event", style: UIAlertActionStyle.default)
{
(result : UIAlertAction) -> Void in
//sometimes doesn't delete anything, sometimes deletes all reccurent events, not just current!!!
do{
try self.eventStore.remove(calendarEvent_toDelete, span: .thisEvent)
} catch let e as NSError{return}
}
alert.addAction(thisEvent_Action)
}
//not recurring event
else{
//works fine
do{
try self.eventStore.remove(calendarEvent_toDelete, span: EKSpan.thisEvent)
} catch let e as NSError{
return
}
}
}
}
})
}
What I am missing in your example is to commit the changes to the event store.
Commit the changes immediately or with a separate commit while bulk processing multiple events.
try? self.eventStore.remove(eventToRemove, span: .thisEvent, commit: true)
Good luck and success.
first get the event using even Id then delete the event
func removeEvent(eventId: String, eventStore: EKEventStore) {
if let eventToDelete = self.eventStore.event(withIdentifier: eventId){
do {
try eventStore.remove(eventToDelete, span: .thisEvent)
} catch let error as NSError {
print("failed to save event with error : \(error)")
}
print("removed Event")
}
}
In my application I can select date and time for EKEvent. I almost achieved what I want except Time. How can I set time. Below is my code, I have tried.
func setReminder(){
let eventStore = EKEventStore()
eventStore.requestAccess(
to: EKEntityType.event, completion: {(granted, error) in
if !granted {
print("Access to store not granted")
print(error!.localizedDescription)
} else {
print("Access granted")
let event = EKEvent(eventStore: eventStore)
event.title = self.getCategoryText + " Reminder"
event.calendar =
eventStore.defaultCalendarForNewEvents
event.timeZone = TimeZone.current
let alarm = EKAlarm(absoluteDate: self.selectedDate!)
event.addAlarm(alarm)
if self.daysBeforeDate != nil{
let earlierDate = self.daysBeforeDate
let earlierAlarm = EKAlarm(absoluteDate: earlierDate!)
event.addAlarm(earlierAlarm)
}
print("selected time", self.selectedTime)
var number1: Double = (self.selectedTime! as NSString).doubleValue
event.startDate = self.selectedDate!.addingTimeInterval(number1)
event.endDate = self.selectedDate!
do {
try eventStore.save(event, span: .thisEvent, commit: true)
} catch let error {
print("Reminder failed with error \(error.localizedDescription)")
return
}
}
})
}
Update 1
let calendar = Calendar.current
var dateComponents = DateComponents()
dateComponents.year = calendar.component(.year, from: self.selectedDate!)
dateComponents.month = calendar.component(.month, from: self.selectedDate!)
dateComponents.day = calendar.component(.day, from: self.selectedDate!)
dateComponents.timeZone = TimeZone.current
dateComponents.hour = self.selectedHour
dateComponents.minute = self.selectedMinute
let userCalendar = Calendar.current // user calendar
let someDateTime = userCalendar.date(from: dateComponents)
This is the code I've used for creating an event for a time interval and it's working fine for me:
func saveEvent(on date: Date, withTitle title: String, forHourse hourse: Int) {
let event = EKEvent(eventStore: eventStore!)
event.title = title
event.startDate = date
event.endDate = date.addingTimeInterval((TimeInterval(hourse * 60 * 60)))
let alarm = EKAlarm(absoluteDate: date)
event.alarms = [alarm]
event.calendar = (eventStore?.defaultCalendarForNewEvents)!
do {
try eventStore?.save(event, span: .thisEvent, commit: true)
} catch {
}
}
I am new to swift and i am practicing "Adding a Calendar Event" from this website: http://www.ioscreator.com/tutorials/add-event-calendar-tutorial-ios8-swift, but I am getting the following errors at line
let result = store.saveEvent(event, span: .ThisEvent, commit: error)
Call can throw, but it is not marked with 'try' and the error is not handled
Cannot convert value of type 'NSError?' to expected argument type 'Bool'
Code:
import UIKit
import EventKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let eventStore = EKEventStore()
switch EKEventStore.authorizationStatusForEntityType(EKEntityType.Event) {
case .Authorized:
insertEvent(eventStore)
case .Denied:
print("Access denied")
case .NotDetermined:
// 3
eventStore.requestAccessToEntityType(EKEntityType.Event, completion:
{[weak self] (granted: Bool, error: NSError?) -> Void in
if granted {
self!.insertEvent(eventStore)
} else {
print("Access denied")
}
})
default:
print("Case Default")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func insertEvent(store : EKEventStore){
let calendars = store.calendarsForEntityType(EKEntityType.Event) as! [EKCalendar]
for calendar in calendars{
if calendar.title == "ioscreater"{
let startDate = NSDate()
let endDate = startDate.dateByAddingTimeInterval(2*60*60)
//Create event
var event = EKEvent(eventStore : store)
event.calendar = calendar
event.title = "New Meeting"
event.startDate = startDate
event.endDate = endDate
//Save event in Calendar
var error : NSError?
let result = store.saveEvent(event, span: .ThisEvent, commit: error)
if result == false{
if let theError = error{
print ("An error occured \(theError)")
}
}
}
}
}
}
I googled the errors but I could not find an appropriate solution.
This works for me in Swift 3.0
Firstly, You need to add "Privacy - Calendars Usage Description" in info.plist.
import EventKit
func addEventToCalendar(title: String, description: String?, startDate: Date, endDate: Date, completion: ((_ success: Bool, _ error: NSError?) -> Void)? = nil) {
let eventStore = EKEventStore()
eventStore.requestAccess(to: .event, completion: { (granted, error) in
if (granted) && (error == nil) {
let event = EKEvent(eventStore: eventStore)
event.title = title
event.startDate = startDate
event.endDate = endDate
event.notes = description
event.calendar = eventStore.defaultCalendarForNewEvents
do {
try eventStore.save(event, span: .thisEvent)
} catch let e as NSError {
completion?(false, e)
return
}
completion?(true, nil)
} else {
completion?(false, error as NSError?)
}
})
}
Then, you can easily call this method like the following:
addEventToCalendar(title: "Best friend birthday", description: "Remember you or miss you!", startDate: NSDate(), endDate: NSDate())
Thanks and enjoy coding!!!
func insertEvent(store : EKEventStore){
let calendars = store.calendarsForEntityType(EKEntityType.Event)
for calendar in calendars{
if calendar.title == "ioscreater"{
let startDate = NSDate()
let endDate = startDate.dateByAddingTimeInterval(2*60*60)
//Create event
var event = EKEvent(eventStore : store)
event.calendar = calendar
event.title = "New Meeting"
event.startDate = startDate
event.endDate = endDate
//Save event in Calendar
do {
try store.saveEvent(event, span: .ThisEvent)
} catch {
// Do error stuff here
}
}
Add saveEvent code in try,catch like below :
do {
try store.saveEvent(event, span: .ThisEvent)
} catch let err as NSError{
print ("An error occured \(err.description)")
}
I am having an issue with a self-hosted Parse Server, everytime I go to log in, I am required to remove the contents of the SCHEMA class.
Here is what I am doing with the login
PFFacebookUtils.logInInBackgroundWithReadPermissions(["public_profile", "user_birthday", "email"], block: {
user, error in
JTProgressHUD.showWithStyle(JTProgressHUDStyle.Gradient)
if user == nil {
print("Error Logging In")
JTProgressHUD.hideWithTransition(.Default)
}
if user != nil {
print("User signed up and logged in through Facebook!")
JTProgressHUD.showWithStyle(JTProgressHUDStyle.Gradient)
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me/?fields=picture.height(512).width(512),first_name,birthday,gender,bio,email", parameters: nil)
graphRequest.startWithCompletionHandler({
connection, result, error in
print("ERROR: \(error)")
guard let r = result as? NSDictionary else {
if let error = error {
print(error)
}
return
}
print(connection)
print(result)
if let e = error { print(e) }
user!["firstName"] = r["first_name"]
user!["gender"] = r["gender"]
user!["pictureString"] = ((r["picture"] as! NSDictionary)["data"] as! NSDictionary) ["url"]
//BIO
user!["bio"] = "Thanks for Downloading Root or Boot, Please Enter a Bio by Clicking Here"
if (r["bio"] != nil){
user!["bio"] = r["bio"]
}
user!["email"] = "user#rootorboot.com"
if (r["email"] != nil) {
user!["email"] = r["email"]
}
// let locationObj = r.objectForKey("hometown")x
// let location = locationObj!.objectForKey("name") as! String
// print("Location: \(location)")
// let workObj = r.objectForKey("work")
// let workDescription = workObj?.objectForInfoDictionaryKey("description") as! String
// print("Work Description: \(workDescription)")
var ageDate = NSDate()
var ageString = NSString()
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
if (r["birthday"] != nil) {
ageDate = dateFormatter.dateFromString(r["birthday"] as! String)!
print(ageDate)
}
else {
ageDate = dateFormatter.dateFromString("01/01/2003")!
print(ageDate)
}
let ageDateFormatter = NSDateFormatter()
ageDateFormatter.dateFormat = "MM/dd/yyyy"
print(ageDateFormatter.stringFromDate(ageDate))
ageString = ageDateFormatter.stringFromDate(ageDate)
print("AGE STRING: \(ageString)")
let pictureURL = ((r["picture"] as! NSDictionary)["data"] as! NSDictionary) ["url"] as! String
let url = NSURL(string: pictureURL)
let request = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {
response, data, error in
// print(ageDate as! String)
if let ageDateForKey = ageString as? String {
let birthday: NSDate = dateFormatter.dateFromString(ageDateForKey as String)!
var now: NSDate = NSDate()
var ageComponents: NSDateComponents = NSCalendar.currentCalendar().components(.Year, fromDate: birthday, toDate: now, options: [])
var age: Int = ageComponents.year
user!["age"] = 13
if (user!["age"] != nil) {
user!["age"] = age
print(age)
}
else if (user!["age"] == nil) {
user!["age"] = 13
print(age)
}
}
let imageFile = PFFile(name: "avatar.jpg", data: data!)
user!["picture"] = imageFile
user!.saveInBackgroundWithBlock(nil)
When I log in (Before SCHEMA fix) - Error Logging In
When I log in (After SCHEMA fix) - User logs in - print(results) runs