How to check NSDate yyyy/mm/dd in NSArray and compare it? - ios

I have an NSArray, inside I have a var of kind NSDate
which give this format "timeStamp = "2015-08-18 16:58:31"
I want to compare in all the array the date only 2015-08-18
compare it and if same date only the first one show full NSDate
and the rest with same date show only the time on UI
This is what I did so far:
func getAllMessages() -> NSArray{
var allMessages = self.mutableSetValueForKey("messages").allObjects as NSArray
let timeStampSortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: true)
var sortByTime = allMessages.sortedArrayUsingDescriptors([timeStampSortDescriptor])
println("\(sortByTime)")
return sortByTime
}
screen shot
http://i.stack.imgur.com/wcsSz.jpg

After some research i did made a solution as following
First this extension is very good and my way is depends on it
https://stackoverflow.com/a/27369380/5188737
If anyone have better solution or clean
I will appreciate if you can post it here
I'm sorry there's no comments
func loadMessages(){
if chatRoom!.messages.count > 0{
var i = 0
var tempMsgDate:NSDate?
var chatMessage:ChatMessage?
for message in chatRoom!.getAllMessages(){
let msg = message as! Message
if i == 0{
tempMsgDate = msg.timeStamp
chatMessage = ChatMessage(incoming: msg.income, text: msg.message, sentDate: convertNSDateToString(msg.timeStamp))
i++
}else{
//if the tempMsgDate (which is the first of the same
//date in the nsarray)
if checkIfSameDayDate(tempMsgDate!,date2: msg.timeStamp){
var tempDate = msg.timeStamp.time
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
let date = dateFormatter.dateFromString(tempDate)
println("loadmessages method: \(date?.time)")
chatMessage = ChatMessage(incoming: msg.income, text: msg.message, sentDate: msg.timeStamp.time)
}else{//after he got to different date it save it as
//first of same date to follow
tempMsgDate = msg.timeStamp
chatMessage = ChatMessage(incoming: msg.income, text: msg.message, sentDate: convertNSDateToString(msg.timeStamp))
}
}
var msgCollection:[ChatMessage] = [ChatMessage]()
msgCollection.append(chatMessage!)
chat.loadedMessages.append(msgCollection)
}
}
}
func convertNSDateToString(date:NSDate) -> String{
let dateString = date.date + " " + date.time
println("in convert: \(dateString)")
return dateString
}
func checkIfSameDateFromSendMSGAndReciveMSG(date:NSDate) -> Bool{
for message in chatRoom!.getAllMessages(){
let msg = message as! Message
if msg.timeStamp.date == date.date{
return true
}
}
return false
}
//checks if the date1 equal to date2
func checkIfSameDayDate(date1:NSDate,date2:NSDate) -> Bool{
if date1.date == date2.date{
return true
}
return false
}

Related

Changes in the datepicker widgets in iOS?

