diff --git a/ConfCore/Download.swift b/ConfCore/Download.swift new file mode 100644 index 0000000..47087ab --- /dev/null +++ b/ConfCore/Download.swift @@ -0,0 +1,52 @@ +// +// Download.swift +// WWDC +// +// Created by Guilherme Rambo on 06/05/17. +// Copyright © 2017 Guilherme Rambo. All rights reserved. +// + +import Cocoa +import RealmSwift + +public enum DownloadStatus: String { + case none + case downloading + case paused + case failed + case completed +} + +/// Defines a download for a session's asset +public class Download: Object { + + /// Unique identifier + public dynamic var identifier = UUID().uuidString + + /// When the download was started + public dynamic var createdAt = Date() + + /// The current progress of the download (from 0 to 1) + public dynamic var progress: Double = 0.0 + + /// The raw status of the download + internal dynamic var rawStatus: String = DownloadStatus.none.rawValue + + /// The status of the download + public var status: DownloadStatus { + get { + return DownloadStatus(rawValue: rawStatus) ?? .none + } + set { + rawStatus = newValue.rawValue + } + } + + /// The asset this download is associated with + public let asset = LinkingObjects(fromType: SessionAsset.self, property: "downloads") + + public override class func primaryKey() -> String? { + return "identifier" + } + +} diff --git a/ConfCore/LiveVideosAdapter.swift b/ConfCore/LiveVideosAdapter.swift index 64c7516..2089d67 100644 --- a/ConfCore/LiveVideosAdapter.swift +++ b/ConfCore/LiveVideosAdapter.swift @@ -35,7 +35,7 @@ final class LiveVideosAdapter: Adapter { // Live assets are always for the current year asset.year = Calendar.current.component(.year, from: Date()) asset.sessionId = sessionId - asset.assetType = SessionAssetType.liveStreamVideo.rawValue + asset.rawAssetType = SessionAssetType.liveStreamVideo.rawValue asset.remoteURL = url return .success(asset) diff --git a/ConfCore/SessionAsset.swift b/ConfCore/SessionAsset.swift index 132c5d7..75218fd 100644 --- a/ConfCore/SessionAsset.swift +++ b/ConfCore/SessionAsset.swift @@ -10,6 +10,7 @@ import Cocoa import RealmSwift public enum SessionAssetType: String { + case none case hdVideo = "WWDCSessionAssetTypeHDVideo" case sdVideo = "WWDCSessionAssetTypeSDVideo" case image = "WWDCSessionAssetTypeShelfImage" @@ -30,7 +31,16 @@ public class SessionAsset: Object { /// - WWDCSessionAssetTypeSlidesPDF /// - WWDCSessionAssetTypeStreamingVideo /// - WWDCSessionAssetTypeWebpageURL - public dynamic var assetType = "" + internal dynamic var rawAssetType = "" + + public var assetType: SessionAssetType { + get { + return SessionAssetType(rawValue: rawAssetType) ?? .none + } + set { + rawAssetType = newValue.rawValue + } + } /// The year of the session this asset belongs to public dynamic var year = 0 @@ -44,12 +54,12 @@ public class SessionAsset: Object { /// Relative local URL to save the asset to when downloading public dynamic var relativeLocalURL = "" - /// Whether this asset has been download or not - public dynamic var isDownloaded = false - /// The session this asset belongs to public let session = LinkingObjects(fromType: Session.self, property: "assets") + /// The downloads for this asset + public let downloads = List() + public override class func primaryKey() -> String? { return "remoteURL" } diff --git a/ConfCore/SessionAssetsAdapter.swift b/ConfCore/SessionAssetsAdapter.swift index 0d078e5..c715c39 100644 --- a/ConfCore/SessionAssetsAdapter.swift +++ b/ConfCore/SessionAssetsAdapter.swift @@ -42,7 +42,7 @@ final class SessionAssetsJSONAdapter: Adapter { var output = [SessionAsset]() let streaming = SessionAsset() - streaming.assetType = SessionAssetType.streamingVideo.rawValue + streaming.rawAssetType = SessionAssetType.streamingVideo.rawValue streaming.remoteURL = url streaming.year = year streaming.sessionId = sessionId @@ -50,7 +50,7 @@ final class SessionAssetsJSONAdapter: Adapter { if let hd = input[AssetKeys.download_hd].string { let hdVideo = SessionAsset() - hdVideo.assetType = SessionAssetType.hdVideo.rawValue + hdVideo.rawAssetType = SessionAssetType.hdVideo.rawValue hdVideo.remoteURL = hd hdVideo.year = year hdVideo.sessionId = sessionId @@ -63,7 +63,7 @@ final class SessionAssetsJSONAdapter: Adapter { if let sd = input[AssetKeys.download_sd].string { let sdVideo = SessionAsset() - sdVideo.assetType = SessionAssetType.sdVideo.rawValue + sdVideo.rawAssetType = SessionAssetType.sdVideo.rawValue sdVideo.remoteURL = sd sdVideo.year = year sdVideo.sessionId = sessionId @@ -76,7 +76,7 @@ final class SessionAssetsJSONAdapter: Adapter { if let slides = input[AssetKeys.slides].string { let slidesAsset = SessionAsset() - slidesAsset.assetType = SessionAssetType.slides.rawValue + slidesAsset.rawAssetType = SessionAssetType.slides.rawValue slidesAsset.remoteURL = slides slidesAsset.year = year slidesAsset.sessionId = sessionId @@ -86,7 +86,7 @@ final class SessionAssetsJSONAdapter: Adapter { if let webpage = input[AssetKeys.webpageURL].string { let webpageAsset = SessionAsset() - webpageAsset.assetType = SessionAssetType.webpage.rawValue + webpageAsset.rawAssetType = SessionAssetType.webpage.rawValue webpageAsset.remoteURL = webpage webpageAsset.year = year webpageAsset.sessionId = sessionId @@ -96,7 +96,7 @@ final class SessionAssetsJSONAdapter: Adapter { if let image = input[AssetKeys.images][AssetKeys.shelf].string { let imageAsset = SessionAsset() - imageAsset.assetType = SessionAssetType.image.rawValue + imageAsset.rawAssetType = SessionAssetType.image.rawValue imageAsset.remoteURL = image imageAsset.year = year imageAsset.sessionId = sessionId diff --git a/WWDC.xcodeproj/project.pbxproj b/WWDC.xcodeproj/project.pbxproj index 2e04f19..4fbb5af 100644 --- a/WWDC.xcodeproj/project.pbxproj +++ b/WWDC.xcodeproj/project.pbxproj @@ -126,6 +126,7 @@ DDF32EB91EBE65B50028E39D /* AppCoordinator+Shelf.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF32EB81EBE65B50028E39D /* AppCoordinator+Shelf.swift */; }; DDF32EBB1EBE65DD0028E39D /* AppCoordinator+SessionActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF32EBA1EBE65DD0028E39D /* AppCoordinator+SessionActions.swift */; }; DDF32EBF1EBE68EE0028E39D /* NSTableView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF32EBE1EBE68EE0028E39D /* NSTableView+Rx.swift */; }; + DDFA10BD1EBEA584001DCF66 /* Download.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFA10BC1EBEA584001DCF66 /* Download.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -324,6 +325,7 @@ DDF32EB81EBE65B50028E39D /* AppCoordinator+Shelf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AppCoordinator+Shelf.swift"; sourceTree = ""; }; DDF32EBA1EBE65DD0028E39D /* AppCoordinator+SessionActions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AppCoordinator+SessionActions.swift"; sourceTree = ""; }; DDF32EBE1EBE68EE0028E39D /* NSTableView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTableView+Rx.swift"; sourceTree = ""; }; + DDFA10BC1EBEA584001DCF66 /* Download.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Download.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -606,6 +608,7 @@ isa = PBXGroup; children = ( DD65FD6A1E48BD9F0054DD35 /* Favorite.swift */, + DDFA10BC1EBEA584001DCF66 /* Download.swift */, DD65FD6C1E48BE270054DD35 /* Bookmark.swift */, ); name = UserDefined; @@ -1034,6 +1037,7 @@ DD65FD6B1E48BD9F0054DD35 /* Favorite.swift in Sources */, DD65FD511E48A05C0054DD35 /* Session.swift in Sources */, DD34DA0B1E4AB3E400F25C45 /* RoomsJSONAdapter.swift in Sources */, + DDFA10BD1EBEA584001DCF66 /* Download.swift in Sources */, DD65FD531E48A06A0054DD35 /* NewsItem.swift in Sources */, DDD3797D1E4AB655005FE876 /* TracksJSONAdapter.swift in Sources */, DD65FD5D1E48A11F0054DD35 /* Track.swift in Sources */, diff --git a/WWDC/AppCoordinator.swift b/WWDC/AppCoordinator.swift index df38d73..25f14be 100644 --- a/WWDC/AppCoordinator.swift +++ b/WWDC/AppCoordinator.swift @@ -29,7 +29,10 @@ final class AppCoordinator { init(windowController: MainWindowController) { let filePath = PathUtil.appSupportPath + "/ConfCore.realm" - let realmConfig = Realm.Configuration(fileURL: URL(fileURLWithPath: filePath)) + + var realmConfig = Realm.Configuration(fileURL: URL(fileURLWithPath: filePath)) + realmConfig.schemaVersion = 2 + realmConfig.migrationBlock = { _, _ in } let client = AppleAPIClient(environment: .current) diff --git a/WWDC/PlaybackViewModel.swift b/WWDC/PlaybackViewModel.swift index 87a4527..7b7fcd1 100644 --- a/WWDC/PlaybackViewModel.swift +++ b/WWDC/PlaybackViewModel.swift @@ -31,7 +31,7 @@ enum PlaybackError: Error { extension Session { func asset(of type: SessionAssetType) -> SessionAsset? { - return assets.filter({ $0.assetType == type.rawValue }).first + return assets.filter({ $0.assetType == type }).first } }