Skip to content

Commit

Permalink
Use the Defaults module (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus authored Apr 16, 2018
1 parent 8246676 commit 1e0fd5f
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 16 deletions.
4 changes: 3 additions & 1 deletion .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ opt_in_rules:
- trailing_closure
- block_based_kvo
- discouraged_direct_init
- strict_fileprivate
- joined_default_parameter
- pattern_matching_keywords
- contains_over_first_not_nil
Expand All @@ -42,6 +41,9 @@ opt_in_rules:
- yoda_condition
- required_enum_case
- discouraged_optional_boolean
- empty_string
- untyped_error_in_catch
- discouraged_optional_collection
force_cast: warning
force_unwrapping: warning
number_separator:
Expand Down
16 changes: 10 additions & 6 deletions Gifski.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
5A1FDC6F203F0B050065E0F5 /* libgifski.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E3FD619F201BD29E0087160A /* libgifski.a */; };
C2040B8920435871004EE259 /* GifskiWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2040B8820435871004EE259 /* GifskiWrapper.swift */; };
C2AFA91D204FFEFD00FC5A7F /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2AFA91B204FFEFD00FC5A7F /* MainWindowController.swift */; };
E30557F0207E521F003401A1 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = E30557EF207E521F003401A1 /* Defaults.swift */; };
E317FF132057E24700A80A18 /* CircularProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = E317FF122057E24700A80A18 /* CircularProgress.swift */; };
E317FF1C20583E9800A80A18 /* DockProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = E317FF1B20583E9800A80A18 /* DockProgress.swift */; };
E339F011203820ED003B78FB /* Gifski.swift in Sources */ = {isa = PBXBuildFile; fileRef = E339F010203820ED003B78FB /* Gifski.swift */; };
Expand Down Expand Up @@ -64,6 +65,7 @@
/* Begin PBXFileReference section */
C2040B8820435871004EE259 /* GifskiWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = GifskiWrapper.swift; sourceTree = "<group>"; usesTabs = 1; };
C2AFA91B204FFEFD00FC5A7F /* MainWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MainWindowController.swift; sourceTree = "<group>"; usesTabs = 1; };
E30557EF207E521F003401A1 /* Defaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Defaults.swift; sourceTree = "<group>"; };
E317FF122057E24700A80A18 /* CircularProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularProgress.swift; sourceTree = "<group>"; };
E317FF1B20583E9800A80A18 /* DockProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DockProgress.swift; sourceTree = "<group>"; };
E339F010203820ED003B78FB /* Gifski.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Gifski.swift; sourceTree = "<group>"; usesTabs = 1; };
Expand Down Expand Up @@ -111,6 +113,7 @@
children = (
E317FF122057E24700A80A18 /* CircularProgress.swift */,
E317FF1B20583E9800A80A18 /* DockProgress.swift */,
E30557EF207E521F003401A1 /* Defaults.swift */,
);
path = Vendor;
sourceTree = "<group>";
Expand Down Expand Up @@ -295,15 +298,16 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E339F011203820ED003B78FB /* Gifski.swift in Sources */,
C2AFA91D204FFEFD00FC5A7F /* MainWindowController.swift in Sources */,
E3CB1DD71F7E4CBC00D79BFC /* VideoDropView.swift in Sources */,
E30557F0207E521F003401A1 /* Defaults.swift in Sources */,
E317FF1C20583E9800A80A18 /* DockProgress.swift in Sources */,
E317FF132057E24700A80A18 /* CircularProgress.swift in Sources */,
C2040B8920435871004EE259 /* GifskiWrapper.swift in Sources */,
E3AE62871E5CD2F300035A2F /* AppDelegate.swift in Sources */,
E3D08F6E1E5D7BFD00F465DF /* util.swift in Sources */,
E317FF1C20583E9800A80A18 /* DockProgress.swift in Sources */,
E339F011203820ED003B78FB /* Gifski.swift in Sources */,
C2040B8920435871004EE259 /* GifskiWrapper.swift in Sources */,
E3CB1DD71F7E4CBC00D79BFC /* VideoDropView.swift in Sources */,
E3DF3E88203BD2B900055855 /* SavePanelAccessoryViewController.swift in Sources */,
C2AFA91D204FFEFD00FC5A7F /* MainWindowController.swift in Sources */,
E3AE62871E5CD2F300035A2F /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
9 changes: 6 additions & 3 deletions Gifski/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ extension NSColor {
static let appTheme = NSColor(named: NSColor.Name("Theme"))!
}

extension Defaults.Keys {
static let outputQuality = Defaults.Key<Double>("outputQuality", default: 1)
}

