Skip to content

Commit

Permalink
Update filter preservation to use Codable compatible serialization to…
Browse files Browse the repository at this point in the history
… faciliate removing SwiftyJSON
  • Loading branch information
allenhumphreys committed Jul 13, 2020
1 parent 1da792a commit e5862ee
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 142 deletions.
2 changes: 0 additions & 2 deletions Cartfile
@@ -1,5 +1,3 @@
github "SwiftyJSON/SwiftyJSON" ~> 5.0

github "ReactiveX/RxSwift" ~> 5.0

github "realm/realm-cocoa" ~> 4.0.0
Expand Down
1 change: 0 additions & 1 deletion Cartfile.resolved
@@ -1,6 +1,5 @@
github "ReactiveX/RxSwift" "5.1.1"
github "RxSwiftCommunity/RxRealm" "2.0.0"
github "SwiftyJSON/SwiftyJSON" "5.0.0"
github "apple/swift-protobuf" "1.9.0"
github "bustoutsolutions/siesta" "1.5.1"
github "insidegui/ChromeCastCore" "0.2.1"
Expand Down
8 changes: 4 additions & 4 deletions WWDC.xcodeproj/project.pbxproj
Expand Up @@ -21,6 +21,7 @@
4D7482CA20FF735D008D156C /* WWDCWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D7482C920FF735D008D156C /* WWDCWindowController.swift */; };
4D7482CC20FFAA09008D156C /* DownloadsStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D7482CB20FFAA09008D156C /* DownloadsStatusViewController.swift */; };
4D82B5F82343DABF005AC3EC /* RxRelay.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4D82B5F72343DABE005AC3EC /* RxRelay.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4D9EE96424BCE097001B1720 /* FilterState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D9EE96324BCE097001B1720 /* FilterState.swift */; };
4DA25DC821063CD500762BBD /* TitleBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DA25DC721063CD500762BBD /* TitleBarViewController.swift */; };
4DA25DCC21064B4800762BBD /* WWDCTabViewControllerTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DA25DCB21064B4800762BBD /* WWDCTabViewControllerTabBar.swift */; };
4DA83FE222AC3F2F0062DB8B /* PUIVibrantBackgroundButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DA83FE122AC3F2F0062DB8B /* PUIVibrantBackgroundButton.swift */; };
Expand Down Expand Up @@ -85,7 +86,6 @@
DD65FD4C1E489FF50054DD35 /* SessionAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD65FD4B1E489FF50054DD35 /* SessionAsset.swift */; };
DD65FD4D1E48A01B0054DD35 /* Realm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD5F517F1E47DE7E0017F9EC /* Realm.framework */; };
DD65FD4E1E48A01B0054DD35 /* RealmSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD5F51801E47DE7E0017F9EC /* RealmSwift.framework */; };
DD65FD4F1E48A01B0054DD35 /* SwiftyJSON.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD5F51841E47DE7E0017F9EC /* SwiftyJSON.framework */; };
DD65FD511E48A05C0054DD35 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD65FD501E48A05C0054DD35 /* Session.swift */; };
DD65FD531E48A06A0054DD35 /* NewsItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD65FD521E48A06A0054DD35 /* NewsItem.swift */; };
DD65FD551E48A0A70054DD35 /* Room.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD65FD541E48A0A70054DD35 /* Room.swift */; };
Expand Down Expand Up @@ -187,7 +187,6 @@
DDBCEC88228AC9C5009300CF /* RxCocoa.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DD5F51811E47DE7E0017F9EC /* RxCocoa.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
DDBCEC89228AC9C5009300CF /* RxRealm.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DD5F51821E47DE7E0017F9EC /* RxRealm.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
DDBCEC8A228AC9C5009300CF /* RxSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DD5F51831E47DE7E0017F9EC /* RxSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
DDBCEC8B228AC9C5009300CF /* SwiftyJSON.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DD5F51841E47DE7E0017F9EC /* SwiftyJSON.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
DDBCEC9A228AD2D0009300CF /* CloudKitCodable.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DDBCEC99228AD2CC009300CF /* CloudKitCodable.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
DDBCEC9C228AD30C009300CF /* SwiftProtobuf.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DDBCEC9B228AD309009300CF /* SwiftProtobuf.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
DDC347C220B1E6B700CFF11C /* CloudKitCodable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDC347C020B1E69700CFF11C /* CloudKitCodable.framework */; };
Expand Down Expand Up @@ -417,7 +416,6 @@
DDBCEC88228AC9C5009300CF /* RxCocoa.framework in Embed Frameworks */,
DDBCEC89228AC9C5009300CF /* RxRealm.framework in Embed Frameworks */,
DDBCEC8A228AC9C5009300CF /* RxSwift.framework in Embed Frameworks */,
DDBCEC8B228AC9C5009300CF /* SwiftyJSON.framework in Embed Frameworks */,
DD36A4DE1E478D7E00B2EA88 /* ConfCore.framework in Embed Frameworks */,
DDD68514247C3B00001BB700 /* Transcripts.framework in Embed Frameworks */,
DDF7219E1ECA12780054C503 /* PlayerUI.framework in Embed Frameworks */,
Expand Down Expand Up @@ -453,6 +451,7 @@
4D7482C920FF735D008D156C /* WWDCWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WWDCWindowController.swift; sourceTree = "<group>"; };
4D7482CB20FFAA09008D156C /* DownloadsStatusViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadsStatusViewController.swift; sourceTree = "<group>"; };
4D82B5F72343DABE005AC3EC /* RxRelay.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxRelay.framework; path = Carthage/Build/Mac/RxRelay.framework; sourceTree = "<group>"; };
4D9EE96324BCE097001B1720 /* FilterState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterState.swift; sourceTree = "<group>"; };
4DA25DC721063CD500762BBD /* TitleBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleBarViewController.swift; sourceTree = "<group>"; };
4DA25DCB21064B4800762BBD /* WWDCTabViewControllerTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WWDCTabViewControllerTabBar.swift; sourceTree = "<group>"; };
4DA83FE122AC3F2F0062DB8B /* PUIVibrantBackgroundButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PUIVibrantBackgroundButton.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -787,7 +786,6 @@
DD3C4D251E561E4D0093BBD0 /* RxRealm.framework in Frameworks */,
DD3C4D261E561E4E0093BBD0 /* RxSwift.framework in Frameworks */,
DDAE7C551E5BC6CD00CEA205 /* Siesta.framework in Frameworks */,
DD65FD4F1E48A01B0054DD35 /* SwiftyJSON.framework in Frameworks */,
DDC347C220B1E6B700CFF11C /* CloudKitCodable.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -1319,6 +1317,7 @@
DDEDFCEE1ED92785002477C8 /* MultipleChoiceFilter.swift */,
DDEDFCF01ED927A4002477C8 /* ToggleFilter.swift */,
DDEDFCF21ED92F2A002477C8 /* TextualFilter.swift */,
4D9EE96324BCE097001B1720 /* FilterState.swift */,
);
name = Search;
sourceTree = "<group>";
Expand Down Expand Up @@ -2341,6 +2340,7 @@
DDDF807E20BA4FFA007284F8 /* WWDCHorizontalScrollView.swift in Sources */,
DD7F387D1EAC113A002D8C00 /* WWDCTextField.swift in Sources */,
DDB352801EC7C4CA00254815 /* Arguments.swift in Sources */,
4D9EE96424BCE097001B1720 /* FilterState.swift in Sources */,
DD7F387A1EAC0CE3002D8C00 /* SessionSummaryViewController.swift in Sources */,
DD382B7E1EAC3565009760C4 /* TabItemView.swift in Sources */,
DD382B7B1EAC345F009760C4 /* MaskImageView.m in Sources */,
Expand Down
52 changes: 52 additions & 0 deletions WWDC/FilterState.swift
@@ -0,0 +1,52 @@
//
// FilterState.swift
// WWDC
//
// Created by Allen Humphreys on 7/13/20.
// Copyright © 2020 Guilherme Rambo. All rights reserved.
//

