// // Preferences.swift // TagTunes // // Created by Kim Wittenburg on 29.08.15. // Copyright © 2015 Kim Wittenburg. All rights reserved. // import Cocoa /// Internal class to be used in IB to bind to the shared preferences. @objc internal class PreferencesSingleton: NSObject { internal dynamic var sharedPreferences: Preferences { return Preferences.sharedPreferences } } /// A custom interface for the `NSUserDefaults`. It is recommended to use this /// class insted of accessing the user defaults directly to prevent errors due /// to misspelled strings. /// /// All properties in this class are KCO compliant. @objc public class Preferences: NSObject { // MARK: Types internal struct UserDefaultsConstants { static let numberOfSearchResultsKey = "Number of Search Results" static let iTunesStoreKey = "iTunes Store" static let useEnglishTagsKey = "Use English Tags" static let removeSavedItemsKey = "Remove Saved Items" static let useCensoredNamesKey = "Use Censored Names" static let caseSensitiveKey = "Case Sensitive" static let tagSavingBehaviorsKey = "Tag Saving Behaviors" } /// Specifies the way a tag is saved to iTunes. public enum TagSavingBehavior: String { /// Sets the tag's value to the value returned from the Search API. case Save = "save" /// Sets the tag's value to an empty string. case Clear = "clear" /// Does not alter the tag's value. case Ignore = "ignore" } // MARK: Initialization public static var sharedPreferences = Preferences() /// Initializes the default preferences. This method must be called the very /// first time the application is launched. It is perfectly valid to call /// this method every time the application launches. Existing values are not /// overridden. public func initializeDefaultValues() { NSUserDefaults.standardUserDefaults().registerDefaults([ UserDefaultsConstants.numberOfSearchResultsKey: 10, UserDefaultsConstants.iTunesStoreKey: NSLocale.currentLocale().objectForKey(NSLocaleCountryCode)!, UserDefaultsConstants.useEnglishTagsKey: false, UserDefaultsConstants.removeSavedItemsKey: false, UserDefaultsConstants.useCensoredNamesKey: false, UserDefaultsConstants.caseSensitiveKey: true ]) if NSUserDefaults.standardUserDefaults().dictionaryForKey(UserDefaultsConstants.tagSavingBehaviorsKey) == nil { tagSavingBehaviors = [:] } var savingBehaviors = tagSavingBehaviors for tag in Tag.allTags { if savingBehaviors[tag] == nil { savingBehaviors[tag] = tag.isReturnedBySearchAPI ? .Save : .Clear } } tagSavingBehaviors = savingBehaviors } // MARK: General Preferences /// The number of search results that should be displayed. public dynamic var numberOfSearchResults: Int { set { NSUserDefaults.standardUserDefaults().setInteger(newValue, forKey: UserDefaultsConstants.numberOfSearchResultsKey) } get { return NSUserDefaults.standardUserDefaults().integerForKey(UserDefaultsConstants.numberOfSearchResultsKey) } } /// The iTunes Store from which the metadata should be loaded. /// /// The value of this property must be a valid two-letter ISO country code. public dynamic var iTunesStore: String { set { NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: UserDefaultsConstants.iTunesStoreKey) } get { return NSUserDefaults.standardUserDefaults().stringForKey(UserDefaultsConstants.iTunesStoreKey)! } } /// If `true` the Search API Request adds the "lang=en" option. public dynamic var useEnglishTags: Bool { set { NSUserDefaults.standardUserDefaults().setBool(newValue, forKey: UserDefaultsConstants.useEnglishTagsKey) } get { return NSUserDefaults.standardUserDefaults().boolForKey(UserDefaultsConstants.useEnglishTagsKey) } } /// If `true` all saved items are removed from the list after saving. public dynamic var removeSavedItems: Bool { set { NSUserDefaults.standardUserDefaults().setBool(newValue, forKey: UserDefaultsConstants.removeSavedItemsKey) } get { return NSUserDefaults.standardUserDefaults().boolForKey(UserDefaultsConstants.removeSavedItemsKey) } } // MARK: Tag Preferences /// If `true` TagTunes displays and saves censored names instead of the /// original names. public dynamic var useCensoredNames: Bool { set { NSUserDefaults.standardUserDefaults().setBool(newValue, forKey: UserDefaultsConstants.useCensoredNamesKey) } get { return NSUserDefaults.standardUserDefaults().boolForKey(UserDefaultsConstants.useCensoredNamesKey) } } /// If `true` TagTunes ignores cases when comparing track titles and albums. public dynamic var caseSensitive: Bool { set { NSUserDefaults.standardUserDefaults().setBool(newValue, forKey: UserDefaultsConstants.caseSensitiveKey) } get { return NSUserDefaults.standardUserDefaults().boolForKey(UserDefaultsConstants.caseSensitiveKey) } } /// The ways different tags are saved (or not saved). public var tagSavingBehaviors: [Tag: TagSavingBehavior] { set { let savableData = newValue.map { ($0.rawValue, $1.rawValue) } NSUserDefaults.standardUserDefaults().setObject(savableData, forKey: UserDefaultsConstants.tagSavingBehaviorsKey) } get { let savableData = NSUserDefaults.standardUserDefaults().dictionaryForKey(UserDefaultsConstants.tagSavingBehaviorsKey)! return savableData.map { (Tag(rawValue: $0)!, TagSavingBehavior(rawValue: $1 as! String)!) } } } }