@NSApplicationMain
final class AppDelegate: NSObject, NSApplicationDelegate {
lazy var mainWindowController = MainWindowController()
var hasFinishedLaunching = false
var urlsToConvertOnLaunch: URL!

func applicationWillFinishLaunching(_ notification: Notification) {
defaults.register(defaults: [
UserDefaults.standard.register(defaults: [
"NSApplicationCrashOnExceptions": true,
"NSFullScreenMenuItemEverywhere": false,
"outputQuality": 1
"NSFullScreenMenuItemEverywhere": false
])

NSAppearance.app = .dark
Expand Down
2 changes: 1 addition & 1 deletion Gifski/MainWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ final class MainWindowController: NSWindowController {
let conversion = Gifski.Conversion(
input: inputUrl,
output: outputUrl,
quality: defaults["outputQuality"] as! Double,
quality: defaults[.outputQuality],
dimensions: self.choosenDimensions,
frameRate: self.choosenFrameRate
)
Expand Down
4 changes: 2 additions & 2 deletions Gifski/SavePanelAccessoryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ final class SavePanelAccessoryViewController: NSViewController {
}

qualitySlider.onAction = { _ in
defaults["outputQuality"] = self.qualitySlider.doubleValue
defaults[.outputQuality] = self.qualitySlider.doubleValue
estimateFileSize()
}

Expand All @@ -57,7 +57,7 @@ final class SavePanelAccessoryViewController: NSViewController {
frameRateSlider.maxValue = Double(frameRate)
frameRateSlider.integerValue = frameRate
frameRateSlider.triggerAction()
qualitySlider.doubleValue = defaults["outputQuality"] as! Double
qualitySlider.doubleValue = defaults[.outputQuality]
qualitySlider.triggerAction()
}
}
127 changes: 127 additions & 0 deletions Gifski/Vendor/Defaults.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Vendored from: https://github.com/sindresorhus/Defaults
import Foundation

public final class Defaults {
public class Keys {
fileprivate init() {}
}

public final class Key<T: Codable>: Keys {
fileprivate let name: String
fileprivate let defaultValue: T

public init(_ key: String, default defaultValue: T) {
self.name = key
self.defaultValue = defaultValue
}
}

public final class OptionalKey<T: Codable>: Keys {
fileprivate let name: String

public init(_ key: String) {
self.name = key
}
}

public subscript<T: Codable>(key: Defaults.Key<T>) -> T {
get {
return UserDefaults.standard[key]
}
set {
UserDefaults.standard[key] = newValue
}
}

public subscript<T: Codable>(key: Defaults.OptionalKey<T>) -> T? {
get {
return UserDefaults.standard[key]
}
set {
UserDefaults.standard[key] = newValue
}
}

public func clear() {
for key in UserDefaults.standard.dictionaryRepresentation().keys {
UserDefaults.standard.removeObject(forKey: key)
}
}
}

// Has to be `defaults` lowercase until Swift supports static subscripts…
public let defaults = Defaults()

public extension UserDefaults {
private func _get<T: Codable>(_ key: String) -> T? {
if isNativelySupportedType(T.self) {
return object(forKey: key) as? T
}

guard let text = string(forKey: key),
let data = "[\(text)]".data(using: .utf8) else {
return nil
}

do {
return (try JSONDecoder().decode([T].self, from: data)).first
} catch {
print(error)
}

return nil
}

private func _set<T: Codable>(_ key: String, to value: T) {
if isNativelySupportedType(T.self) {
set(value, forKey: key)
return
}

do {
// Some codable values like URL and enum are encoded as a top-level
// string which JSON can't handle, so we need to wrap it in an array
// We need this: https://forums.swift.org/t/allowing-top-level-fragments-in-jsondecoder/11750
let data = try JSONEncoder().encode([value])
let string = String(data: data, encoding: .utf8)?.dropFirst().dropLast()
set(string, forKey: key)
} catch {
print(error)
}
}

public subscript<T: Codable>(key: Defaults.Key<T>) -> T {
get {
return _get(key.name) ?? key.defaultValue
}
set {
_set(key.name, to: newValue)
}
}

public subscript<T: Codable>(key: Defaults.OptionalKey<T>) -> T? {
get {
return _get(key.name)
}
set {
if let value = newValue {
_set(key.name, to: value)
}
}
}

private func isNativelySupportedType<T>(_ type: T.Type) -> Bool {
switch type {
case is Bool.Type,
is String.Type,
is Int.Type,
is Double.Type,
is Float.Type,
is Date.Type,
is Data.Type:
return true
default:
return false
}
}
}
3 changes: 0 additions & 3 deletions Gifski/util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import Cocoa
import AVFoundation


let defaults = UserDefaults.standard


/**
Convenience function for initializing an object and modifying its properties

Expand Down

0 comments on commit 1e0fd5f

Please sign in to comment.