add Defaults package

replaced UserDefaults.default with Defaults
add prefer language settings
This commit is contained in:
PangMo5 2021-06-25 17:02:24 +09:00
parent 28d2136a25
commit 3ee33461d3
12 changed files with 126 additions and 60 deletions

View File

@ -12,6 +12,7 @@ import TVVLCKit
import MediaPlayer import MediaPlayer
import JellyfinAPI import JellyfinAPI
import Combine import Combine
import Defaults
protocol VideoPlayerSettingsDelegate: AnyObject { protocol VideoPlayerSettingsDelegate: AnyObject {
func selectNew(audioTrack id: Int32) func selectNew(audioTrack id: Int32)
@ -149,8 +150,7 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
func fetchVideo() { func fetchVideo() {
// Fetch max bitrate from UserDefaults depending on current connection mode // Fetch max bitrate from UserDefaults depending on current connection mode
let defaults = UserDefaults.standard let maxBitrate = Defaults[.inNetworkBandwidth]
let maxBitrate = defaults.integer(forKey: "InNetworkBandwidth")
// Build a device profile // Build a device profile
let builder = DeviceProfileBuilder() let builder = DeviceProfileBuilder()

View File

@ -133,6 +133,10 @@
628B95382670CDAB0091AF3B /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5377CBFF263B596B003A4E83 /* Model.xcdatamodeld */; }; 628B95382670CDAB0091AF3B /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5377CBFF263B596B003A4E83 /* Model.xcdatamodeld */; };
628B953A2670CE250091AF3B /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 628B95392670CE250091AF3B /* KeychainSwift */; }; 628B953A2670CE250091AF3B /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 628B95392670CE250091AF3B /* KeychainSwift */; };
628B953C2670D2430091AF3B /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621338922660107500A81A2A /* StringExtensions.swift */; }; 628B953C2670D2430091AF3B /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621338922660107500A81A2A /* StringExtensions.swift */; };
62CB3F462685BAF7003D0A6F /* Defaults in Frameworks */ = {isa = PBXBuildFile; productRef = 62CB3F452685BAF7003D0A6F /* Defaults */; };
62CB3F482685BB3B003D0A6F /* Defaults in Frameworks */ = {isa = PBXBuildFile; productRef = 62CB3F472685BB3B003D0A6F /* Defaults */; };
62CB3F4B2685BB77003D0A6F /* DefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */; };
62CB3F4C2685BB77003D0A6F /* DefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */; };
62E632DA267D2BC40063E547 /* LatestMediaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632D9267D2BC40063E547 /* LatestMediaViewModel.swift */; }; 62E632DA267D2BC40063E547 /* LatestMediaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632D9267D2BC40063E547 /* LatestMediaViewModel.swift */; };
62E632DC267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; }; 62E632DC267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; };
62E632DD267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; }; 62E632DD267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; };
@ -304,6 +308,7 @@
628B952A2670CABE0091AF3B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 628B952A2670CABE0091AF3B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
628B95362670CB800091AF3B /* JellyfinWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinWidget.swift; sourceTree = "<group>"; }; 628B95362670CB800091AF3B /* JellyfinWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinWidget.swift; sourceTree = "<group>"; };
628B953B2670D1FC0091AF3B /* WidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetExtension.entitlements; sourceTree = "<group>"; }; 628B953B2670D1FC0091AF3B /* WidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetExtension.entitlements; sourceTree = "<group>"; };
62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultsExtension.swift; sourceTree = "<group>"; };
62E632D9267D2BC40063E547 /* LatestMediaViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestMediaViewModel.swift; sourceTree = "<group>"; }; 62E632D9267D2BC40063E547 /* LatestMediaViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestMediaViewModel.swift; sourceTree = "<group>"; };
62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibrarySearchViewModel.swift; sourceTree = "<group>"; }; 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibrarySearchViewModel.swift; sourceTree = "<group>"; };
62E632DF267D30CA0063E547 /* LibraryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryViewModel.swift; sourceTree = "<group>"; }; 62E632DF267D30CA0063E547 /* LibraryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryViewModel.swift; sourceTree = "<group>"; };
@ -331,6 +336,7 @@
53EC6E1E267E80AC006DD26A /* Pods_JellyfinPlayer_tvOS.framework in Frameworks */, 53EC6E1E267E80AC006DD26A /* Pods_JellyfinPlayer_tvOS.framework in Frameworks */,
53A431BF266B0FFE0016769F /* JellyfinAPI in Frameworks */, 53A431BF266B0FFE0016769F /* JellyfinAPI in Frameworks */,
535870912669D7A800D05A09 /* Introspect in Frameworks */, 535870912669D7A800D05A09 /* Introspect in Frameworks */,
62CB3F482685BB3B003D0A6F /* Defaults in Frameworks */,
5358708D2669D7A800D05A09 /* KeychainSwift in Frameworks */, 5358708D2669D7A800D05A09 /* KeychainSwift in Frameworks */,
536D3D84267BEA550004248C /* ParallaxView in Frameworks */, 536D3D84267BEA550004248C /* ParallaxView in Frameworks */,
53ABFDDC267972BF00886593 /* TVServices.framework in Frameworks */, 53ABFDDC267972BF00886593 /* TVServices.framework in Frameworks */,
@ -343,6 +349,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
62CB3F462685BAF7003D0A6F /* Defaults in Frameworks */,
5338F757263B7E2E0014BF09 /* KeychainSwift in Frameworks */, 5338F757263B7E2E0014BF09 /* KeychainSwift in Frameworks */,
53EC6E25267EB10F006DD26A /* SwiftyJSON in Frameworks */, 53EC6E25267EB10F006DD26A /* SwiftyJSON in Frameworks */,
53EC6E21267E80B1006DD26A /* Pods_JellyfinPlayer_iOS.framework in Frameworks */, 53EC6E21267E80B1006DD26A /* Pods_JellyfinPlayer_iOS.framework in Frameworks */,
@ -591,6 +598,7 @@
6267B3D526710B8900A7371D /* CollectionExtensions.swift */, 6267B3D526710B8900A7371D /* CollectionExtensions.swift */,
6267B3D92671138200A7371D /* ImageExtensions.swift */, 6267B3D92671138200A7371D /* ImageExtensions.swift */,
62EC353326766B03000E9F2D /* DeviceRotationViewModifier.swift */, 62EC353326766B03000E9F2D /* DeviceRotationViewModifier.swift */,
62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */,
); );
path = Extensions; path = Extensions;
sourceTree = "<group>"; sourceTree = "<group>";
@ -662,6 +670,7 @@
53A431BE266B0FFE0016769F /* JellyfinAPI */, 53A431BE266B0FFE0016769F /* JellyfinAPI */,
53ABFDEC26799D7700886593 /* ActivityIndicator */, 53ABFDEC26799D7700886593 /* ActivityIndicator */,
536D3D83267BEA550004248C /* ParallaxView */, 536D3D83267BEA550004248C /* ParallaxView */,
62CB3F472685BB3B003D0A6F /* Defaults */,
); );
productName = "JellyfinPlayer tvOS"; productName = "JellyfinPlayer tvOS";
productReference = 535870602669D21600D05A09 /* JellyfinPlayer tvOS.app */; productReference = 535870602669D21600D05A09 /* JellyfinPlayer tvOS.app */;
@ -693,6 +702,7 @@
53A431BC266B0FF20016769F /* JellyfinAPI */, 53A431BC266B0FF20016769F /* JellyfinAPI */,
625CB5792678C4A400530A6E /* ActivityIndicator */, 625CB5792678C4A400530A6E /* ActivityIndicator */,
53EC6E24267EB10F006DD26A /* SwiftyJSON */, 53EC6E24267EB10F006DD26A /* SwiftyJSON */,
62CB3F452685BAF7003D0A6F /* Defaults */,
); );
productName = JellyfinPlayer; productName = JellyfinPlayer;
productReference = 5377CBF1263B596A003A4E83 /* JellyfinPlayer iOS.app */; productReference = 5377CBF1263B596A003A4E83 /* JellyfinPlayer iOS.app */;
@ -761,6 +771,7 @@
625CB5782678C4A400530A6E /* XCRemoteSwiftPackageReference "ActivityIndicator" */, 625CB5782678C4A400530A6E /* XCRemoteSwiftPackageReference "ActivityIndicator" */,
536D3D82267BEA550004248C /* XCRemoteSwiftPackageReference "ParallaxView" */, 536D3D82267BEA550004248C /* XCRemoteSwiftPackageReference "ParallaxView" */,
53EC6E23267EB10F006DD26A /* XCRemoteSwiftPackageReference "SwiftyJSON" */, 53EC6E23267EB10F006DD26A /* XCRemoteSwiftPackageReference "SwiftyJSON" */,
62CB3F442685BAF7003D0A6F /* XCRemoteSwiftPackageReference "Defaults" */,
); );
productRefGroup = 5377CBF2263B596A003A4E83 /* Products */; productRefGroup = 5377CBF2263B596A003A4E83 /* Products */;
projectDirPath = ""; projectDirPath = "";
@ -944,6 +955,7 @@
091B5A8D268315D400D78B61 /* ServerDiscovery.swift in Sources */, 091B5A8D268315D400D78B61 /* ServerDiscovery.swift in Sources */,
53ABFDE7267974EF00886593 /* ConnectToServerViewModel.swift in Sources */, 53ABFDE7267974EF00886593 /* ConnectToServerViewModel.swift in Sources */,
53ABFDEE26799DCD00886593 /* ImageView.swift in Sources */, 53ABFDEE26799DCD00886593 /* ImageView.swift in Sources */,
62CB3F4C2685BB77003D0A6F /* DefaultsExtension.swift in Sources */,
62E632E4267D3BA60063E547 /* MovieItemViewModel.swift in Sources */, 62E632E4267D3BA60063E547 /* MovieItemViewModel.swift in Sources */,
5358706C2669D21700D05A09 /* PersistenceController.swift in Sources */, 5358706C2669D21700D05A09 /* PersistenceController.swift in Sources */,
535870AA2669D8AE00D05A09 /* BlurHashDecode.swift in Sources */, 535870AA2669D8AE00D05A09 /* BlurHashDecode.swift in Sources */,
@ -982,6 +994,7 @@
6225FCCB2663841E00E067F6 /* ParallaxHeader.swift in Sources */, 6225FCCB2663841E00E067F6 /* ParallaxHeader.swift in Sources */,
625CB5772678C34300530A6E /* ConnectToServerViewModel.swift in Sources */, 625CB5772678C34300530A6E /* ConnectToServerViewModel.swift in Sources */,
536D3D78267BD5C30004248C /* ViewModel.swift in Sources */, 536D3D78267BD5C30004248C /* ViewModel.swift in Sources */,
62CB3F4B2685BB77003D0A6F /* DefaultsExtension.swift in Sources */,
53DE4BD02670961400739748 /* EpisodeItemView.swift in Sources */, 53DE4BD02670961400739748 /* EpisodeItemView.swift in Sources */,
53F8377D265FF67C00F456B3 /* VideoPlayerSettingsView.swift in Sources */, 53F8377D265FF67C00F456B3 /* VideoPlayerSettingsView.swift in Sources */,
53192D5D265AA78A008A4215 /* DeviceProfileBuilder.swift in Sources */, 53192D5D265AA78A008A4215 /* DeviceProfileBuilder.swift in Sources */,
@ -1068,7 +1081,7 @@
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 54; CURRENT_PROJECT_VERSION = 54;
DEVELOPMENT_ASSET_PATHS = "\"JellyfinPlayer tvOS/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"JellyfinPlayer tvOS/Preview Content\"";
DEVELOPMENT_TEAM = 9R8RREG67J; DEVELOPMENT_TEAM = 4BHXT8RHFR;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = "JellyfinPlayer tvOS/Info.plist"; INFOPLIST_FILE = "JellyfinPlayer tvOS/Info.plist";
@ -1077,7 +1090,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.0; MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = me.vigue.jellyfin; PRODUCT_BUNDLE_IDENTIFIER = dev.kwangmin.swiftfin;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos; SDKROOT = appletvos;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -1096,7 +1109,7 @@
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 54; CURRENT_PROJECT_VERSION = 54;
DEVELOPMENT_ASSET_PATHS = "\"JellyfinPlayer tvOS/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"JellyfinPlayer tvOS/Preview Content\"";
DEVELOPMENT_TEAM = 9R8RREG67J; DEVELOPMENT_TEAM = 4BHXT8RHFR;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = "JellyfinPlayer tvOS/Info.plist"; INFOPLIST_FILE = "JellyfinPlayer tvOS/Info.plist";
@ -1105,7 +1118,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.0; MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = me.vigue.jellyfin; PRODUCT_BUNDLE_IDENTIFIER = dev.kwangmin.swiftfin;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos; SDKROOT = appletvos;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -1245,7 +1258,7 @@
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 54; CURRENT_PROJECT_VERSION = 54;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = 9R8RREG67J; DEVELOPMENT_TEAM = 4BHXT8RHFR;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
EXCLUDED_ARCHS = ""; EXCLUDED_ARCHS = "";
@ -1257,7 +1270,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.0; MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = me.vigue.jellyfin; PRODUCT_BUNDLE_IDENTIFIER = dev.pangmo5.swiftfin;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTS_MACCATALYST = NO; SUPPORTS_MACCATALYST = NO;
@ -1280,7 +1293,7 @@
CURRENT_PROJECT_VERSION = 54; CURRENT_PROJECT_VERSION = 54;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = 9R8RREG67J; DEVELOPMENT_TEAM = 4BHXT8RHFR;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
EXCLUDED_ARCHS = ""; EXCLUDED_ARCHS = "";
@ -1292,7 +1305,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.0; MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = me.vigue.jellyfin; PRODUCT_BUNDLE_IDENTIFIER = dev.pangmo5.swiftfin;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTS_MACCATALYST = NO; SUPPORTS_MACCATALYST = NO;
@ -1310,7 +1323,7 @@
CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements; CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 54; CURRENT_PROJECT_VERSION = 54;
DEVELOPMENT_TEAM = 9R8RREG67J; DEVELOPMENT_TEAM = 4BHXT8RHFR;
INFOPLIST_FILE = WidgetExtension/Info.plist; INFOPLIST_FILE = WidgetExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.1; IPHONEOS_DEPLOYMENT_TARGET = 14.1;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@ -1319,7 +1332,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.0; MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = me.vigue.jellyfin.widget; PRODUCT_BUNDLE_IDENTIFIER = dev.pangmo5.swiftfin.Widget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -1335,7 +1348,7 @@
CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements; CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 54; CURRENT_PROJECT_VERSION = 54;
DEVELOPMENT_TEAM = 9R8RREG67J; DEVELOPMENT_TEAM = 4BHXT8RHFR;
INFOPLIST_FILE = WidgetExtension/Info.plist; INFOPLIST_FILE = WidgetExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.1; IPHONEOS_DEPLOYMENT_TARGET = 14.1;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@ -1344,7 +1357,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.0; MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = me.vigue.jellyfin.widget; PRODUCT_BUNDLE_IDENTIFIER = dev.pangmo5.swiftfin.Widget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -1450,6 +1463,14 @@
minimumVersion = 1.1.0; minimumVersion = 1.1.0;
}; };
}; };
62CB3F442685BAF7003D0A6F /* XCRemoteSwiftPackageReference "Defaults" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sindresorhus/Defaults";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 5.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */ /* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */ /* Begin XCSwiftPackageProductDependency section */
@ -1533,6 +1554,16 @@
package = 5338F755263B7E2E0014BF09 /* XCRemoteSwiftPackageReference "keychain-swift" */; package = 5338F755263B7E2E0014BF09 /* XCRemoteSwiftPackageReference "keychain-swift" */;
productName = KeychainSwift; productName = KeychainSwift;
}; };
62CB3F452685BAF7003D0A6F /* Defaults */ = {
isa = XCSwiftPackageProductDependency;
package = 62CB3F442685BAF7003D0A6F /* XCRemoteSwiftPackageReference "Defaults" */;
productName = Defaults;
};
62CB3F472685BB3B003D0A6F /* Defaults */ = {
isa = XCSwiftPackageProductDependency;
package = 62CB3F442685BAF7003D0A6F /* XCRemoteSwiftPackageReference "Defaults" */;
productName = Defaults;
};
/* End XCSwiftPackageProductDependency section */ /* End XCSwiftPackageProductDependency section */
/* Begin XCVersionGroup section */ /* Begin XCVersionGroup section */

