I am trying to load my JSON Data into FSCalendar.
I understand from the documentation that when you use an array that can be show in the calendar with the dots. I am wanting to do that same thing but instead to have the dots appear from my dates listed in my JSON file. I have loaded the JSON file into my bundle as well as made a function to load the JSON data and I have created a structure.
My problem comes in when I am trying to use an array from the structure and then load that array into the "func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {" function. I have been working on this for a while and could use some help. Thanks
JSON Data: - I titled the JSON file data.json
[
{
"event": "Christmas",
"date": [
"2021-01-02",
"2021-01-03",
"2021-01-04"
]
}
]
View Controller:
import UIKit
import FSCalendar
class ViewController: UIViewController, FSCalendarDelegate, FSCalendarDataSource, FSCalendarDelegateAppearance {
//MARK: - calendar variables
@IBOutlet var calendar: FSCalendar!
@IBOutlet weak var dateLabel: UILabel!
fileprivate let gregorian: Calendar = Calendar(identifier: .gregorian)
fileprivate lazy var dateFormatter1: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd"
return formatter
}()
fileprivate lazy var dateFormatter2: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
// These are just test data to see the dots on the calendar
var datesWithEvents = ["2021-01-15","2021-01-16","2021-01-17","2021-01-18"]
var datesWithMultipleEvents = ["2021-01-20","2021-01-21","2021-01-22","2021-01-23"]
//MARK: - JSON variable
// var result: Results?
let data = DataLoader().eventData
//MARK: - viewdidload
override func viewDidLoad() {
super.viewDidLoad()
// parseJSON()
let data = DataLoader().eventData
print(data)
calendar.delegate = self
calendar.dataSource = self
}
deinit {
print("(#function)")
}
//MARK: - calendar functions
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
let formatter = DateFormatter()
formatter.dateFormat = "EEEE MM-dd-YYYY"
let string = formatter.string(from: date)
print("(string)")
}
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventDefaultColorsFor date: Date) -> [UIColor]? {
let key = self.dateFormatter2.string(from: date)
// this is the test with the hard coded arrays, I think i need to
implement the JSON here but am not sure how
if self.datesWithMultipleEvents.contains(key) {
return [UIColor.magenta, appearance.eventDefaultColor, UIColor.red]
}
return nil
}
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter2.string(from: date)
if self.datesWithEvents.contains(dateString) {
return 1
}
if self.datesWithMultipleEvents.contains(dateString) {
return 3
}
return 0
}
Data Model:
struct EventsData: Codable {
var event: String
var date: [String]
}
JSON loader:
import Foundation
public class DataLoader {
@Published var eventData = [EventsData]()
init() {
load()
}
func load() {
if let fileLocation = Bundle.main.url(forResource: "data", withExtension: "json") {
//do catch incase of error
do {
let data = try Data(contentsOf: fileLocation)
let jsonDecoder = JSONDecoder()
let dataFromJson = try jsonDecoder.decode([EventsData].self, from: data)
self.eventData = dataFromJson
} catch {
print(error)
}
}
}
}
EDIT:
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter2.string(from: date)
if self.eventData.contains(where: //<#T##(EventsData) throws -> Bool#>) //How to get this to do the contains like in the next if statement
if self.datesWithEvents.contains(dateString) {
return 1
}
if self.datesWithMultipleEvents.contains(dateString) {
return 3
}
return 0
}