In our iOS app we have a timepicker widget to book appointments. This has worked fine for a long time. We just changed iOS developer and when he rebuilt the app the timepicker is broken for some reason we cannot tell. Has something changed recently in XCode/iOS that could explain why the layout suddenly is broken?
How it was
How it is now
This is the code responsible:
This timepicker is based on the standard iOS UIDatePicker.
class TimePickerController: UIViewController {
#IBOutlet weak var notAvailableLbl: UILabel!
#IBOutlet weak var fromPicker: UIDatePicker!
#IBOutlet weak var toPicker: UIDatePicker!
#IBOutlet weak var switchNotAvailable: UISwitch!
var object: EventElement?
var delegate:TimePickerControllerDelegate?
var name: DEFAULT_AVAILABILITY_CONST!
var startTime,endTime: Date?
var isFromSettings:Bool = false
var isNotAvailable: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.barTintColor = AppColors.Primary
switchNotAvailable.setOn(isNotAvailable, animated: true)
switchChanged(switchNotAvailable)
setPickerLocale(withIdentifier: "en_GB")
setPickerTimezone(withIdentifier: "UTC")
initPickerDates()
if object?.type == EVENT_CONST.lunch{
switchNotAvailable.isHidden = true
notAvailableLbl.isHidden = true
}else{
switchNotAvailable.isHidden = false
notAvailableLbl.isHidden = false
}
}
func setPickerLocale(withIdentifier locale: String) {
// Changing to 24 hrs
let local = NSLocale(localeIdentifier: locale) as Locale
fromPicker.locale = local
toPicker.locale = local
}
func setPickerTimezone(withIdentifier timeZone: String) {
//set timezone
fromPicker.timeZone = TimeZone.init(identifier: timeZone)
toPicker.timeZone = TimeZone.init(identifier: timeZone)
}
func initPickerDates() {
if let obj = object {
let startTime = obj.start.split(separator: "Z")
let endTime = obj.end.split(separator: "Z")
if(startTime.first == endTime.first)
{
fromPicker.date = getTimeFromString(stringTime: String("08:00"))
toPicker.date = getTimeFromString(stringTime: String("22:00"))
}
else{
fromPicker.date = getTimeFromString(stringTime: String(startTime.first ?? "08:00"))
toPicker.date = getTimeFromString(stringTime: String(endTime.first ?? "22:00"))
}
}else {
if let start = startTime,let end = endTime {
if(start == end)
{
// 8.00 to 22.00
fromPicker.date = start
toPicker.date = end.dateByAddingHours(hours: 14)
}
else{
fromPicker.date = start
toPicker.date = end
}
}
}
}
func getTimeFromString(stringTime: String) -> Date
{
let local = NSLocale(localeIdentifier: "en_GB") as Locale
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
dateFormatter.locale = local
dateFormatter.timeZone = TimeZone.init(identifier: "UTC")
let date = dateFormatter.date(from: stringTime) ?? Date()
print(date)
return date
}
#IBAction func btnDone(_ sender: Any) {
print(fromPicker.date)
print(toPicker.date)
updateEvent()
}
func updateEvent() {
var start = fromPicker.date.timeDisplay + "Z"
var end = toPicker.date.timeDisplay + "Z"
var createdDate:String = ""
var id:String = ""
var name:String = ""
if object == nil {
start = fromPicker.date.ISOISO8601StringForAvailability + "Z"
end = toPicker.date.ISOISO8601StringForAvailability + "Z"
createdDate = Date().toString(format: DateFormat.Custom("yyyy-MM-dd'T'HH:mm:ss")) + "Z"
id = UUID().uuidString.lowercased()
name = self.name.rawValue
}
else{
createdDate = object?.created ?? ""
id = object?.id ?? ""
name = (object?.name.rawValue) ?? ""
}
print("switch state",switchNotAvailable.isOn)
if switchNotAvailable.isOn {
if let startT = startTime,let endT = endTime {
let startDt = "08:00Z".formatDateWithTime(referenceDate: startT)
let endDt = "08:00Z".formatDateWithTime(referenceDate: endT)
start = startDt!.toString(format: DateFormat.Custom("yyyy-MM-dd'T'HH:mm"),timezone: "UTC") + "Z"
end = endDt!.toString(format: DateFormat.Custom("yyyy-MM-dd'T'HH:mm"),timezone: "UTC") + "Z"
}
else{
start = "08:00Z"
end = "08:00Z"
}
}
ActivityIndicator().showIndicator(backgroundColor: nil)
print("start and end date : ",start," ",end)
let type:String?
if isFromSettings == true{
type = object?.type.rawValue
}
else{
type = "AVAILABILITY_PATCH"
}
print(type ?? "AVAILABILITY_PATCH")
APICalls().updateAvailability(start: start, end: end, name: name, type: type ?? "AVAILABILITY_PATCH", created: createdDate,id: id ) { (response) in
ActivityIndicator().hideIndicator()
if let result = response
{
let res = Event.init(dictionary: result as? NSDictionary ?? [:])
DatabaseManager.getInstance().saveAvailability(object: res)
self.delegate?.didSelectTime(from: self.fromPicker.date, to: self.toPicker.date)
self.navigationController?.popViewController(animated: true)
}
}
}
To disable this time picker style, you have to add below line.
fromPicker.preferredDatePickerStyle = .wheels
In IOS 14 we have to define DatePickerStyle.
Please write these two lines in initPickerDates() method to set picker wheel style
fromPicker.preferredDatePickerStyle = .wheels
toPicker.preferredDatePickerStyle = .wheels
In IOS 14, we have multiple styles for date pickers. So this is the default behavior in iOS 14.
You just need to add the following line in the initPickerDates() method.
fromPicker.preferredDatePickerStyle = .wheels
toPicker.preferredDatePickerStyle = .wheels

Swift Firebase Multithreading Issue