View File

@ -19,6 +19,15 @@
"version": "0.6.0" "version": "0.6.0"
} }
}, },
{
"package": "Defaults",
"repositoryURL": "https://github.com/sindresorhus/Defaults",
"state": {
"branch": null,
"revision": "63d93f97ad545c8bceb125a8a36175ea705f7cf5",
"version": "5.0.0"
}
},
{ {
"package": "Gifu", "package": "Gifu",
"repositoryURL": "https://github.com/kaishin/Gifu", "repositoryURL": "https://github.com/kaishin/Gifu",

View File

@ -8,13 +8,13 @@
<true/> <true/>
<key>com.apple.security.application-groups</key> <key>com.apple.security.application-groups</key>
<array> <array>
<string>group.me.vigue.jellyfin.mobileclient</string> <string>group.dev.pangmo5.swiftfin</string>
</array> </array>
<key>com.apple.security.network.client</key> <key>com.apple.security.network.client</key>
<true/> <true/>
<key>keychain-access-groups</key> <key>keychain-access-groups</key>
<array> <array>
<string>$(AppIdentifierPrefix)me.vigue.jellyfin.sharedKeychain</string> <string>$(AppIdentifierPrefix)dev.pangmo5.swiftfin.sharedKeychain</string>
</array> </array>
</dict> </dict>
</plist> </plist>

View File

@ -30,7 +30,7 @@ struct PersistenceController {
init(inMemory: Bool = false) { init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: "Model") container = NSPersistentCloudKitContainer(name: "Model")
container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: FileManager.default container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.me.vigue.jellyfin.mobileclient")!.appendingPathComponent("\(container.name).sqlite"))] .containerURL(forSecurityApplicationGroupIdentifier: "group.dev.pangmo5.swiftfin")!.appendingPathComponent("\(container.name).sqlite"))]
if inMemory { if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")

View File

@ -7,28 +7,30 @@
import CoreData import CoreData
import SwiftUI import SwiftUI
import Defaults
struct SettingsView: View { struct SettingsView: View {
@Environment(\.managedObjectContext) private var viewContext @Environment(\.managedObjectContext) private var viewContext
@ObservedObject var viewModel: SettingsViewModel @ObservedObject var viewModel: SettingsViewModel
@Binding var close: Bool @Binding var close: Bool
@State private var inNetworkStreamBitrate: Int = 40_000_000 @Default(.inNetworkBandwidth)
@State private var outOfNetworkStreamBitrate: Int = 40_000_000 var inNetworkStreamBitrate
@State private var autoSelectSubtitles: Bool = false @Default(.outOfNetworkBandwidth)
@State private var autoSelectSubtitlesLangcode: String = "none" var outOfNetworkStreamBitrate
@Default(.isAutoSelectSubtitles)
var isAutoSelectSubtitles
@Default(.autoSelectSubtitlesLangCode)
var autoSelectSubtitlesLangcode
@Default(.autoSelectAudioLangCode)
var autoSelectAudioLangcode
@State private var username: String = "" @State private var username: String = ""
func onAppear() { func onAppear() {
let defaults = UserDefaults.standard
username = SessionManager.current.user.username ?? "" username = SessionManager.current.user.username ?? ""
inNetworkStreamBitrate = defaults.integer(forKey: "InNetworkBandwidth")
outOfNetworkStreamBitrate = defaults.integer(forKey: "OutOfNetworkBandwidth")
autoSelectSubtitles = defaults.bool(forKey: "AutoSelectSubtitles")
autoSelectSubtitlesLangcode = defaults.string(forKey: "AutoSelectSubtitlesLangcode") ?? ""
} }
var body: some View { var body: some View {
NavigationView { NavigationView {
Form { Form {
@ -37,29 +39,35 @@ struct SettingsView: View {
ForEach(self.viewModel.bitrates, id: \.self) { bitrate in ForEach(self.viewModel.bitrates, id: \.self) { bitrate in
Text(bitrate.name).tag(bitrate.value) Text(bitrate.name).tag(bitrate.value)
} }
}.onChange(of: inNetworkStreamBitrate) { _ in
let defaults = UserDefaults.standard
defaults.setValue(_inNetworkStreamBitrate.wrappedValue, forKey: "InNetworkBandwidth")
} }
Picker("Default remote quality", selection: $outOfNetworkStreamBitrate) { Picker("Default remote quality", selection: $outOfNetworkStreamBitrate) {
ForEach(self.viewModel.bitrates, id: \.self) { bitrate in ForEach(self.viewModel.bitrates, id: \.self) { bitrate in
Text(bitrate.name).tag(bitrate.value) Text(bitrate.name).tag(bitrate.value)
} }
}.onChange(of: outOfNetworkStreamBitrate) { _ in
let defaults = UserDefaults.standard
defaults.setValue(_outOfNetworkStreamBitrate.wrappedValue, forKey: "OutOfNetworkBandwidth")
} }
} }
Section(header: Text("Accessibility")) { Section(header: Text("Accessibility")) {
Toggle("Automatically show subtitles", isOn: $autoSelectSubtitles).onChange(of: autoSelectSubtitles, perform: { _ in Toggle("Automatically show subtitles", isOn: $isAutoSelectSubtitles)
let defaults = UserDefaults.standard Picker("Subtitles Language preferences", selection: $autoSelectSubtitlesLangcode) {
defaults.setValue(autoSelectSubtitles, forKey: "AutoSelectSubtitles") Text("Auto")
}) .tag("Auto")
Picker("Language preferences", selection: $autoSelectSubtitlesLangcode) {} ForEach(viewModel.isoLanguageCodesPair, id: \.1) {
Text($0.0)
.tag($0.1)
}
}
Picker("Audio Language preferences", selection: $autoSelectAudioLangcode) {
Text("Auto")
.tag("Auto")
ForEach(viewModel.isoLanguageCodesPair, id: \.1) {
Text($0.0)
.tag($0.1)
}
}
} }
Section { Section {
HStack { HStack {
Text("Signed in as \(username)").foregroundColor(.primary) Text("Signed in as \(username)").foregroundColor(.primary)

View File

@ -12,7 +12,7 @@ import MediaPlayer
import Combine import Combine
import GoogleCast import GoogleCast
import SwiftyJSON import SwiftyJSON
import Defaults
enum PlayerDestination { enum PlayerDestination {
case remote case remote
@ -417,8 +417,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
mediaPlayer.drawable = videoContentView mediaPlayer.drawable = videoContentView
// Fetch max bitrate from UserDefaults depending on current connection mode // Fetch max bitrate from UserDefaults depending on current connection mode
let defaults = UserDefaults.standard let maxBitrate = Defaults[.inNetworkBandwidth]
let maxBitrate = defaults.integer(forKey: "InNetworkBandwidth")
// Build a device profile // Build a device profile
let builder = DeviceProfileBuilder() let builder = DeviceProfileBuilder()

View File

@ -0,0 +1,19 @@
//
/*
* 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 Defaults
extension Defaults.Keys {
static let inNetworkBandwidth = Key<Int>("InNetworkBandwidth", default: 40_000_000)
static let outOfNetworkBandwidth = Key<Int>("OutOfNetworkBandwidth", default: 40_000_000)
static let isAutoSelectSubtitles = Key<Bool>("isAutoSelectSubtitles", default: false)
static let autoSelectSubtitlesLangCode = Key<String>("AutoSelectSubtitlesLangCode", default: "Auto")
static let autoSelectAudioLangCode = Key<String>("AutoSelectAudioLangCode", default: "Auto")
}

View File

@ -81,7 +81,7 @@ final class SessionManager {
fileprivate func getAuthToken(userID: String) -> String? { fileprivate func getAuthToken(userID: String) -> String? {
let keychain = KeychainSwift() let keychain = KeychainSwift()
keychain.accessGroup = "9R8RREG67J.me.vigue.jellyfin.sharedKeychain" keychain.accessGroup = "4BHXT8RHFR.dev.pangmo5.swiftfin.sharedKeychain"
return keychain.get("AccessToken_\(userID)") return keychain.get("AccessToken_\(userID)")
} }
@ -134,7 +134,7 @@ final class SessionManager {
_ = try? PersistenceController.shared.container.viewContext.save() _ = try? PersistenceController.shared.container.viewContext.save()
let keychain = KeychainSwift() let keychain = KeychainSwift()
keychain.accessGroup = "9R8RREG67J.me.vigue.jellyfin.sharedKeychain" keychain.accessGroup = "4BHXT8RHFR.dev.pangmo5.swiftfin.sharedKeychain"
keychain.set(accessToken!, forKey: "AccessToken_\(user.user_id!)") keychain.set(accessToken!, forKey: "AccessToken_\(user.user_id!)")
generateAuthHeader(with: accessToken) generateAuthHeader(with: accessToken)
@ -151,7 +151,7 @@ final class SessionManager {
nc.post(name: Notification.Name("didSignOut"), object: nil) nc.post(name: Notification.Name("didSignOut"), object: nil)
let keychain = KeychainSwift() let keychain = KeychainSwift()
keychain.accessGroup = "9R8RREG67J.me.vigue.jellyfin.sharedKeychain" keychain.accessGroup = "4BHXT8RHFR.dev.pangmo5.swiftfin.sharedKeychain"
keychain.delete("AccessToken_\(user?.user_id ?? "")") keychain.delete("AccessToken_\(user?.user_id ?? "")")
generateAuthHeader(with: nil) generateAuthHeader(with: nil)

View File

@ -24,7 +24,9 @@ struct Bitrates: Codable, Hashable {
} }
final class SettingsViewModel: ObservableObject { final class SettingsViewModel: ObservableObject {
let currentLocale = Locale.current
var bitrates: [Bitrates] = [] var bitrates: [Bitrates] = []
var isoLanguageCodesPair = [(name: String, isoCode: String)]()
init() { init() {
let url = Bundle.main.url(forResource: "bitrates", withExtension: "json")! let url = Bundle.main.url(forResource: "bitrates", withExtension: "json")!
@ -39,5 +41,10 @@ final class SettingsViewModel: ObservableObject {
} catch { } catch {
print(error) print(error)
} }
isoLanguageCodesPair = Locale.isoLanguageCodes.compactMap {
guard let name = currentLocale.localizedString(forLanguageCode: $0) else { return nil }
return (name, $0)
}
} }
} }

View File

@ -10,6 +10,7 @@
import Foundation import Foundation
import Combine import Combine
import Nuke import Nuke
import Defaults
#if !os(tvOS) #if !os(tvOS)
import WidgetKit import WidgetKit
@ -30,14 +31,6 @@ final class SplashViewModel: ViewModel {
WidgetCenter.shared.reloadAllTimelines() WidgetCenter.shared.reloadAllTimelines()
#endif #endif
let defaults = UserDefaults.standard
if defaults.integer(forKey: "InNetworkBandwidth") == 0 {
defaults.setValue(40_000_000, forKey: "InNetworkBandwidth")
}
if defaults.integer(forKey: "OutOfNetworkBandwidth") == 0 {
defaults.setValue(40_000_000, forKey: "OutOfNetworkBandwidth")
}
let nc = NotificationCenter.default let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(didLogIn), name: Notification.Name("didSignIn"), object: nil) nc.addObserver(self, selector: #selector(didLogIn), name: Notification.Name("didSignIn"), object: nil)
nc.addObserver(self, selector: #selector(didLogOut), name: Notification.Name("didSignOut"), object: nil) nc.addObserver(self, selector: #selector(didLogOut), name: Notification.Name("didSignOut"), object: nil)

View File

@ -4,11 +4,11 @@
<dict> <dict>
<key>com.apple.security.application-groups</key> <key>com.apple.security.application-groups</key>
<array> <array>
<string>group.me.vigue.jellyfin.mobileclient</string> <string>group.dev.pangmo5.swiftfin</string>
</array> </array>
<key>keychain-access-groups</key> <key>keychain-access-groups</key>
<array> <array>
<string>$(AppIdentifierPrefix)me.vigue.jellyfin.sharedKeychain</string> <string>$(AppIdentifierPrefix)dev.pangmo5.swiftfin.sharedKeychain</string>
</array> </array>
</dict> </dict>
</plist> </plist>