import Foundation

struct WWDCFiltersState: Codable {
let scheduleTab, videosTab: WWDCFiltersState.Tab

enum CodingKeys: String, CodingKey {
// Key names are for backward compatibility with the old way of serializing the state
case scheduleTab = "WWDC.MainWindowTab.schedule"
case videosTab = "WWDC.MainWindowTab.videos"
}
}

extension WWDCFiltersState {
struct Tab: Codable {
let focus, event, track: MultipleChoiceFilter.State?
let isDownloaded, isFavorite, hasBookmarks, isUnwatched: ToggleFilter.State?
let text: TextualFilter.State?
}
}

extension WWDCFiltersState.Tab {
init(filters: [FilterType]) {
self = .init(
focus: filters.get(MultipleChoiceFilter.self, for: .focus)?.state,
event: filters.get(MultipleChoiceFilter.self, for: .event)?.state,
track: filters.get(MultipleChoiceFilter.self, for: .track)?.state,
isDownloaded: filters.get(ToggleFilter.self, for: .isDownloaded)?.state,
isFavorite: filters.get(ToggleFilter.self, for: .isFavorite)?.state,
hasBookmarks: filters.get(ToggleFilter.self, for: .hasBookmarks)?.state,
isUnwatched: filters.get(ToggleFilter.self, for: .isUnwatched)?.state,
text: filters.get(TextualFilter.self, for: .text)?.state
)
}
}