I'm trying to run a couple of for loops inside of a function that should return an array of strings.
Where I'm having trouble is with getting the correct results BEFORE the next for loop is run...and then again returning that results BEFORE I need to return the array of strings to complete the function.
In the first case, I have a for loop that's getting data from Firebase. I was able to use a dispatch group to get the value to print out - but then with the other loop after this - I was having issues from using the dispatch group in the prior task.
The code all works perfectly if executed with the correct values but I'm not sure how to go about this with regards to threading. Would really appreciate any help.
func findTopSpots() -> [String] {
var topFive = [String]()
var locationRatingDictionary = [String:Double]()
let myGroup = DispatchGroup()
let locationsArray = ["wyoming", "kansas", "arkansas", "florida", "california"]
// Use the days to find the most common month
let calendar = NSCalendar.current
var monthArray = [String]()
var date = self.departureDate!
let endDate = self.returnDate!
// Formatter for printing the month name
let fmt = DateFormatter()
fmt.dateFormat = "MMMM"
// Add each days month to an array
while date <= endDate {
date = calendar.date(byAdding: .day, value: 1, to: date)!
monthArray.append(fmt.string(from: date))
}
// Return the primary month from function
let primaryMonth = findMostCommonMonthInArray(array: monthArray).lowercased()
// Create a dictionary of location:rating for the primary month
for doc in locationsArray {
self.db.collection("locations").document(doc).collection("historic").document(primaryMonth).getDocument { (document, err) in
if let document = document, document.exists {
let rating = document["rating"] as? Double
locationRatingDictionary[doc] = rating
} else {
print("Document does not exist")
}
}
}
//---- THE CODE BELOW WILL NOT PRINT WITH ANY VALUES ----//
print(locationRatingDictionary)
// Sort the tuple array by rating
let locationRatingTupleArray = locationRatingDictionary.sorted{ $0.value > $1.value }
// Return 5 results
for (location,rating) in locationRatingTupleArray.prefix(5) {
print(location,rating)
topFive.append(location)
}
print("top five are \(topFive)")
return topFive
}
The issue here is that the firebase returns with query results asynchronously and you are not waiting for it to return.
I can see that you have instantiate DispatchGroup but have not used it. Lets try to use it to solve your issue. Also, you would need to change the method signature to take a closure. This avoids blocking thread to return function output.
func findTopSpots(completionHandler:([String])->Void) {
var topFive = [String]()
var locationRatingDictionary = [String:Double]()
let myGroup = DispatchGroup()
let locationsArray = ["wyoming", "kansas", "arkansas", "florida", "california"]
// Use the days to find the most common month
let calendar = NSCalendar.current
var monthArray = [String]()
var date = self.departureDate!
let endDate = self.returnDate!
// Formatter for printing the month name
let fmt = DateFormatter()
fmt.dateFormat = "MMMM"
// Add each days month to an array
while date <= endDate {
date = calendar.date(byAdding: .day, value: 1, to: date)!
monthArray.append(fmt.string(from: date))
}
// Return the primary month from function
let primaryMonth = findMostCommonMonthInArray(array: monthArray).lowercased()
// Create a dictionary of location:rating for the primary month
for doc in locationsArray {
myGroup.enter() self.db.collection("locations").document(doc).collection("historic").document(primaryMonth).getDocument { (document, err) in
if let document = document, document.exists {
let rating = document["rating"] as? Double
locationRatingDictionary[doc] = rating
} else {
print("Document does not exist")
}
myGroup.leave()
}
}
myGroup.notify(queue:.main) {
//---- THE CODE BELOW WILL NOT PRINT WITH ANY VALUES ----//
print(locationRatingDictionary)
// Sort the tuple array by rating
let locationRatingTupleArray = locationRatingDictionary.sorted{ $0.value > $1.value }
// Return 5 results
for (location,rating) in locationRatingTupleArray.prefix(5) {
print(location,rating)
topFive.append(location)
}
print("top five are \(topFive)")
completionHandler(topFive)
}
}
Your code is asynchronous fastest way is dispatchGroup with completion
//
func findTopSpots(completion:#escaping(_ arr:[string])->void){
let dispatchGroup = DispatchGroup()
var topFive = [String]()
var locationRatingDictionary = [String:Double]()
let locationsArray = ["wyoming", "kansas", "arkansas", "florida", "california"]
// Use the days to find the most common month
let calendar = NSCalendar.current
var monthArray = [String]()
var date = self.departureDate!
let endDate = self.returnDate!
// Formatter for printing the month name
let fmt = DateFormatter()
fmt.dateFormat = "MMMM"
// Add each days month to an array
while date <= endDate {
date = calendar.date(byAdding: .day, value: 1, to: date)!
monthArray.append(fmt.string(from: date))
}
// Return the primary month from function
let primaryMonth = findMostCommonMonthInArray(array: monthArray).lowercased()
// Create a dictionary of location:rating for the primary month
for doc in locationsArray {
dispatchGroup.enter()
self.db.collection("locations").document(doc).collection("historic").document(primaryMonth).getDocument { (document, err) in
if let document = document, document.exists {
let rating = document["rating"] as? Double
locationRatingDictionary[doc] = rating
} else {
print("Document does not exist")
}
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .main) {
//---- THE CODE BELOW WILL NOT PRINT WITH ANY VALUES ----//
print(locationRatingDictionary)
// Sort the tuple array by rating
let locationRatingTupleArray = locationRatingDictionary.sorted{ $0.value > $1.value }
// Return 5 results
for (location,rating) in locationRatingTupleArray.prefix(5) {
print(location,rating)
topFive.append(location)
}
print("top five are \(topFive)")
completion(topFive)
}
}

Get items from array by the nearest day

I'm adding items to my Firebase with date in this format:
var date: NSDate?
override func viewDidLoad() {
super.viewDidLoad()
date = NSDate()
}
// ......
#IBAction func save(_ sender: UIBarButtonItem) {
if let realDate = date {
fullDate = "\(String(describing: realDate))"
}
// ......
let wordItem = Word(word: word, translation: translation, date: fullDate, fullDate: trueDate, exOne: exOne, exTwo: exTwo, completed: false, keyRandom: randomString)
let wordItemRef = self.ref?.child("Users").child(uid).child("LearnedWords").child(randomString)
wordItemRef?.setValue(wordItem.toAnyObject())
presentingViewController?.dismiss(animated: true, completion: nil)
}
So, my Firebase for Date looks like this:
Then, I retrieve this data in another ViewController and add it to the array:
override func viewDidLoad() {
super.viewDidLoad()
// checking if user is in
guard let uid = Auth.auth().currentUser?.uid else {
return
}
// retrieving data from FireBase
ref = Database.database().reference()
databaseHandle = ref?.child("Users").child(uid).child("LearnedWords").observe(.value, with: { (snapshot) in
var newItems: [Word] = []
for item in snapshot.children {
let wordItem = Word(snapshot: item as! DataSnapshot)
newItems.append(wordItem)
}
newItems.sort(by: { $0.date.compare($1.date) == .orderedDescending})
self.words = newItems
self.getAllMessagesSent(snapshot: newItems)
})
}
// retrieve data from Firebase to the View
func getAllMessagesSent(snapshot: [Word]) {
int = snapshot.count - 1
array = snapshot
}
The question:
How is it possible to retrieve the items from array from the nearest day? If today is 16 of August, I should get all items of the nearest day (for example, 8 items from 12 of August, if this date was the last). And should I change the way I'm adding date to Firebase to achieve this?
Edit
I achieved this by comparing the last date in the array with all other dates:
// retrieve data from Firebase to the View
var dateToCompare: String?
var array: [Word] = []
func getAllMessagesSent(snapshot: [Word]) {
int = snapshot.count - 1
array = snapshot
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
// get the nearest item's date and convert it to Date
dateToCompare = array[0].fullDate
let formattedDateToCompare = dateFormatter.date(from: dateToCompare!)
// make array of dates
var dateArray = [NSDate]()
var numberOfWordsThisDay = 1
// formatting all dates in the array
for i in 0..<array.count {
let date1 = dateFormatter.date(from: array[i].fullDate)
dateArray.append(date1! as NSDate)
}
// comparing and in case of cussces increase the number
for i in 1..<array.count {
if Calendar.current.compare(formattedDateToCompare!, to: dateArray[i] as Date, toGranularity: .day) == .orderedSame {
numberOfWordsThisDay += 1
}
}
self.numOfWords.placeholder = "From \(numberOfWordsThisDay) to \(array.count)"
}
It works, but it definitely doesn't look like efficient solution, because I loop over two huge arrays. Is it possible to improve my code? Thanks!

