Partially added icloud support for console logo. Added iCloud utilities and tests
This commit is contained in:
@@ -39,9 +39,12 @@
|
||||
B98CBBDB264E98DE00B1B7AC /* Console+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98CBBD8264E98DD00B1B7AC /* Console+CoreDataProperties.swift */; };
|
||||
B98CBBDC264E98DE00B1B7AC /* GameSeries+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98CBBD9264E98DD00B1B7AC /* GameSeries+CoreDataClass.swift */; };
|
||||
B98CBBDD264E98F300B1B7AC /* Console+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F922D1352F0029BFAD /* Console+CoreDataClass.swift */; };
|
||||
B98CBBE3265045AC00B1B7AC /* URLExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98CBBE2265045AC00B1B7AC /* URLExtension.swift */; };
|
||||
B98CBBEB2652B75F00B1B7AC /* ZockerhoehleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98CBBEA2652B75F00B1B7AC /* ZockerhoehleTests.swift */; };
|
||||
B9A0550122F8C22D0054D9A0 /* GameSeriesAllView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550022F8C22D0054D9A0 /* GameSeriesAllView.swift */; };
|
||||
B9A0550322F8C2740054D9A0 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550222F8C2740054D9A0 /* MainView.swift */; };
|
||||
B9A0550522F8CB400054D9A0 /* GameSeriesLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550422F8CB400054D9A0 /* GameSeriesLibraryView.swift */; };
|
||||
B9BCCEB92653BDEA005F46D6 /* ICloudManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */; };
|
||||
B9BCF4CA2168ACB600ECBAAC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */; };
|
||||
B9D2C6F722E98ED800797F67 /* AccessoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */; };
|
||||
B9E2A079233B69D400EAEB14 /* GameSeriesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */; };
|
||||
@@ -58,6 +61,16 @@
|
||||
B9F44AE922F4655600FC6B29 /* AccessoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F44AE822F4655600FC6B29 /* AccessoryStore.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
B98CBBED2652B75F00B1B7AC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = B93C1B9121496BFD0014FD6E /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = B93C1B9821496BFD0014FD6E;
|
||||
remoteInfo = Zockerhoehle;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
B983997A233A0295002F9946 /* Embed Watch Content */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
@@ -108,9 +121,14 @@
|
||||
B98CBBD7264E98DD00B1B7AC /* GameSeries+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GameSeries+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
B98CBBD8264E98DD00B1B7AC /* Console+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Console+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
B98CBBD9264E98DD00B1B7AC /* GameSeries+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GameSeries+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||
B98CBBE2265045AC00B1B7AC /* URLExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLExtension.swift; sourceTree = "<group>"; };
|
||||
B98CBBE82652B75F00B1B7AC /* ZockerhoehleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ZockerhoehleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B98CBBEA2652B75F00B1B7AC /* ZockerhoehleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZockerhoehleTests.swift; sourceTree = "<group>"; };
|
||||
B98CBBEC2652B75F00B1B7AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
B9A0550022F8C22D0054D9A0 /* GameSeriesAllView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameSeriesAllView.swift; sourceTree = "<group>"; };
|
||||
B9A0550222F8C2740054D9A0 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
|
||||
B9A0550422F8CB400054D9A0 /* GameSeriesLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameSeriesLibraryView.swift; sourceTree = "<group>"; };
|
||||
B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICloudManager.swift; sourceTree = "<group>"; };
|
||||
B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessoryViewModel.swift; sourceTree = "<group>"; };
|
||||
B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameSeriesViewModel.swift; sourceTree = "<group>"; };
|
||||
@@ -137,6 +155,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B98CBBE52652B75F00B1B7AC /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@@ -175,6 +200,7 @@
|
||||
B98B2FAB232C0F8C00606DC4 /* ImagePicker.swift */,
|
||||
B9EC09812383F94B004BC9AB /* LibraryExport.swift */,
|
||||
B90E03EA238557D900E79643 /* LibraryImport.swift */,
|
||||
B98CBBE2265045AC00B1B7AC /* URLExtension.swift */,
|
||||
);
|
||||
path = Utils;
|
||||
sourceTree = "<group>";
|
||||
@@ -183,6 +209,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B93C1B9B21496BFD0014FD6E /* Zockerhoehle */,
|
||||
B98CBBE92652B75F00B1B7AC /* ZockerhoehleTests */,
|
||||
B93C1B9A21496BFD0014FD6E /* Products */,
|
||||
B90B64A12235909900E54BA3 /* Frameworks */,
|
||||
B94CB53522D3708F0029BFAD /* Zockerhoehle copy-Info.plist */,
|
||||
@@ -193,6 +220,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B93C1B9921496BFD0014FD6E /* Zockerhoehle.app */,
|
||||
B98CBBE82652B75F00B1B7AC /* ZockerhoehleTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -209,6 +237,7 @@
|
||||
B9F44ABD22F31DEF00FC6B29 /* SceneDelegate.swift */,
|
||||
B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */,
|
||||
B98A735F22C1738800FB3410 /* CDManager.swift */,
|
||||
B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */,
|
||||
B93C1BA321496BFE0014FD6E /* Assets.xcassets */,
|
||||
B93C1BA821496BFE0014FD6E /* Info.plist */,
|
||||
B98A731722BA9E4600FB3410 /* Zockerhoehle.xcdatamodeld */,
|
||||
@@ -254,6 +283,15 @@
|
||||
path = CDModel;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B98CBBE92652B75F00B1B7AC /* ZockerhoehleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B98CBBEA2652B75F00B1B7AC /* ZockerhoehleTests.swift */,
|
||||
B98CBBEC2652B75F00B1B7AC /* Info.plist */,
|
||||
);
|
||||
path = ZockerhoehleTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -280,13 +318,31 @@
|
||||
productReference = B93C1B9921496BFD0014FD6E /* Zockerhoehle.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
B98CBBE72652B75F00B1B7AC /* ZockerhoehleTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = B98CBBF12652B75F00B1B7AC /* Build configuration list for PBXNativeTarget "ZockerhoehleTests" */;
|
||||
buildPhases = (
|
||||
B98CBBE42652B75F00B1B7AC /* Sources */,
|
||||
B98CBBE52652B75F00B1B7AC /* Frameworks */,
|
||||
B98CBBE62652B75F00B1B7AC /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
B98CBBEE2652B75F00B1B7AC /* PBXTargetDependency */,
|
||||
);
|
||||
name = ZockerhoehleTests;
|
||||
productName = ZockerhoehleTests;
|
||||
productReference = B98CBBE82652B75F00B1B7AC /* ZockerhoehleTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
B93C1B9121496BFD0014FD6E /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1100;
|
||||
LastSwiftUpdateCheck = 1250;
|
||||
LastUpgradeCheck = 1250;
|
||||
ORGANIZATIONNAME = "Julian-Steffen Müller";
|
||||
TargetAttributes = {
|
||||
@@ -294,6 +350,10 @@
|
||||
CreatedOnToolsVersion = 9.4.1;
|
||||
LastSwiftMigration = 1020;
|
||||
};
|
||||
B98CBBE72652B75F00B1B7AC = {
|
||||
CreatedOnToolsVersion = 12.5;
|
||||
TestTargetID = B93C1B9821496BFD0014FD6E;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = B93C1B9421496BFD0014FD6E /* Build configuration list for PBXProject "Zockerhoehle" */;
|
||||
@@ -314,6 +374,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
B93C1B9821496BFD0014FD6E /* Zockerhoehle */,
|
||||
B98CBBE72652B75F00B1B7AC /* ZockerhoehleTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -328,6 +389,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B98CBBE62652B75F00B1B7AC /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
@@ -361,6 +429,7 @@
|
||||
B98B2FAA2328DF3400606DC4 /* GameSeriesStore.swift in Sources */,
|
||||
B9839991233A0E16002F9946 /* GameSeriesCover+CoreDataProperties.swift in Sources */,
|
||||
B983998C233A0BC9002F9946 /* Cover+CoreDataClass.swift in Sources */,
|
||||
B98CBBE3265045AC00B1B7AC /* URLExtension.swift in Sources */,
|
||||
B9839992233A0E19002F9946 /* GameSeriesCover+CoreDataClass.swift in Sources */,
|
||||
B94112E0233A4EF800159AE4 /* GamePickupsView.swift in Sources */,
|
||||
B94112E2233B55B100159AE4 /* ConsoleViewModel.swift in Sources */,
|
||||
@@ -397,14 +466,31 @@
|
||||
B98A736022C1738800FB3410 /* CDManager.swift in Sources */,
|
||||
B94CB50222D1352F0029BFAD /* Cover+CoreDataProperties.swift in Sources */,
|
||||
B9E2A07E233B6E4F00EAEB14 /* ConsoleAllView.swift in Sources */,
|
||||
B9BCCEB92653BDEA005F46D6 /* ICloudManager.swift in Sources */,
|
||||
B9EC0987238555BF004BC9AB /* SettingsView.swift in Sources */,
|
||||
B9F44AE522F418F600FC6B29 /* ConsoleStore.swift in Sources */,
|
||||
B9E2A079233B69D400EAEB14 /* GameSeriesViewModel.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B98CBBE42652B75F00B1B7AC /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B98CBBEB2652B75F00B1B7AC /* ZockerhoehleTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
B98CBBEE2652B75F00B1B7AC /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = B93C1B9821496BFD0014FD6E /* Zockerhoehle */;
|
||||
targetProxy = B98CBBED2652B75F00B1B7AC /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
B93C1BA921496BFE0014FD6E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
@@ -537,6 +623,7 @@
|
||||
"$(PROJECT_DIR)/Carthage/Build/iOS",
|
||||
);
|
||||
INFOPLIST_FILE = Zockerhoehle/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@@ -562,6 +649,7 @@
|
||||
"$(PROJECT_DIR)/Carthage/Build/iOS",
|
||||
);
|
||||
INFOPLIST_FILE = Zockerhoehle/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@@ -574,6 +662,51 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
B98CBBEF2652B75F00B1B7AC /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 85J8CBD673;
|
||||
INFOPLIST_FILE = ZockerhoehleTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = haus.mueller.ZockerhoehleTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Zockerhoehle.app/Zockerhoehle";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
B98CBBF02652B75F00B1B7AC /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 85J8CBD673;
|
||||
INFOPLIST_FILE = ZockerhoehleTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = haus.mueller.ZockerhoehleTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Zockerhoehle.app/Zockerhoehle";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
@@ -595,6 +728,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
B98CBBF12652B75F00B1B7AC /* Build configuration list for PBXNativeTarget "ZockerhoehleTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
B98CBBEF2652B75F00B1B7AC /* Debug */,
|
||||
B98CBBF02652B75F00B1B7AC /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
|
||||
@@ -23,6 +23,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
#endif
|
||||
|
||||
print("disFinishLaunchung")
|
||||
/*let url = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")//.appendingPathComponent("Zockerhoehle").appendingPathComponent("consoles")
|
||||
|
||||
if !FileManager.default.fileExists(atPath: url!.path, isDirectory: nil) {
|
||||
do {
|
||||
print("------------ \(url)")
|
||||
try FileManager.default.createDirectory(at: url!, withIntermediateDirectories: true, attributes: nil)
|
||||
}
|
||||
catch {
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
}else {
|
||||
let url2 = url?.appendingPathComponent("test23.txt")
|
||||
FileManager.default.createFile(atPath: url2!.path, contents: nil, attributes: nil)
|
||||
print("------------- \(url2)")
|
||||
}*/
|
||||
|
||||
|
||||
//FlockeWS.fetchEntries(for: GameCollection.consoleID)
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class Console: NSManagedObject, Identifiable {
|
||||
}
|
||||
}
|
||||
|
||||
public static func sortConsoleByNewestGame(consoleA : Console, consoleB : Console) -> Bool {
|
||||
public static func compareConsolesByNewestGame(consoleA : Console, consoleB : Console) -> Bool {
|
||||
guard let newestGameConsoleA = (consoleA.games!.allObjects as! [Game]).max(by:{
|
||||
Game.compareByCreationDate(gameA: $0, gameB: $1)
|
||||
}) else { return false }
|
||||
@@ -72,6 +72,7 @@ extension Console : Encodable {
|
||||
case accessories
|
||||
case games
|
||||
case logo
|
||||
case logo_icloud_path
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@@ -81,7 +82,7 @@ extension Console : Encodable {
|
||||
try container.encode(shortName ?? "", forKey: .shortName)
|
||||
try container.encode(generation, forKey: .generation)
|
||||
try container.encode(manufacturer ?? "", forKey: .manufacturer)
|
||||
|
||||
try container.encode(logo_icloud_path ?? "", forKey: .logo_icloud_path)
|
||||
var accessoryList : [String] = []
|
||||
for accessory in accessories! {
|
||||
if let accessory = accessory as? Accessory {
|
||||
|
||||
@@ -26,6 +26,7 @@ extension Console {
|
||||
@NSManaged public var accessories: NSSet?
|
||||
@NSManaged public var games: NSSet?
|
||||
@NSManaged public var logo: Logo?
|
||||
@NSManaged public var logo_icloud_path : String?
|
||||
|
||||
}
|
||||
|
||||
|
||||
48
Zockerhoehle/ICloudManager.swift
Normal file
48
Zockerhoehle/ICloudManager.swift
Normal file
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// ICloudDriveManager.swift
|
||||
// Zockerhoehle
|
||||
//
|
||||
// Created by Julian-Steffen Müller on 18.05.21.
|
||||
// Copyright © 2021 Julian-Steffen Müller. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
class ICloudManager {
|
||||
static let shared : ICloudManager = ICloudManager();
|
||||
|
||||
static let relative_seperator : [String] = ["iCloud~Zockerhoehle", "Documents"]
|
||||
|
||||
static public func relativePathFrom(url : URL) -> String? {
|
||||
return url.relative_path_after(pathComponent: relative_seperator) ?? .none
|
||||
}
|
||||
|
||||
static public func fileExists(at path : String?) -> Bool {
|
||||
guard let path = path else { return false }
|
||||
|
||||
if let url = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents").appendingPathComponent(path) {
|
||||
return FileManager.default.fileExists(atPath: url.path)
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static public func imageFrom(path : String?) -> UIImage? {
|
||||
guard let path = path else { return .none }
|
||||
|
||||
do {
|
||||
let url = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents").appendingPathComponent(path)
|
||||
let imageData = try Data(contentsOf: url!)
|
||||
|
||||
return UIImage(data: imageData)!
|
||||
}catch {
|
||||
return .none
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private init() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,18 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSUbiquitousContainers</key>
|
||||
<dict>
|
||||
<key>iCloud.Zockerhoehle</key>
|
||||
<dict>
|
||||
<key>NSUbiquitousContainerIsDocumentScopePublic</key>
|
||||
<true/>
|
||||
<key>NSUbiquitousContainerName</key>
|
||||
<string>Zockerhoehle</string>
|
||||
<key>NSUbiquitousContainerSupportedFolderLevels</key>
|
||||
<string>One</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
@@ -19,7 +31,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<string>7</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string></string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
||||
@@ -25,9 +25,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UIApplicationDelegate {
|
||||
if let windowScene = scene as? UIWindowScene {
|
||||
let window = UIWindow(windowScene: windowScene)
|
||||
|
||||
window.rootViewController = UIHostingController(rootView: MainView()
|
||||
let contentView = MainView()
|
||||
.environmentObject(self.gameSeriesStore)
|
||||
.environmentObject(self.consolesStore))
|
||||
.environmentObject(self.consolesStore)
|
||||
.environment(\.managedObjectContext, CDManager.shared.viewContext)
|
||||
|
||||
window.rootViewController = UIHostingController(rootView: contentView)
|
||||
self.window = window
|
||||
window.makeKeyAndVisible()
|
||||
}
|
||||
|
||||
35
Zockerhoehle/Utils/URLExtension.swift
Normal file
35
Zockerhoehle/Utils/URLExtension.swift
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// URLExtension.swift
|
||||
// Zockerhoehle
|
||||
//
|
||||
// Created by Julian-Steffen Müller on 15.05.21.
|
||||
// Copyright © 2021 Julian-Steffen Müller. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension URL {
|
||||
/*
|
||||
This function created
|
||||
*/
|
||||
func relative_path_after(pathComponent seperator_components : [String]) -> String? {
|
||||
var seperators = seperator_components
|
||||
|
||||
var url = URL(string: "")
|
||||
for path_component in pathComponents {
|
||||
if seperators.count == 0 {
|
||||
if url == .none {
|
||||
url = URL(string: path_component)
|
||||
}else {
|
||||
url = url?.appendingPathComponent(path_component)
|
||||
}
|
||||
}else{
|
||||
if seperators.first! == path_component {
|
||||
seperators.removeFirst()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return url?.absoluteString ?? .none
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import SwiftUI
|
||||
import Combine
|
||||
|
||||
class ConsoleViewModel : ObservableObject {
|
||||
var objectWillChange = ObservableObjectPublisher()
|
||||
//var objectWillChange = ObservableObjectPublisher()
|
||||
|
||||
init(_ console: Console) {
|
||||
self.console = console
|
||||
@@ -25,7 +25,7 @@ class ConsoleViewModel : ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
var name : String {
|
||||
@Published var name : String {
|
||||
didSet {
|
||||
guard let console = console else { return }
|
||||
console.name = name
|
||||
|
||||
@@ -12,18 +12,23 @@ import QGrid
|
||||
|
||||
struct ModalAddConsoleToLibrary : View {
|
||||
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
|
||||
@Environment(\.managedObjectContext) private var viewContext
|
||||
|
||||
@State var modalConsoleName : String = ""
|
||||
@State var modalConsoleLogoICloudPath : String? = .none
|
||||
|
||||
private func addConsoleToLibrary() {
|
||||
//TODO
|
||||
}
|
||||
@State var isImporting : Bool = false
|
||||
|
||||
let defaultImage = UIImage()
|
||||
|
||||
var addButton : some View {
|
||||
return Button(action: {
|
||||
addConsoleToLibrary()
|
||||
let console = Console(context: viewContext)
|
||||
console.name = self.modalConsoleName
|
||||
console.logo_icloud_path = self.modalConsoleLogoICloudPath
|
||||
|
||||
self.presentationMode.wrappedValue.dismiss()},
|
||||
label: { Text("Add") })
|
||||
label: { Text("Fertig") })
|
||||
.disabled(self.modalConsoleName.trimmingCharacters(in: .whitespacesAndNewlines) == "" )
|
||||
}
|
||||
|
||||
@@ -31,40 +36,55 @@ struct ModalAddConsoleToLibrary : View {
|
||||
NavigationView {
|
||||
Form {
|
||||
TextField("Name", text: $modalConsoleName)
|
||||
Image(uiImage: ICloudManager.imageFrom(path: self.modalConsoleLogoICloudPath) ?? defaultImage)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
Button(action: {
|
||||
isImporting = true;
|
||||
}, label: { Text("Bla")})
|
||||
}
|
||||
.font(.caption)
|
||||
.navigationBarTitle(Text("New Console"))
|
||||
.navigationBarTitle(Text("Neue Konsole anlegen"))
|
||||
.navigationBarItems(leading: Button(action: { self.presentationMode.wrappedValue.dismiss() },
|
||||
label: {Text("Cancel")}),
|
||||
label: {Text("Abbrechen")}),
|
||||
//Add Button is disabled if no name is entered
|
||||
trailing: addButton)
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
.fileImporter(
|
||||
isPresented: $isImporting,
|
||||
allowedContentTypes: [.jpeg, .png],
|
||||
allowsMultipleSelection: false
|
||||
) { result in
|
||||
do {
|
||||
let selectedFile : URL = try result.get().first!
|
||||
|
||||
//It seems that isUbiquitousItem checks if the file is contained in the Apps iCloud folder
|
||||
if (FileManager.default.isUbiquitousItem(at: selectedFile)) {
|
||||
self.modalConsoleLogoICloudPath = ICloudManager.relativePathFrom(url: selectedFile)
|
||||
|
||||
print("Selected Image in iCloud Path \(self.modalConsoleLogoICloudPath ?? "n/a")")
|
||||
}else{
|
||||
Alert(title: Text("Falscher Ordner"))
|
||||
print("Außerhalb \(selectedFile.relativeString)")
|
||||
}
|
||||
}catch{
|
||||
print("ConsoleAllView::ModalAddConsoleToLibrary Error getting result '\(result)'")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ConsolesListView : View {
|
||||
@EnvironmentObject var consoleStore : ConsoleStore
|
||||
@Environment(\.managedObjectContext) private var viewContext
|
||||
@FetchRequest(entity: Console.entity(), sortDescriptors: [NSSortDescriptor(key: "manufacturer", ascending: true), NSSortDescriptor(key: "generation", ascending: true), NSSortDescriptor(key: "name", ascending: true)])
|
||||
var consoles: FetchedResults<Console>
|
||||
|
||||
@State var showAddConsoleToLibraryModal: Bool = false
|
||||
|
||||
var body: some View {
|
||||
/*List(consoleStore.consoles) {console in
|
||||
NavigationLink(destination: ConsoleLibraryView(console: console)) {
|
||||
HStack {
|
||||
if console.logo?.image != nil {
|
||||
Image(uiImage: console.logo!.image!).resizable().frame(width: 50.0, height: 50.0)
|
||||
}else {
|
||||
Image(systemName: "stop").resizable().frame(width: 50.0, height: 50.0)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text("\(console.name)")
|
||||
Text("Spiele: \(console.games.filter({($0 as! Game).inWishlist == false}).count), Zubehör: \(console.accessories.filter({($0 as! Accessory).inWishlist == false}).count)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
QGrid(consoleStore.consoles, columns: 4, columnsInLandscape: 6) {
|
||||
QGrid(consoles, columns: 4, columnsInLandscape: 6) {
|
||||
GridCell(console: $0)
|
||||
}
|
||||
.padding()
|
||||
@@ -83,13 +103,14 @@ struct ConsolesListView : View {
|
||||
|
||||
struct GridCell: View {
|
||||
var console: Console
|
||||
let defaultImage = UIImage()
|
||||
|
||||
var body: some View {
|
||||
VStack() {
|
||||
if console.logo?.image != nil {
|
||||
if ICloudManager.fileExists(at: console.logo_icloud_path) {
|
||||
NavigationLink(destination: ConsoleLibraryView(console: console)) {
|
||||
VStack {
|
||||
Image(uiImage: (console.logo?.image)!)
|
||||
Image(uiImage: ICloudManager.imageFrom(path: console.logo_icloud_path) ?? defaultImage)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
//.shadow(color: .primary, radius: 5)
|
||||
@@ -99,10 +120,10 @@ struct GridCell: View {
|
||||
}.buttonStyle(PlainButtonStyle())
|
||||
|
||||
}else{
|
||||
Text("mu")
|
||||
}
|
||||
//
|
||||
//Text(person.lastName).lineLimit(1)
|
||||
NavigationLink(destination: ConsoleLibraryView(console: console)) {
|
||||
Text(console.shortName ?? console.name!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,6 @@ struct GamePickupsView: View {
|
||||
}
|
||||
}
|
||||
.padding(.top) // Workaround, damit die Liste beim scrollen nicht unter der NavigationView angezeigt wird
|
||||
.navigationBarTitle(Text("Latest Pickups"))
|
||||
.navigationBarTitle(Text("Zuletzt gehortete Spiele"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,22 +34,39 @@ struct OverviewHeader<Destination : View> : View {
|
||||
}
|
||||
}
|
||||
|
||||
struct EmptyCategory : View {
|
||||
private var emptyMessage : String
|
||||
|
||||
init(_ emptyMessage: String) {
|
||||
self.emptyMessage = emptyMessage
|
||||
}
|
||||
|
||||
var body : some View {
|
||||
HStack() {
|
||||
Spacer()
|
||||
Text("Keine Spiele in der Zockerhöhle!").frame(height: 75)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Overview: View {
|
||||
@EnvironmentObject var consoleStore : ConsoleStore
|
||||
@ObservedObject var gameStore : GameStore = GameStore(sortDescriptors: [NSSortDescriptor(key: "createdAt", ascending: false), NSSortDescriptor(key: "name", ascending: true)], fetchLimit: 10)
|
||||
@EnvironmentObject var gameSeriesStore : GameSeriesStore
|
||||
@ObservedObject var featuredStore = FeaturedStore()
|
||||
|
||||
|
||||
var ConsolesOverview : some View {
|
||||
VStack(alignment: .leading) {
|
||||
OverviewHeader(title: "Aktivste Konsolen", destination: ConsolesListView())
|
||||
|
||||
if consoleStore.consoles.count == 0 {
|
||||
Text("No consoles")
|
||||
EmptyCategory("Keine Konsolen in der Zockerhöhle!")
|
||||
}else{
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(alignment: .top, spacing: 0) {
|
||||
ForEach(consoleStore.consoles.sorted(by: { Console.sortConsoleByNewestGame(consoleA: $0, consoleB: $1)})) { console in
|
||||
ForEach(consoleStore.consoles.sorted(by: { Console.compareConsolesByNewestGame(consoleA: $0, consoleB: $1)})) { console in
|
||||
NavigationLink(destination: ConsoleLibraryView(console: console)) {
|
||||
VStack(alignment: .leading) {
|
||||
Group {
|
||||
@@ -80,10 +97,10 @@ struct Overview: View {
|
||||
var GamesOverview : some View {
|
||||
VStack(alignment: .leading) {
|
||||
//TODO
|
||||
OverviewHeader(title: "Latest Game Pickups", destination: GamePickupsView())
|
||||
OverviewHeader(title: "Zuletzt gehortete Spiele", destination: GamePickupsView())
|
||||
|
||||
if gameStore.games.count == 0 {
|
||||
Text("No Games")
|
||||
EmptyCategory("Keine Spiele in der Zockerhöhle")
|
||||
}else {
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(alignment: .top, spacing: 0) {
|
||||
@@ -121,7 +138,7 @@ struct Overview: View {
|
||||
OverviewHeader(title: "Spielserien", destination: GameSeriesAllView())
|
||||
|
||||
if gameSeriesStore.gameSeries.count == 0 {
|
||||
Text("No game series")
|
||||
EmptyCategory("Keine Spieleserie angelegt!")
|
||||
}else{
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(alignment: .top, spacing: 0) {
|
||||
@@ -177,7 +194,7 @@ struct Overview: View {
|
||||
}
|
||||
}.buttonStyle(PlainButtonStyle())
|
||||
}else {
|
||||
Text("No featured console")
|
||||
EmptyCategory("Nichts aktuelles :(")
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
<key>com.apple.developer.icloud-services</key>
|
||||
<array>
|
||||
<string>CloudKit</string>
|
||||
<string>CloudDocuments</string>
|
||||
</array>
|
||||
<key>com.apple.developer.ubiquity-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.Zockerhoehle</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<entity name="Console" representedClassName="Console" syncable="YES">
|
||||
<attribute name="circumstances" optional="YES" attributeType="String"/>
|
||||
<attribute name="generation" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="logo_icloud_path" optional="YES" attributeType="String"/>
|
||||
<attribute name="manufacturer" optional="YES" attributeType="String"/>
|
||||
<attribute name="name" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="shortName" optional="YES" attributeType="String"/>
|
||||
@@ -59,7 +60,7 @@
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="Accessory" positionX="-265.9140625" positionY="29.15625" width="128" height="149"/>
|
||||
<element name="Console" positionX="-535.7890625" positionY="56.03515625" width="128" height="164"/>
|
||||
<element name="Console" positionX="-535.7890625" positionY="56.03515625" width="128" height="179"/>
|
||||
<element name="Cover" positionX="-66.69921875" positionY="223.48046875" width="128" height="59"/>
|
||||
<element name="Game" positionX="-288.828125" positionY="276.7421875" width="128" height="245"/>
|
||||
<element name="GameSeries" positionX="-686.828125" positionY="359.20703125" width="128" height="89"/>
|
||||
|
||||
22
ZockerhoehleTests/Info.plist
Normal file
22
ZockerhoehleTests/Info.plist
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
45
ZockerhoehleTests/ZockerhoehleTests.swift
Normal file
45
ZockerhoehleTests/ZockerhoehleTests.swift
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// ZockerhoehleTests.swift
|
||||
// ZockerhoehleTests
|
||||
//
|
||||
// Created by Julian-Steffen Müller on 17.05.21.
|
||||
// Copyright © 2021 Julian-Steffen Müller. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import Zockerhoehle
|
||||
|
||||
class ZockerhoehleTests: XCTestCase {
|
||||
|
||||
let icloud_drive_seperators : [String] = ["iCloud~Zockerhoehle", "Documents"]
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
func test_url_icloud_split() throws {
|
||||
// VALID FILES
|
||||
let url_valid_file : URL = URL(string: "file:///private/var/mobile/Library/Mobile%20Documents/iCloud~Zockerhoehle/Documents/backup.json")!
|
||||
let url_valid_file_in_subfolder : URL = URL(string: "file:///private/var/mobile/Library/Mobile%20Documents/iCloud~Zockerhoehle/Documents/consoles/ps4.png")!
|
||||
|
||||
XCTAssertEqual(url_valid_file.relative_path_after(pathComponent: icloud_drive_seperators), "backup.json")
|
||||
XCTAssertEqual(url_valid_file_in_subfolder.relative_path_after(pathComponent: icloud_drive_seperators), "consoles/ps4.png")
|
||||
|
||||
//INVALID URL
|
||||
let url_unvalid_url_2 : URL = URL(string: "http://mueller.haus")!
|
||||
|
||||
XCTAssertEqual(url_unvalid_url_2.relative_path_after(pathComponent: icloud_drive_seperators), .none)
|
||||
|
||||
|
||||
// INVALID FILE
|
||||
let url_unvalid_file : URL = URL(string: "file:///private/var/mobile/Library/Mobile%20Documents/com~apple~CloudDocs/photo.jpg")!
|
||||
|
||||
XCTAssertEqual(url_unvalid_file.relative_path_after(pathComponent: icloud_drive_seperators), .none)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user