diff --git a/JellyfinPlayer.xcodeproj/project.pbxproj b/JellyfinPlayer.xcodeproj/project.pbxproj index 7295069a..a4d9c384 100644 --- a/JellyfinPlayer.xcodeproj/project.pbxproj +++ b/JellyfinPlayer.xcodeproj/project.pbxproj @@ -18,8 +18,6 @@ 53352571265EA0A0006CCA86 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 53352570265EA0A0006CCA86 /* Introspect */; }; 5338F74E263B61370014BF09 /* ConnectToServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5338F74D263B61370014BF09 /* ConnectToServerView.swift */; }; 5338F757263B7E2E0014BF09 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 5338F756263B7E2E0014BF09 /* KeychainSwift */; }; - 533A8E6626748B4F00719967 /* MobileVLCKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 533A8E6526748B4F00719967 /* MobileVLCKit.framework */; platformFilter = ios; }; - 533A8E6726748B4F00719967 /* MobileVLCKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 533A8E6526748B4F00719967 /* MobileVLCKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 535870632669D21600D05A09 /* JellyfinPlayer_tvOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535870622669D21600D05A09 /* JellyfinPlayer_tvOSApp.swift */; }; 535870652669D21600D05A09 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535870642669D21600D05A09 /* ContentView.swift */; }; 535870672669D21700D05A09 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 535870662669D21700D05A09 /* Assets.xcassets */; }; @@ -91,7 +89,14 @@ 628B95382670CDAB0091AF3B /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5377CBFF263B596B003A4E83 /* Model.xcdatamodeld */; }; 628B953A2670CE250091AF3B /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 628B95392670CE250091AF3B /* KeychainSwift */; }; 628B953C2670D2430091AF3B /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621338922660107500A81A2A /* StringExtensions.swift */; }; - 62FA8A522671DE3C004BA2AB /* WidgetEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FA8A512671DE3C004BA2AB /* WidgetEnvironment.swift */; }; + 62EC3527267665D8000E9F2D /* MobileVLCKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53D5E3DC264B47EE00BADDC8 /* MobileVLCKit.xcframework */; }; + 62EC3528267665D8000E9F2D /* MobileVLCKit.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 53D5E3DC264B47EE00BADDC8 /* MobileVLCKit.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 62EC352C26766675000E9F2D /* ServerEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC352B26766675000E9F2D /* ServerEnvironment.swift */; }; + 62EC352D26766675000E9F2D /* ServerEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC352B26766675000E9F2D /* ServerEnvironment.swift */; }; + 62EC352F267666A5000E9F2D /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC352E267666A5000E9F2D /* SessionManager.swift */; }; + 62EC3530267666A5000E9F2D /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC352E267666A5000E9F2D /* SessionManager.swift */; }; + 62EC353126766848000E9F2D /* ServerEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC352B26766675000E9F2D /* ServerEnvironment.swift */; }; + 62EC353226766849000E9F2D /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EC352E267666A5000E9F2D /* SessionManager.swift */; }; AE8C3159265D6F90008AA076 /* bitrates.json in Resources */ = {isa = PBXBuildFile; fileRef = AE8C3158265D6F90008AA076 /* bitrates.json */; }; /* End PBXBuildFile section */ @@ -115,17 +120,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 533A8E6826748B4F00719967 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 533A8E6726748B4F00719967 /* MobileVLCKit.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; 5358709F2669D82900D05A09 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -148,6 +142,17 @@ name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; }; + 62EC3529267665D8000E9F2D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 62EC3528267665D8000E9F2D /* MobileVLCKit.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -212,7 +217,8 @@ 628B952A2670CABE0091AF3B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 628B95362670CB800091AF3B /* JellyfinWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinWidget.swift; sourceTree = ""; }; 628B953B2670D1FC0091AF3B /* WidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetExtension.entitlements; sourceTree = ""; }; - 62FA8A512671DE3C004BA2AB /* WidgetEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetEnvironment.swift; sourceTree = ""; }; + 62EC352B26766675000E9F2D /* ServerEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerEnvironment.swift; sourceTree = ""; }; + 62EC352E267666A5000E9F2D /* SessionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionManager.swift; sourceTree = ""; }; AE8C3158265D6F90008AA076 /* bitrates.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = bitrates.json; sourceTree = ""; }; /* End PBXFileReference section */ @@ -233,11 +239,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 533A8E6626748B4F00719967 /* MobileVLCKit.framework in Frameworks */, 5338F757263B7E2E0014BF09 /* KeychainSwift in Frameworks */, 53352571265EA0A0006CCA86 /* Introspect in Frameworks */, 621C638026672A30004216EA /* NukeUI in Frameworks */, 53A431BD266B0FF20016769F /* JellyfinAPI in Frameworks */, + 62EC3527267665D8000E9F2D /* MobileVLCKit.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -289,6 +295,7 @@ 535870752669D60C00D05A09 /* Shared */ = { isa = PBXGroup; children = ( + 62EC352A26766657000E9F2D /* Shared */, 532175392671BCED005491E6 /* ViewModel */, 621338912660106C00A81A2A /* Extensions */, AE8C3157265D6F5E008AA076 /* Resources */, @@ -407,11 +414,19 @@ 628B95262670CABD0091AF3B /* NextUpWidget.swift */, 628B95282670CABE0091AF3B /* Assets.xcassets */, 628B952A2670CABE0091AF3B /* Info.plist */, - 62FA8A512671DE3C004BA2AB /* WidgetEnvironment.swift */, ); path = WidgetExtension; sourceTree = ""; }; + 62EC352A26766657000E9F2D /* Shared */ = { + isa = PBXGroup; + children = ( + 62EC352B26766675000E9F2D /* ServerEnvironment.swift */, + 62EC352E267666A5000E9F2D /* SessionManager.swift */, + ); + path = Shared; + sourceTree = ""; + }; AE8C3157265D6F5E008AA076 /* Resources */ = { isa = PBXGroup; children = ( @@ -457,7 +472,7 @@ 5377CBEF263B596A003A4E83 /* Resources */, 5302F8322658B74800647A2E /* CopyFiles */, 628B95312670CABE0091AF3B /* Embed App Extensions */, - 533A8E6826748B4F00719967 /* Embed Frameworks */, + 62EC3529267665D8000E9F2D /* Embed Frameworks */, ); buildRules = ( ); @@ -584,6 +599,8 @@ buildActionMask = 2147483647; files = ( 6267B3DC2671139500A7371D /* ImageExtensions.swift in Sources */, + 62EC352D26766675000E9F2D /* ServerEnvironment.swift in Sources */, + 62EC3530267666A5000E9F2D /* SessionManager.swift in Sources */, 535870A82669D8AE00D05A09 /* StringExtensions.swift in Sources */, 6267B3D826710B9800A7371D /* CollectionExtensions.swift in Sources */, 535870A52669D8AE00D05A09 /* ParallaxHeader.swift in Sources */, @@ -630,8 +647,10 @@ 53E4E649263F725B00F67C6B /* MultiSelectorView.swift in Sources */, 621338B32660A07800A81A2A /* LazyView.swift in Sources */, 531AC8BF26750DE20091C7EB /* ImageView.swift in Sources */, + 62EC352F267666A5000E9F2D /* SessionManager.swift in Sources */, 535870AD2669D8DD00D05A09 /* Typings.swift in Sources */, 53C4404E266C75C70049424C /* HandleAPIRequestCompletion.swift in Sources */, + 62EC352C26766675000E9F2D /* ServerEnvironment.swift in Sources */, 6267B3DA2671138200A7371D /* ImageExtensions.swift in Sources */, 5377CBF7263B596A003A4E83 /* ContentView.swift in Sources */, 5389277C263CC3DB0035E14B /* BlurHashDecode.swift in Sources */, @@ -648,6 +667,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 62EC353126766848000E9F2D /* ServerEnvironment.swift in Sources */, 6267B3D42671024A00A7371D /* APIExtensions.swift in Sources */, 6267B3D726710B9700A7371D /* CollectionExtensions.swift in Sources */, 628B953C2670D2430091AF3B /* StringExtensions.swift in Sources */, @@ -655,8 +675,8 @@ 628B95372670CB800091AF3B /* JellyfinWidget.swift in Sources */, 6228B1C22670EB010067FD35 /* PersistenceController.swift in Sources */, 628B95272670CABD0091AF3B /* NextUpWidget.swift in Sources */, - 62FA8A522671DE3C004BA2AB /* WidgetEnvironment.swift in Sources */, 628B95382670CDAB0091AF3B /* Model.xcdatamodeld in Sources */, + 62EC353226766849000E9F2D /* SessionManager.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/JellyfinPlayer.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/JellyfinPlayer.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4cf2aa37..9dacef05 100644 --- a/JellyfinPlayer.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/JellyfinPlayer.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -20,7 +20,7 @@ } }, { - "package": "jellyfin-sdk-swift", + "package": "JellyfinAPI", "repositoryURL": "https://github.com/jellyfin/jellyfin-sdk-swift", "state": { "branch": "main", @@ -29,7 +29,7 @@ } }, { - "package": "keychain-swift", + "package": "KeychainSwift", "repositoryURL": "https://github.com/evgenyneu/keychain-swift", "state": { "branch": null, @@ -56,7 +56,7 @@ } }, { - "package": "SwiftUI-Introspect", + "package": "Introspect", "repositoryURL": "https://github.com/siteline/SwiftUI-Introspect", "state": { "branch": null, diff --git a/Shared/Shared/ServerEnvironment.swift b/Shared/Shared/ServerEnvironment.swift new file mode 100644 index 00000000..71e6a9f8 --- /dev/null +++ b/Shared/Shared/ServerEnvironment.swift @@ -0,0 +1,23 @@ +// + /* + * SwiftFin is subject to the terms of the Mozilla Public + * License, v2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright 2021 Aiden Vigue & Jellyfin Contributors + */ + +import Foundation +import CoreData + +final class ServerEnvironment { + + static let shared = ServerEnvironment() + var server: Server? + + init() { + let serverRequest = NSFetchRequest(entityName: "Server") + let servers = try? PersistenceController.shared.container.viewContext.fetch(serverRequest) as? [Server] + server = servers?.first + } +} diff --git a/WidgetExtension/WidgetEnvironment.swift b/Shared/Shared/SessionManager.swift similarity index 77% rename from WidgetExtension/WidgetEnvironment.swift rename to Shared/Shared/SessionManager.swift index 48c17eda..3f4d2677 100644 --- a/WidgetExtension/WidgetEnvironment.swift +++ b/Shared/Shared/SessionManager.swift @@ -12,26 +12,17 @@ import CoreData import KeychainSwift import UIKit -final class WidgetEnvironment { - static let shared = WidgetEnvironment() - - var server: Server? +final class SessionManager { + + static let shared = SessionManager() var user: SignedInUser? - var header: String? - + var authHeader: String? + init() { - update() - } - - func update() { - let serverRequest = NSFetchRequest(entityName: "Server") - let servers = try? PersistenceController.shared.container.viewContext.fetch(serverRequest) as? [Server] let savedUserRequest = NSFetchRequest(entityName: "SignedInUser") let savedUsers = try? PersistenceController.shared.container.viewContext.fetch(savedUserRequest) as? [SignedInUser] - - server = servers?.first user = savedUsers?.first - + let keychain = KeychainSwift() // need prefix keychain.accessGroup = "9R8RREG67J.me.vigue.jellyfin.sharedKeychain" @@ -51,6 +42,6 @@ final class WidgetEnvironment { header.append("Version=\"\(appVersion ?? "0.0.1")\", ") header.append("Token=\"\(authToken)\"") - self.header = header + self.authHeader = header } } diff --git a/WidgetExtension/NextUpWidget.swift b/WidgetExtension/NextUpWidget.swift index fcc66227..3726c097 100644 --- a/WidgetExtension/NextUpWidget.swift +++ b/WidgetExtension/NextUpWidget.swift @@ -25,18 +25,17 @@ struct NextUpWidgetProvider: TimelineProvider { func getSnapshot(in context: Context, completion: @escaping (NextUpEntry) -> Void) { let currentDate = Date() - WidgetEnvironment.shared.update() - guard let server = WidgetEnvironment.shared.server else { return + guard let server = ServerEnvironment.shared.server else { return DispatchQueue.main.async { completion(NextUpEntry(date: currentDate, items: [], error: WidgetError.emptyServer)) } } - guard let savedUser = WidgetEnvironment.shared.user else { return + guard let savedUser = SessionManager.shared.user else { return DispatchQueue.main.async { completion(NextUpEntry(date: currentDate, items: [], error: WidgetError.emptyUser)) } } - guard let header = WidgetEnvironment.shared.header else { return + guard let header = SessionManager.shared.authHeader else { return DispatchQueue.main.async { completion(NextUpEntry(date: currentDate, items: [], error: WidgetError.emptyHeader)) } @@ -81,20 +80,19 @@ struct NextUpWidgetProvider: TimelineProvider { func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { let currentDate = Date() let entryDate = Calendar.current.date(byAdding: .hour, value: 1, to: currentDate)! - WidgetEnvironment.shared.update() - guard let server = WidgetEnvironment.shared.server else { return + guard let server = ServerEnvironment.shared.server else { return DispatchQueue.main.async { completion(Timeline(entries: [NextUpEntry(date: currentDate, items: [], error: WidgetError.emptyServer)], policy: .after(entryDate))) } } - guard let savedUser = WidgetEnvironment.shared.user else { return + guard let savedUser = SessionManager.shared.user else { return DispatchQueue.main.async { completion(Timeline(entries: [NextUpEntry(date: currentDate, items: [], error: WidgetError.emptyUser)], policy: .after(entryDate))) } } - guard let header = WidgetEnvironment.shared.header else { return + guard let header = SessionManager.shared.authHeader else { return DispatchQueue.main.async { completion(Timeline(entries: [NextUpEntry(date: currentDate, items: [], error: WidgetError.emptyHeader)], policy: .after(entryDate)))