Sorting an Array of Dictionaries with multiple criteria in Swift

I have an array of dictionaries and my dictionary is type [String:AnyObject]. Here is some data:
[{
name = Joe;
score = 50;
favorite = Phone;
startDate = "2015-10-15";
startingTime = "2015-10-15 19:00:00 +0000";
finished = "<null>";
}, {
name = Mark;
score = 60;
favorite = Phone;
startDate = "2015-10-16”;
startingTime = "2015-10-16 19:00:00 +0000";
finished = "<null>";
}, {
name = Joe;
score = 30;
favorite = Phone;
startDate = "2015-10-15";
startingTime = "2015-10-15 19:00:00 +0000";
finished = "<null>";
}]
What I want is to be able to sort these first by name, then by startingTime, then if those both match then by score (I have score stored as a string though).
I know this is terribly wrong but I typed in:
test.sort({ $0.name! < $1.name! })
That gave me an error "Cannot invoke 'sort' with an argument list of type '((_, _) -> _)'."
Can anyone shed some light as to how to do this sort?
** Updated to have code from the view controller with the answer
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var allArray = [AnyObject]()
var array = [String:AnyObject]()
array["name"] = "Joe"
array["score"] = 50 as Int
array["favorite"] = "Phone"
array["startDate"] = "2015-10-15"
let date = NSDate()
array["date"] = date
array["finished"] = nil
allArray.append(array)
array["name"] = "Mark"
array["score"] = 60 as Int
array["favorite"] = "Phone"
array["startDate"] = "2015-10-16"
array["date"] = date
array["finished"] = nil
allArray.append(array)
array["name"] = "Joe"
array["score"] = 30 as Int
array["favorite"] = "Phone"
array["startDate"] = "2015-10-15"
array["date"] = date
array["finished"] = nil
allArray.append(array)
println(allArray)
allArray.sort {
if let name0 = $0["name"] as? String, name1 = $1["name"] as? String
where name0 != name1 {
return name0 < name1
}
// You said 'startingTime' in your question your code showed 'date'
if let date0 = $0["date"] as? NSDate, date1 = $1["date"] as? NSDate
where date0.timeIntervalSince1970 != date1.timeIntervalSince1970 {
return date0.timeIntervalSince1970 < date1.timeIntervalSince1970
}
// You have 'score' as String. I think you would want a numeric type instead
return ($0["score"] as! Int) < ($1["score"] as! Int)
}
println(allArray)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Thanks!
Try being more explicit with the closure parameters if the compiler gets weird like that.
This sort method seems to work for me.
arr = arr.sort { a, b in
if a["name"] == b["name"] {
if a["startingTime"] == b["startingTime"] {
return a["score"] > b["score"]
}
return a["startingTime"] > b["startingTime"]
} else {
return a["name"] > b["name"]
}
}
Just to add my solution to the already crowded answers because none of the existing one look satisfactory to me.
// allArray is as initiated in your viewDidLoad method
let sortedArray = allArray.sort {
if let name0 = $0["name"] as? String, name1 = $1["name"] as? String
where name0 != name1 {
return name0 < name1
}
// You said 'startingTime' in your question but your code showed 'date'
if let date0 = $0["date"] as? NSDate, date1 = $1["date"] as? NSDate
where date0.timeIntervalSince1970 != date1.timeIntervalSince1970 {
return date0.timeIntervalSince1970 < date1.timeIntervalSince1970
}
// You have 'score' as String. I think you would want a numeric type instead
return ($0["score"] as! Int) < ($1["score"] as! Int)
}
The code is riddled with casts because you use AnyObject as the value type.
It looks like this works, the guard is just so I don't have to deal with unwrapping in the comparisons (I'm loving guard because of this, makes the code cleaner IMO)
let test : [[String:AnyObject]] = [["name":"joe", "time":1, "score":5], ["name":"joe", "time":1, "score":3], ["name":"joe", "time":1, "score":7]]
let sorted = test.sort{
guard let name = $0["name"] as? String,
let time = $0["time"] as? Int,
let score = $0["score"] as? Int,
let name1 = $1["name"] as? String,
let time1 = $1["time"] as? Int,
let score1 = $1["score"] as? Int else{
//unwrapping failed, sort is going to be bad
return false
}
if name == name1 {
if time == time1 {
return score < score1
}else {
return time < time1
}
}else {
return name < name1
}
}
print(sorted)
Here are some code fragments that make the given code work better. First add these to the beginning of your file to make dates comparable.
public func ==(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs === rhs || lhs.compare(rhs) == .OrderedSame
}
public func <(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.compare(rhs) == .OrderedAscending
}
extension NSDate: Comparable { }
Then use the syntax below in your method (this is swift 2):
var allArray = [AnyObject]()
var array = [String:AnyObject]()
array["name"] = "Joe"
array["score"] = "50"
array["favorite"] = "Phone"
array["startDate"] = "2015-10-15"
let date = NSDate()
array["startingTime"] = date
array["finished"] = nil
allArray.append(array)
array["name"] = "Mark"
array["score"] = "60"
array["favorite"] = "Phone"
array["startDate"] = "2015-10-16"
array["startingTime"] = date
array["finished"] = nil
allArray.append(array)
array["name"] = "Joe"
array["score"] = "30"
array["favorite"] = "Phone"
array["startDate"] = "2015-10-15"
array["startingTime"] = date
array["finished"] = nil
allArray.append(array)
print(allArray)
allArray.sortInPlace { i,j in (i["name"] as! String) < (j["name"] as! String) || (i["startingTime"] as! NSDate) < (j["startingTime"] as! NSDate) }
I do prefer if you use syntax like this though. It is a more swift way of declaring an array of dictionaries.
let xyz = [
[
"name" : "Joe",
"score" : 50,
"favorite" : "Phone",
"startDate" : "2015-10-15",
"startingTime" : "2015-10-15 19:00:00 +0000",
"finished" : "<null>"
], [
"name" : "Mark",
"score" : 60,
"favorite" : "Phone",
"startDate" : "2015-10-16",
"startingTime" : "2015-10-16 19:00:00 +0000",
"finished" : "<null>"
], [
"name" : "Joe",
"score" : 30,
"favorite" : "Phone",
"startDate" : "2015-10-15",
"startingTime" : "2015-10-15 19:00:00 +0000",
"finished" : "<null>"
]
]
var test = xyz.sort { ($0["name"] as! String) < ($1["name"] as! String) }