extension Array where Element == FilterType {
func get<T: FilterType>(_ type: T.Type, for identifier: FilterIdentifier) -> T? {
let result = self.first { (filter) -> Bool in
return filter.identifier == identifier && filter is T
}

return result as? T
}
}
36 changes: 1 addition & 35 deletions WWDC/FilterType.swift
Expand Up @@ -8,47 +8,13 @@

import Foundation

typealias WWDCFiltersStateDictionary = [ String : [ FilterIdentifier.RawValue: WWDCFilterTypeDictionary ] ]
typealias WWDCFilterTypeDictionary = [ String: Any ]

protocol FilterType {

var identifier: String { get set }
var identifier: FilterIdentifier { get set }
var isEmpty: Bool { get }
var predicate: NSPredicate? { get }
mutating func reset()
func dictionaryRepresentation() -> WWDCFilterTypeDictionary

}

// Can't use WWDCFilterTypeDictionary as Value's type, likely a bug in Swift
extension Dictionary where Key == String, Value == [ String: Any ] {

init?(filters: [FilterType]) {

self = [String: WWDCFilterTypeDictionary]()

for filter in filters {

guard let filterID = FilterIdentifier(rawValue: filter.identifier) else {
continue
}

switch filterID {
case .text:
//TextualFilter
self[filterID.rawValue] = filter.dictionaryRepresentation()

case .event, .focus, .track:
//MultipleChoiceFilter
self[filterID.rawValue] = filter.dictionaryRepresentation()

case .isFavorite, .isDownloaded, .isUnwatched, .hasBookmarks:
//ToggleFilters
self[filterID.rawValue] = filter.dictionaryRepresentation()
}
}
}
}

extension Array where Element == FilterType {
Expand Down
38 changes: 12 additions & 26 deletions WWDC/MultipleChoiceFilter.swift
Expand Up @@ -8,10 +8,10 @@

import Foundation

struct FilterOption: Equatable {
struct FilterOption: Equatable, Codable {
let title: String
let value: String
let isNegative: Bool
var isNegative: Bool = false

init(title: String, value: String, isNegative: Bool = false) {
self.title = title
Expand All @@ -23,13 +23,8 @@ struct FilterOption: Equatable {
return FilterOption(title: newTitle, value: value, isNegative: true)
}

func dictionaryRepresentation() -> [String: String] {
var dictionary = [String: String]()

dictionary["value"] = value
dictionary["title"] = title

return dictionary
enum CodingKeys: String, CodingKey {
case value, title
}
}

Expand All @@ -50,21 +45,11 @@ extension Array where Element == FilterOption {
}
}

func dictionaryRepresentation() -> [[String: String]] {
var array = [[String: String]]()

for option in self {
array.append(option.dictionaryRepresentation())
}

return array
}

}

struct MultipleChoiceFilter: FilterType {

var identifier: String
var identifier: FilterIdentifier
var isSubquery: Bool
var collectionKey: String
var modelKey: String
Expand Down Expand Up @@ -118,7 +103,7 @@ struct MultipleChoiceFilter: FilterType {
return NSCompoundPredicate(orPredicateWithSubpredicates: subpredicates)
}

init(identifier: String, isSubquery: Bool, collectionKey: String, modelKey: String, options: [FilterOption], selectedOptions: [FilterOption], emptyTitle: String) {
init(identifier: FilterIdentifier, isSubquery: Bool, collectionKey: String, modelKey: String, options: [FilterOption], selectedOptions: [FilterOption], emptyTitle: String) {
self.identifier = identifier
self.isSubquery = isSubquery
self.collectionKey = collectionKey
Expand All @@ -134,11 +119,12 @@ struct MultipleChoiceFilter: FilterType {
selectedOptions = []
}

func dictionaryRepresentation() -> WWDCFilterTypeDictionary {
var dictionary: WWDCFilterTypeDictionary = WWDCFilterTypeDictionary()

dictionary["selectedOptions"] = selectedOptions.dictionaryRepresentation()
var state: State {
State(selectedOptions: selectedOptions)
}

return dictionary
struct State: Codable {
let selectedOptions: [FilterOption]
}
}

13 changes: 3 additions & 10 deletions WWDC/Preferences.swift
Expand Up @@ -8,7 +8,6 @@

import Foundation
import ConfCore
import SwiftyJSON

extension Notification.Name {
static let LocalVideoStoragePathPreferenceDidChange = Notification.Name("LocalVideoStoragePathPreferenceDidChange")
Expand Down Expand Up @@ -81,18 +80,12 @@ final class Preferences {
}
}

var filtersState: JSON? {
var filtersState: String? {
get {
if let string = defaults.object(forKey: #function) as? String {
return JSON(parseJSON: string)
} else {
return nil
}
defaults.object(forKey: #function) as? String
}
set {
if let myString = newValue?.rawString() {
defaults.set(myString, forKey: #function)
}
defaults.set(newValue, forKey: #function)
}
}

Expand Down

0 comments on commit e5862ee

Please sign in to comment.