// // UserDefaultsStore.swift // Feels (iOS) // // Created by Trey Tartt on 1/22/22. // import Foundation class UserDefaultsStore { enum Keys: String { case savedOnboardingData case needsOnboarding case useCloudKit case deleteEnable case mainViewTopHeaderIndex case theme case moodImages case moodTint case personalityPack case customWidget case customMoodTint case customMoodTintUpdateNumber case textColor case showNSFW case shape case daysFilter case firstLaunchDate case hasActiveSubscription case lastVotedDate case contentViewCurrentSelectedHeaderViewBackDays case contentViewHeaderTag case contentViewHeaderTagViewOneViewType case contentViewHeaderTagViewTwoViewType case currentSelectedHeaderViewViewType } static func getOnboarding() -> OnboardingData { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.savedOnboardingData.rawValue) as? Data, let model = try? JSONDecoder().decode(OnboardingData.self, from: data) { return model } else { return OnboardingData() } } static func saveOnboarding(onboardingData: OnboardingData) -> OnboardingData { do { let data = try JSONEncoder().encode(onboardingData) GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.savedOnboardingData.rawValue) return UserDefaultsStore.getOnboarding() } catch { fatalError("error saving") } } static func moodMoodImagable() -> MoodImagable.Type { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.moodImages.rawValue) as? Int, let model = MoodImages.init(rawValue: data) { return model.moodImages } else { return MoodImages.FontAwesome.moodImages } } static func moodTintable() -> MoodTintable.Type { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.moodTint.rawValue) as? Int, let model = MoodTints.init(rawValue: data) { return model.moodTints } else { return MoodTints.Default.moodTints } } static func personalityPackable() -> PersonalityPack { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.personalityPack.rawValue) as? Int, let model = PersonalityPack.init(rawValue: data) { return model } else { return PersonalityPack.Default } } static func theme() -> Theme { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.theme.rawValue) as? Int, let model = Theme.init(rawValue: data) { return model } else { return Theme.system } } static func getCustomWidgets() -> [CustomWidgetModel] { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customWidget.rawValue) as? Data, let model = try? JSONDecoder().decode([CustomWidgetModel].self, from: data) { return model } else { GroupUserDefaults.groupDefaults.removeObject(forKey: UserDefaultsStore.Keys.customWidget.rawValue) let widget = CustomWidgetModel.randomWidget widget.isSaved = true let widgets = [widget] let data = try! JSONEncoder().encode(widgets) GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue) if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customWidget.rawValue) as? Data, let models = try? JSONDecoder().decode([CustomWidgetModel].self, from: data) { let sorted = models.sorted(by: { $0.createdDate < $1.createdDate }) return sorted } else { fatalError("error getting widgets") } } } @discardableResult static func saveCustomWidget(widgetModel: CustomWidgetModel, inUse: Bool) -> [CustomWidgetModel] { do { var existingWidgets = getCustomWidgets() if let exisitingWidget = existingWidgets.firstIndex(where: { $0.uuid == widgetModel.uuid }) { existingWidgets.remove(at: exisitingWidget) // give it differnet uuid so the view updates widgetModel.uuid = UUID().uuidString } if inUse { existingWidgets.forEach({ $0.inUse = false }) widgetModel.inUse = true } existingWidgets.append(widgetModel) existingWidgets.forEach({ $0.isSaved = true }) let data = try JSONEncoder().encode(existingWidgets) GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue) return UserDefaultsStore.getCustomWidgets() } catch { fatalError("error saving") } } @discardableResult static func deleteCustomWidget(withUUID uuid: String) -> [CustomWidgetModel] { do { var existingWidgets = getCustomWidgets() if let exisitingWidget = existingWidgets.firstIndex(where: { $0.uuid == uuid }) { existingWidgets.remove(at: exisitingWidget) } if existingWidgets.count == 0 { let widget = CustomWidgetModel.randomWidget widget.isSaved = true widget.inUse = true existingWidgets.append(widget) } if let _ = existingWidgets.first(where: { $0.inUse == true }) {} else { if let first = existingWidgets.first { first.inUse = true } } let data = try JSONEncoder().encode(existingWidgets) GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue) return UserDefaultsStore.getCustomWidgets() } catch { fatalError("error saving") } } static func getCustomMoodTint() -> SavedMoodTint { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customMoodTint.rawValue) as? Data{ do { let model = try JSONDecoder().decode(SavedMoodTint.self, from: data) return model } catch { print(error) } } return SavedMoodTint() } static func getCustomBGShape() -> BGShape { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.shape.rawValue) as? Int, let model = BGShape.init(rawValue: data) { return model } else { return BGShape.circle } } @discardableResult static func saveCustomMoodTint(customTint: SavedMoodTint) -> SavedMoodTint { do { let data = try JSONEncoder().encode(customTint) GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customMoodTint.rawValue) return UserDefaultsStore.getCustomMoodTint() } catch { print(error) fatalError("error saving") } } @discardableResult static func saveDaysFilter(days: [Int]) -> [Int] { GroupUserDefaults.groupDefaults.set(days, forKey: UserDefaultsStore.Keys.daysFilter.rawValue) return UserDefaultsStore.getDaysFilter() } static func getDaysFilter() -> [Int] { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.daysFilter.rawValue) as? [Int] { return data } else { return [1,2,3,4,5,6,7] } } }