Returning a single calendar with calendarWithIdentifier

I'm trying to call a method that will get a calendar when creating an event. This method I'm sure is meant to use calendarWithIdentifier which gets the ID of the
Here's my code for the creating the event and calling the method that will get the calendar. I need to call a specific calendar
var store = EKEventStore()
func applicationDidFinishLaunching(aNotification: NSNotification) {
// ask for permission
// call methods
}
// Create new calendar
func createCalendar() -> EKCalendar? {
var calendar = EKCalendar(forEntityType: EKEntityTypeEvent, eventStore: self.store)
calendar.title = "Calendarname"
// ...
return calendar
}
func createEvent(){
var newEvent : EKEvent = EKEvent(eventStore: store)
var error : NSError? = nil
newEvent.title = "day off"
newEvent.location = "London"
var startDate : String = "2015-07-16";
var dateFmt1 = NSDateFormatter()
dateFmt1.dateFormat = "yyyy-MM-dd"
var date1:NSDate = dateFmt1.dateFromString(startDate)!;
var endDate : String = "2015-07-17";
var dateFmt2 = NSDateFormatter()
dateFmt2.dateFormat = "yyyy-MM-dd"
var date2:NSDate = dateFmt2.dateFromString(endDate)!;
newEvent.startDate = date1
newEvent.endDate = date2
newEvent.notes = "testing the event"
newEvent.calendar = getCalendar()
self.store.saveEvent(newEvent, span: EKSpanThisEvent, commit: true, error: nil)
}
func getCalendar() -> EKCalendar? {
// ...
}
I'm aware of this
func calendarWithIdentifier(_ identifier: String!) -> EKCalendar!
which is from Apple's EventKit Documentation used to return a calendar by id. So I'm using the Calendar's name ("Calendarname") as the argument, but this doesn't seem to be right. It's returning nil.
Can someone help me get the Calendar correctly? Thank you
The method calendarWithIdentifier expects a UID rather than a readable name. You need to retrieve them from your store like this:
var calUid:String = "?"
for cal in store.calendarsForEntityType(EKEntityTypeEvent) {
if cal.title == "Calendarname" { calUid = cal.calendarIdentifier }
}
and later you can use it like
calendar = store.calendarWithIdentifier(calUid)
I was able to get it working. Here's the getCalendar function now:
func getPSACalendar() -> EKCalendar{
var calUID:String = "?"
var cal = store.calendarsForEntityType(EKEntityTypeEvent) as [EKCalendar]
for i in cal {
if i.title == "Calendarname" {
calUID = i.calendarIdentifier
}
}
var calendar = store.calendarWithIdentifier(calUID)
return calendar
}

Resources