diff --git a/Cartfile b/Cartfile index feb86a6..07354f2 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "dstranz/Disk" "feature/SPM_xcode11" +github "saoudrizwan/Disk" diff --git a/Zockerhoehle.xcodeproj/project.pbxproj b/Zockerhoehle.xcodeproj/project.pbxproj index 2b5bddd..a92dc01 100644 --- a/Zockerhoehle.xcodeproj/project.pbxproj +++ b/Zockerhoehle.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ B93C1BB02149750E0014FD6E /* AllConsolesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93C1BAF2149750E0014FD6E /* AllConsolesViewController.swift */; }; B93D60CC22D88F2B00DD390F /* AccessoryDetailController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93D60CB22D88F2B00DD390F /* AccessoryDetailController.swift */; }; B93D60CE22D88F5700DD390F /* AccessoryDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93D60CD22D88F5700DD390F /* AccessoryDetailView.swift */; }; + B93D60D122E5009700DD390F /* GameViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93D60D022E5009700DD390F /* GameViewModel.swift */; }; B9418449215422ED0050D099 /* AddEntryPopUpViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9418448215422ED0050D099 /* AddEntryPopUpViewController.swift */; }; B941844B2156891E0050D099 /* UIButtonX.swift in Sources */ = {isa = PBXBuildFile; fileRef = B941844A2156891E0050D099 /* UIButtonX.swift */; }; B94CB4FF22D1352F0029BFAD /* Accessory+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */; }; @@ -42,9 +43,17 @@ B98A736022C1738800FB3410 /* CDManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98A735F22C1738800FB3410 /* CDManager.swift */; }; B9BCF4CA2168ACB600ECBAAC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */; }; B9BCF523217900D700ECBAAC /* WaitingPopOver.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9BCF521217900D700ECBAAC /* WaitingPopOver.storyboard */; }; + B9D2C6F722E98ED800797F67 /* AccessoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */; }; B9D6A39A22D885DD00A280DC /* AccessoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D6A39922D885DD00A280DC /* AccessoryCell.swift */; }; B9E256FE2156D026009FD133 /* UIViewX.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9E256FD2156D026009FD133 /* UIViewX.swift */; }; B9F002E52187AA3200E12B0A /* FlockeConnector.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F002E42187AA3200E12B0A /* FlockeConnector.swift */; }; + B9F44ABA22F312E600FC6B29 /* ConsoleLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F44AB922F312E600FC6B29 /* ConsoleLibraryView.swift */; }; + B9F44ABC22F3145300FC6B29 /* ConsoleDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F44ABB22F3145300FC6B29 /* ConsoleDetailViewController.swift */; }; + B9F44ABE22F31DEF00FC6B29 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F44ABD22F31DEF00FC6B29 /* SceneDelegate.swift */; }; + B9F44AE322F3216F00FC6B29 /* ConsolesListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F44AE222F3216F00FC6B29 /* ConsolesListView.swift */; }; + B9F44AE522F418F600FC6B29 /* ConsoleStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F44AE422F418F600FC6B29 /* ConsoleStore.swift */; }; + B9F44AE722F429D300FC6B29 /* GameStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F44AE622F429D300FC6B29 /* GameStore.swift */; }; + B9F44AE922F4655600FC6B29 /* AccessoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F44AE822F4655600FC6B29 /* AccessoryStore.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -59,13 +68,12 @@ B926F14921502DE1004D36B7 /* ConsoleEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleEntry.swift; sourceTree = ""; }; B93C1B9921496BFD0014FD6E /* Zockerhoehle.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Zockerhoehle.app; sourceTree = BUILT_PRODUCTS_DIR; }; B93C1B9C21496BFD0014FD6E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - B93C1BA121496BFD0014FD6E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; B93C1BA321496BFE0014FD6E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; B93C1BA821496BFE0014FD6E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - B93C1BAE21496CC50014FD6E /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = ""; }; B93C1BAF2149750E0014FD6E /* AllConsolesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllConsolesViewController.swift; sourceTree = ""; }; B93D60CB22D88F2B00DD390F /* AccessoryDetailController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessoryDetailController.swift; sourceTree = ""; }; B93D60CD22D88F5700DD390F /* AccessoryDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessoryDetailView.swift; sourceTree = ""; }; + B93D60D022E5009700DD390F /* GameViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewModel.swift; sourceTree = ""; }; B9418448215422ED0050D099 /* AddEntryPopUpViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEntryPopUpViewController.swift; sourceTree = ""; }; B941844A2156891E0050D099 /* UIButtonX.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButtonX.swift; sourceTree = ""; }; B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Accessory+CoreDataClass.swift"; sourceTree = ""; }; @@ -85,11 +93,20 @@ B94CB53822D3B6490029BFAD /* GameDetailController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameDetailController.swift; sourceTree = ""; }; B98A731822BA9E4600FB3410 /* Zockerhoehle.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Zockerhoehle.xcdatamodel; sourceTree = ""; }; B98A735F22C1738800FB3410 /* CDManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CDManager.swift; sourceTree = ""; }; + B9A054FE22F852B00054D9A0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Zockerhoehle/Base.lproj/WaitingPopOver.storyboard; sourceTree = ""; }; + B9A054FF22F852B00054D9A0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; - B9BCF522217900D700ECBAAC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Zockerhoehle/Base.lproj/WaitingPopOver.storyboard; sourceTree = ""; }; + B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessoryViewModel.swift; sourceTree = ""; }; B9D6A39922D885DD00A280DC /* AccessoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessoryCell.swift; sourceTree = ""; }; B9E256FD2156D026009FD133 /* UIViewX.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewX.swift; sourceTree = ""; }; B9F002E42187AA3200E12B0A /* FlockeConnector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlockeConnector.swift; sourceTree = ""; }; + B9F44AB922F312E600FC6B29 /* ConsoleLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleLibraryView.swift; sourceTree = ""; }; + B9F44ABB22F3145300FC6B29 /* ConsoleDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleDetailViewController.swift; sourceTree = ""; }; + B9F44ABD22F31DEF00FC6B29 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + B9F44AE222F3216F00FC6B29 /* ConsolesListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsolesListView.swift; sourceTree = ""; }; + B9F44AE422F418F600FC6B29 /* ConsoleStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleStore.swift; sourceTree = ""; }; + B9F44AE622F429D300FC6B29 /* GameStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameStore.swift; sourceTree = ""; }; + B9F44AE822F4655600FC6B29 /* AccessoryStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessoryStore.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -129,6 +146,7 @@ B9418448215422ED0050D099 /* AddEntryPopUpViewController.swift */, B94CB53822D3B6490029BFAD /* GameDetailController.swift */, B93D60CB22D88F2B00DD390F /* AccessoryDetailController.swift */, + B9F44ABB22F3145300FC6B29 /* ConsoleDetailViewController.swift */, ); path = ViewController; sourceTree = ""; @@ -141,6 +159,8 @@ B94CB53622D3B3CC0029BFAD /* GameDetailView.swift */, B9D6A39922D885DD00A280DC /* AccessoryCell.swift */, B93D60CD22D88F5700DD390F /* AccessoryDetailView.swift */, + B9F44AB922F312E600FC6B29 /* ConsoleLibraryView.swift */, + B9F44AE222F3216F00FC6B29 /* ConsolesListView.swift */, ); path = Views; sourceTree = ""; @@ -185,6 +205,8 @@ B93C1B9B21496BFD0014FD6E /* Zockerhoehle */ = { isa = PBXGroup; children = ( + B9F44ABD22F31DEF00FC6B29 /* SceneDelegate.swift */, + B93D60CF22E5006F00DD390F /* ViewModel */, B98A734622BACA9C00FB3410 /* CDModel */, B926F14821502D7F004D36B7 /* Lib */, B926F13A214AF21B004D36B7 /* Utils */, @@ -203,6 +225,18 @@ path = Zockerhoehle; sourceTree = ""; }; + B93D60CF22E5006F00DD390F /* ViewModel */ = { + isa = PBXGroup; + children = ( + B93D60D022E5009700DD390F /* GameViewModel.swift */, + B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */, + B9F44AE422F418F600FC6B29 /* ConsoleStore.swift */, + B9F44AE622F429D300FC6B29 /* GameStore.swift */, + B9F44AE822F4655600FC6B29 /* AccessoryStore.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; B98A734622BACA9C00FB3410 /* CDModel */ = { isa = PBXGroup; children = ( @@ -266,7 +300,6 @@ knownRegions = ( en, Base, - de, ); mainGroup = B93C1B9021496BFD0014FD6E; productRefGroup = B93C1B9A21496BFD0014FD6E /* Products */; @@ -325,14 +358,19 @@ B94CB53722D3B3CC0029BFAD /* GameDetailView.swift in Sources */, B94CB50322D1352F0029BFAD /* Game+CoreDataClass.swift in Sources */, B94CB50822D1352F0029BFAD /* GameSeries+CoreDataProperties.swift in Sources */, + B9F44ABA22F312E600FC6B29 /* ConsoleLibraryView.swift in Sources */, + B9F44ABE22F31DEF00FC6B29 /* SceneDelegate.swift in Sources */, + B9D2C6F722E98ED800797F67 /* AccessoryViewModel.swift in Sources */, B93C1BB02149750E0014FD6E /* AllConsolesViewController.swift in Sources */, B926F13F214E4678004D36B7 /* GameCell.swift in Sources */, B9F002E52187AA3200E12B0A /* FlockeConnector.swift in Sources */, B94CB50A22D1352F0029BFAD /* Logo+CoreDataProperties.swift in Sources */, B94CB4FF22D1352F0029BFAD /* Accessory+CoreDataClass.swift in Sources */, B98A734D22BAD27D00FB3410 /* Zockerhoehle.xcdatamodeld in Sources */, + B93D60D122E5009700DD390F /* GameViewModel.swift in Sources */, B9E256FE2156D026009FD133 /* UIViewX.swift in Sources */, B926F12B2149B173004D36B7 /* ConsoleCell.swift in Sources */, + B9F44AE722F429D300FC6B29 /* GameStore.swift in Sources */, B926F12D2149B264004D36B7 /* FlockeEntry.swift in Sources */, B98A735E22BFAA4B00FB3410 /* ConsoleLibraryViewController.swift in Sources */, B94CB50522D1352F0029BFAD /* Console+CoreDataClass.swift in Sources */, @@ -344,14 +382,18 @@ B926F14A21502DE1004D36B7 /* ConsoleEntry.swift in Sources */, B93D60CC22D88F2B00DD390F /* AccessoryDetailController.swift in Sources */, B94CB50722D1352F0029BFAD /* GameSeries+CoreDataClass.swift in Sources */, + B9F44ABC22F3145300FC6B29 /* ConsoleDetailViewController.swift in Sources */, B9418449215422ED0050D099 /* AddEntryPopUpViewController.swift in Sources */, B94CB50022D1352F0029BFAD /* Accessory+CoreDataProperties.swift in Sources */, B9D6A39A22D885DD00A280DC /* AccessoryCell.swift in Sources */, B926F14721502D53004D36B7 /* CodableExtensionAny.swift in Sources */, B94CB50422D1352F0029BFAD /* Game+CoreDataProperties.swift in Sources */, + B9F44AE922F4655600FC6B29 /* AccessoryStore.swift in Sources */, B98A736022C1738800FB3410 /* CDManager.swift in Sources */, B94CB50222D1352F0029BFAD /* Cover+CoreDataProperties.swift in Sources */, + B9F44AE322F3216F00FC6B29 /* ConsolesListView.swift in Sources */, B94CB50122D1352F0029BFAD /* Cover+CoreDataClass.swift in Sources */, + B9F44AE522F418F600FC6B29 /* ConsoleStore.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -361,8 +403,7 @@ B93C1BA021496BFD0014FD6E /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( - B93C1BA121496BFD0014FD6E /* Base */, - B93C1BAE21496CC50014FD6E /* de */, + B9A054FF22F852B00054D9A0 /* Base */, ); name = Main.storyboard; sourceTree = ""; @@ -370,7 +411,7 @@ B9BCF521217900D700ECBAAC /* WaitingPopOver.storyboard */ = { isa = PBXVariantGroup; children = ( - B9BCF522217900D700ECBAAC /* Base */, + B9A054FE22F852B00054D9A0 /* Base */, ); name = WaitingPopOver.storyboard; sourceTree = ""; @@ -498,6 +539,8 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = ""; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = M9N7K3KZX9; FRAMEWORK_SEARCH_PATHS = ( @@ -511,6 +554,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "de.mm-neuemedien.Zockerhoehle"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -520,6 +564,8 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = ""; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = M9N7K3KZX9; FRAMEWORK_SEARCH_PATHS = ( @@ -533,6 +579,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "de.mm-neuemedien.Zockerhoehle"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/Zockerhoehle/AppDelegate.swift b/Zockerhoehle/AppDelegate.swift index a429f28..390dfb5 100644 --- a/Zockerhoehle/AppDelegate.swift +++ b/Zockerhoehle/AppDelegate.swift @@ -23,30 +23,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { #endif print("disFinishLaunchung") - + FlockeWS.fetchEntries(for: GameCollection.consoleID) + return true } - - func applicationWillResignActive(_ application: UIApplication) { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. - } - - func applicationDidEnterBackground(_ application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. - } - - func applicationWillEnterForeground(_ application: UIApplication) { - // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. - } - - func applicationDidBecomeActive(_ application: UIApplication) { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. - } - - func applicationWillTerminate(_ application: UIApplication) { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. - } } - diff --git a/Zockerhoehle/Base.lproj/Main.storyboard b/Zockerhoehle/Base.lproj/Main.storyboard index afdc4fc..3c1da85 100644 --- a/Zockerhoehle/Base.lproj/Main.storyboard +++ b/Zockerhoehle/Base.lproj/Main.storyboard @@ -27,7 +27,7 @@ - + @@ -112,7 +112,7 @@ - + @@ -141,7 +141,7 @@ - + @@ -152,7 +152,7 @@ - + @@ -162,7 +162,7 @@ - + @@ -235,16 +235,16 @@ - - - - - - + + + + + + @@ -255,7 +255,7 @@ - + @@ -410,7 +410,7 @@ - + @@ -422,18 +422,18 @@ - + - + - + @@ -451,18 +451,18 @@ - + - + - + @@ -480,7 +480,7 @@ - + @@ -488,8 +488,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Zockerhoehle/CDModel/Accessory+CoreDataClass.swift b/Zockerhoehle/CDModel/Accessory+CoreDataClass.swift index bb01f19..57ede58 100644 --- a/Zockerhoehle/CDModel/Accessory+CoreDataClass.swift +++ b/Zockerhoehle/CDModel/Accessory+CoreDataClass.swift @@ -11,6 +11,10 @@ import Foundation import CoreData @objc(Accessory) -public class Accessory: NSManagedObject { - +public class Accessory: NSManagedObject, Identifiable { + @nonobjc public class func fetchRequest(console : Console) -> NSFetchRequest { + let fetchRequest = NSFetchRequest(entityName: "Accessory") + fetchRequest.predicate = NSPredicate(format: "console == %@", console) + return fetchRequest + } } diff --git a/Zockerhoehle/CDModel/Accessory+CoreDataProperties.swift b/Zockerhoehle/CDModel/Accessory+CoreDataProperties.swift index 0b47bb3..4c25759 100644 --- a/Zockerhoehle/CDModel/Accessory+CoreDataProperties.swift +++ b/Zockerhoehle/CDModel/Accessory+CoreDataProperties.swift @@ -9,7 +9,7 @@ import Foundation import CoreData - +import UIKit extension Accessory { diff --git a/Zockerhoehle/CDModel/Console+CoreDataClass.swift b/Zockerhoehle/CDModel/Console+CoreDataClass.swift index febe48f..c9afa8f 100644 --- a/Zockerhoehle/CDModel/Console+CoreDataClass.swift +++ b/Zockerhoehle/CDModel/Console+CoreDataClass.swift @@ -11,6 +11,12 @@ import Foundation import CoreData @objc(Console) -public class Console: NSManagedObject { - +public class Console: NSManagedObject, Identifiable { + + public var id : NSManagedObjectID { + get { + return self.objectID + } + } + } diff --git a/Zockerhoehle/CDModel/Console+CoreDataProperties.swift b/Zockerhoehle/CDModel/Console+CoreDataProperties.swift index b5e34b6..1fb12f8 100644 --- a/Zockerhoehle/CDModel/Console+CoreDataProperties.swift +++ b/Zockerhoehle/CDModel/Console+CoreDataProperties.swift @@ -19,7 +19,7 @@ extension Console { @NSManaged public var generation: Int64 @NSManaged public var manufacturer: String? - @NSManaged public var name: String? + @NSManaged public var name: String @NSManaged public var accessories: NSSet @NSManaged public var games: NSSet @NSManaged public var logo: Logo? diff --git a/Zockerhoehle/CDModel/Game+CoreDataClass.swift b/Zockerhoehle/CDModel/Game+CoreDataClass.swift index 0f6cf8b..31e50c5 100644 --- a/Zockerhoehle/CDModel/Game+CoreDataClass.swift +++ b/Zockerhoehle/CDModel/Game+CoreDataClass.swift @@ -9,8 +9,14 @@ import Foundation import CoreData +import SwiftUI @objc(Game) -public class Game: NSManagedObject { - +public class Game: NSManagedObject, Identifiable { + @nonobjc public class func fetchRequest(console : Console) -> NSFetchRequest { + let fetchRequest = NSFetchRequest(entityName: "Game") + fetchRequest.predicate = NSPredicate(format: "console == %@", console) + return fetchRequest + } + } diff --git a/Zockerhoehle/CDModel/Game+CoreDataProperties.swift b/Zockerhoehle/CDModel/Game+CoreDataProperties.swift index 132928e..520fcaa 100644 --- a/Zockerhoehle/CDModel/Game+CoreDataProperties.swift +++ b/Zockerhoehle/CDModel/Game+CoreDataProperties.swift @@ -11,13 +11,13 @@ import Foundation import CoreData -extension Game { +extension Game{ @nonobjc public class func fetchRequest() -> NSFetchRequest { return NSFetchRequest(entityName: "Game") } - @NSManaged public var finished: Date? + @NSManaged public var isFinished: Bool @NSManaged public var inWishlist: Bool @NSManaged public var isDigital: Bool @NSManaged public var name: String diff --git a/Zockerhoehle/Info.plist b/Zockerhoehle/Info.plist index e49a713..b946932 100644 --- a/Zockerhoehle/Info.plist +++ b/Zockerhoehle/Info.plist @@ -27,10 +27,27 @@ NSAllowsArbitraryLoads + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + UILaunchStoryboardName LaunchScreen - UIMainStoryboardFile - Main UIRequiredDeviceCapabilities armv7 diff --git a/Zockerhoehle/Model/GameCollection.swift b/Zockerhoehle/Model/GameCollection.swift index 660562d..172fb4d 100644 --- a/Zockerhoehle/Model/GameCollection.swift +++ b/Zockerhoehle/Model/GameCollection.swift @@ -41,10 +41,15 @@ class GameCollection { let cdm = CDManager.shared + var tmpConsole : Console? = .none for console in self.consoles { let cdConsole = Console(entity: Console.entity(), insertInto: cdm.viewContext) cdConsole.name = console.name + if cdConsole.name == "Nintendo Entertainment System" { + tmpConsole = cdConsole + } + cdConsole.generation = Int64(console.generation ?? 0) cdConsole.manufacturer = console.manufacturer @@ -78,6 +83,22 @@ class GameCollection { } } + guard let con = tmpConsole else { + print("No Console") + return + } + let fetchReq = NSFetchRequest(entityName: "Game") + fetchReq.predicate = NSPredicate(format: "console=%@", con) + do { + let fetchRes = try CDManager.shared.viewContext.fetch(fetchReq) + + for g in fetchRes { + print("\(g.name)") + } + }catch { + print(error) + } + }catch let error as NSError { print("Load of Chached not possible \(error.localizedDescription)"); } diff --git a/Zockerhoehle/SceneDelegate.swift b/Zockerhoehle/SceneDelegate.swift new file mode 100644 index 0000000..567ba00 --- /dev/null +++ b/Zockerhoehle/SceneDelegate.swift @@ -0,0 +1,63 @@ +// +// SceneDelegate.swift +// Zockerhoehle +// +// Created by Julian-Steffen Müller on 01.08.19. +// Copyright © 2019 Julian-Steffen Müller. All rights reserved. +// + +import Foundation +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate, UIApplicationDelegate { + var window: UIWindow? + + let gameStore = GameStore(console: .none) + let consoleStore = ConsoleStore() + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Use a UIHostingController as window root view controller + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + let view = ConsolesListView(gameStore: self.gameStore) + window.rootViewController = UIHostingController(rootView: view) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + + // Save changes in the application's managed object context when the application transitions to the background. + } +} diff --git a/Zockerhoehle/Utils/FlockeWS.swift b/Zockerhoehle/Utils/FlockeWS.swift index e5f7200..d26d868 100644 --- a/Zockerhoehle/Utils/FlockeWS.swift +++ b/Zockerhoehle/Utils/FlockeWS.swift @@ -25,14 +25,23 @@ class FlockeWS { print("FETCH ENTRIES: Creating URL fails") return } - + let task = URLSession.shared.dataTask(with: fetchEntriesURL) { (data, resp, err) in if (err == nil) { let consoles : [FlockeEntry] = try! JSONDecoder().decode([FlockeEntry].self, from: data!) DispatchQueue.main.async { GameCollection.shared.updateGameItems(items: consoles, with: parent) + for console in consoles { + FlockeWS.fetchEntries(for: console.id) + + if let att = console.iconAttachment { + FlockeWS.fetchAttachment(attachment: att.id) + } + } } + }else{ + print("FLOCKEWS::fetchEntries; \(err?.localizedDescription ?? "N/A")") } } task.resume() diff --git a/Zockerhoehle/ViewController/AccessoryDetailController.swift b/Zockerhoehle/ViewController/AccessoryDetailController.swift index 2724821..47882c7 100644 --- a/Zockerhoehle/ViewController/AccessoryDetailController.swift +++ b/Zockerhoehle/ViewController/AccessoryDetailController.swift @@ -15,6 +15,7 @@ class AccessoryDetailController : UIViewController { @IBSegueAction func emebdedAccessoryDetaio(_ coder: NSCoder) -> UIViewController? { - return UIHostingController(coder: coder, rootView: AccessoryDetailView(accessory: accessory)) + let accessoryVM = AccessoryViewModel(accessory: accessory!) + return UIHostingController(coder: coder, rootView: AccessoryDetailView(accessoryVM: accessoryVM)) } } diff --git a/Zockerhoehle/ViewController/ConsoleDetailViewController.swift b/Zockerhoehle/ViewController/ConsoleDetailViewController.swift new file mode 100644 index 0000000..df4bc20 --- /dev/null +++ b/Zockerhoehle/ViewController/ConsoleDetailViewController.swift @@ -0,0 +1,17 @@ +// +// ConsoleDetailViewController.swift +// Zockerhoehle +// +// Created by Julian-Steffen Müller on 01.08.19. +// Copyright © 2019 Julian-Steffen Müller. All rights reserved. +// + +import Foundation +import UIKit +import SwiftUI + +class ConsoleDetailViewController : UIViewController { + @IBSegueAction func embedConsoleDetail(_ coder: NSCoder) -> UIViewController? { + return UIHostingController(coder: coder, rootView: ConsoleLibraryView(console: .none)) + } +} diff --git a/Zockerhoehle/ViewController/ConsoleLibraryViewController.swift b/Zockerhoehle/ViewController/ConsoleLibraryViewController.swift index 89b6b87..f0e292e 100644 --- a/Zockerhoehle/ViewController/ConsoleLibraryViewController.swift +++ b/Zockerhoehle/ViewController/ConsoleLibraryViewController.swift @@ -27,9 +27,9 @@ class ConsoleLibraryViewController: UIViewController { //Remove subscription to old console object subsriber?.cancel() - subsriber = console?.publisher(for: \.games, options: .new).sink(receiveValue: {_ in - self.refreshConsoleLibrary() - }) + //subsriber = console?.publisher(for: \.games, options: .new).sink(receiveValue: {_ in + // self.refreshConsoleLibrary() + //}) refreshConsoleLibrary() } diff --git a/Zockerhoehle/ViewController/GameDetailController.swift b/Zockerhoehle/ViewController/GameDetailController.swift index 0a6914a..92db689 100644 --- a/Zockerhoehle/ViewController/GameDetailController.swift +++ b/Zockerhoehle/ViewController/GameDetailController.swift @@ -15,6 +15,11 @@ class GameDetailController : UIViewController { @IBSegueAction func embedConsoleDetail(_ coder: NSCoder) -> UIViewController? { - return UIHostingController(coder: coder, rootView: GameDetailView(game: game)) + guard let game = self.game else { + print("ERROR GameDetailController::emedConsoleDetail; Game optional is empty") + + return UIViewController() + } + return UIHostingController(coder: coder, rootView: GameDetailView(gameVM: GameViewModel(game: game)) ) } } diff --git a/Zockerhoehle/ViewModel/AccessoryStore.swift b/Zockerhoehle/ViewModel/AccessoryStore.swift new file mode 100644 index 0000000..d4ad59f --- /dev/null +++ b/Zockerhoehle/ViewModel/AccessoryStore.swift @@ -0,0 +1,56 @@ +// +// AccessoryStore.swift +// Zockerhoehle +// +// Created by Julian-Steffen Müller on 02.08.19. +// Copyright © 2019 Julian-Steffen Müller. All rights reserved. +// + +import Foundation +import SwiftUI +import CoreData +import Combine + +class AccessoryStore : NSObject, ObservableObject, NSFetchedResultsControllerDelegate { + var objectWillChange = ObservableObjectPublisher() + var consoleFilter : Console? + + var accessories : [Accessory] { + get { + if self.fetchResultsController.fetchedObjects == nil { + do { + try fetchResultsController.performFetch() + }catch { + print("AccessoryStore::accessories Perform Fetch not possible '\(error)'") + } + } + + return self.fetchResultsController.fetchedObjects ?? [] + } + } + + lazy var fetchResultsController : NSFetchedResultsController = { + var accessoriesFetch : NSFetchRequest = Accessory.fetchRequest() + if let console = consoleFilter { + accessoriesFetch = Accessory.fetchRequest(console: console) + } + + accessoriesFetch.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)] + + let accessoriesFetchRC = NSFetchedResultsController(fetchRequest: accessoriesFetch, managedObjectContext: CDManager.shared.viewContext, sectionNameKeyPath: nil, cacheName: nil) + + accessoriesFetchRC.delegate = self + + return accessoriesFetchRC + }() + + init(console : Console?) { + super.init() + self.consoleFilter = console + } + + func controllerDidChangeContent(_ controller: NSFetchedResultsController) { + print("GameStore::controllerDidChangeContent") + self.objectWillChange.send() + } +} diff --git a/Zockerhoehle/ViewModel/AccessoryViewModel.swift b/Zockerhoehle/ViewModel/AccessoryViewModel.swift new file mode 100644 index 0000000..89c0ec0 --- /dev/null +++ b/Zockerhoehle/ViewModel/AccessoryViewModel.swift @@ -0,0 +1,76 @@ +// +// AccessoryViewModel.swift +// Zockerhoehle +// +// Created by Julian-Steffen Müller on 25.07.19. +// Copyright © 2019 Julian-Steffen Müller. All rights reserved. +// + +import Foundation +import UIKit +import Combine +import SwiftUI + +class AccessoryViewModel : ObservableObject { + var objectWillChange = ObservableObjectPublisher() + + var inWishlist : Bool { + didSet { + if let accessory = self.accessory { + accessory.inWishlist = inWishlist + } + } + } + + var manufacturer : String? { + didSet { + if let accessory = self.accessory { + accessory.manufacturer = manufacturer + } + } + } + + var color : String? { + didSet { + if let accessory = self.accessory { + accessory.color = color + } + } + } + + var name : String { + didSet { + if let accessory = self.accessory { + accessory.name = name + } + } + } + + private var accessory : Accessory? { + didSet { + if accessory != nil { + self.name = accessory!.name + self.inWishlist = accessory!.inWishlist + self.color = accessory!.color + self.manufacturer = accessory!.manufacturer + } + } + } + + init(accessory : Accessory) { + self.accessory = accessory + + self.name = accessory.name + self.inWishlist = accessory.inWishlist + self.color = accessory.color + self.manufacturer = accessory.manufacturer + + _ = NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange, object: CDManager.shared.viewContext).sink { + //TODO + self.objectWillChange.send() + if let accessory = self.accessory { + print("Accessory: \(accessory.name) Notification: \($0.description)") + } + } + } +} diff --git a/Zockerhoehle/ViewModel/ConsoleStore.swift b/Zockerhoehle/ViewModel/ConsoleStore.swift new file mode 100644 index 0000000..ee27212 --- /dev/null +++ b/Zockerhoehle/ViewModel/ConsoleStore.swift @@ -0,0 +1,48 @@ +// +// ConsoleStore.swift +// Zockerhoehle +// +// Created by Julian-Steffen Müller on 02.08.19. +// Copyright © 2019 Julian-Steffen Müller. All rights reserved. +// + +import Foundation +import Combine +import SwiftUI +import CoreData + +class ConsoleStore : NSObject, ObservableObject, NSFetchedResultsControllerDelegate { + var objectWillChange = ObservableObjectPublisher() + + var consoles : [Console] { + get { + if self.fetchResultsController.fetchedObjects == nil { + do { + try fetchResultsController.performFetch() + }catch { + print("ConsoleStore::consoles Perform Fetch not possible '\(error)'") + } + } + + return self.fetchResultsController.fetchedObjects ?? [] + } + } + + lazy var fetchResultsController : NSFetchedResultsController = { + let consolesFetch : NSFetchRequest = Console.fetchRequest() + + consolesFetch.sortDescriptors = [NSSortDescriptor(key: "manufacturer", ascending: true), NSSortDescriptor(key: "generation", ascending: true), NSSortDescriptor(key: "name", ascending: true)] + + var consolesfetchRC = NSFetchedResultsController(fetchRequest: consolesFetch, managedObjectContext: CDManager.shared.viewContext, sectionNameKeyPath: nil, cacheName: nil) + + consolesfetchRC.delegate = self + + return consolesfetchRC + + }() + + func controllerDidChangeContent(_ controller: NSFetchedResultsController) { + print("AllConsolesViewController::controllerDidChangeContent") + self.objectWillChange.send() + } +} diff --git a/Zockerhoehle/ViewModel/GameStore.swift b/Zockerhoehle/ViewModel/GameStore.swift new file mode 100644 index 0000000..6d5da0d --- /dev/null +++ b/Zockerhoehle/ViewModel/GameStore.swift @@ -0,0 +1,56 @@ +// +// GameStore.swift +// Zockerhoehle +// +// Created by Julian-Steffen Müller on 02.08.19. +// Copyright © 2019 Julian-Steffen Müller. All rights reserved. +// + +import Foundation +import SwiftUI +import CoreData +import Combine + +class GameStore : NSObject, ObservableObject, NSFetchedResultsControllerDelegate { + var objectWillChange = PassthroughSubject() + var consoleFilter : Console? + + var games : [Game] { + get { + if self.fetchResultsController.fetchedObjects == nil { + do { + try fetchResultsController.performFetch() + }catch { + print("GameStore::games Perform Fetch not possible '\(error)'") + } + } + + return self.fetchResultsController.fetchedObjects ?? [] + } + } + + lazy var fetchResultsController : NSFetchedResultsController = { + var gamesFetch : NSFetchRequest = Game.fetchRequest() + if let console = consoleFilter { + gamesFetch = Game.fetchRequest(console: console) + } + + gamesFetch.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)] + + let gamesFetchRC = NSFetchedResultsController(fetchRequest: gamesFetch, managedObjectContext: CDManager.shared.viewContext, sectionNameKeyPath: nil, cacheName: nil) + + gamesFetchRC.delegate = self + + return gamesFetchRC + }() + + init(console : Console?) { + super.init() + self.consoleFilter = console + } + + func controllerDidChangeContent(_ controller: NSFetchedResultsController) { + print("GameStore::controllerDidChangeContent") + self.objectWillChange.send() + } +} diff --git a/Zockerhoehle/ViewModel/GameViewModel.swift b/Zockerhoehle/ViewModel/GameViewModel.swift new file mode 100644 index 0000000..35f41ec --- /dev/null +++ b/Zockerhoehle/ViewModel/GameViewModel.swift @@ -0,0 +1,77 @@ +// +// GameViewModel.swift +// Zockerhoehle +// +// Created by Julian-Steffen Müller on 21.07.19. +// Copyright © 2019 Julian-Steffen Müller. All rights reserved. +// + +import Foundation +import SwiftUI +import Combine +import CoreData +import UIKit + +class GameViewModel : ObservableObject { + var objectWillChange = ObservableObjectPublisher() + + private var game : Game? { + didSet { + if game != nil { + self.name = game!.name + self.inWishlist = game!.inWishlist + self.isDigital = game!.isDigital + self.isFinished = game!.isFinished + } + } + } + + var name : String { + didSet { + if let game = self.game { + game.name = name + } + } + } + + var inWishlist : Bool { + didSet { + if let game = self.game { + game.inWishlist = inWishlist + } + } + } + + var isDigital : Bool { + didSet { + if let game = self.game { + game.isDigital = isDigital + } + } + } + + var isFinished : Bool { + didSet { + if let game = self.game { + game.isFinished = isFinished + } + } + } + + init(game : Game) { + self.game = game + + self.name = game.name + self.inWishlist = game.inWishlist + self.isDigital = game.isDigital + self.isFinished = game.isFinished + + _ = NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange, object: CDManager.shared.viewContext).sink { + //TODO + self.objectWillChange.send() + if let game = self.game { + print("Game: \(game.name) Notification: \($0.description)") + } + } + } +} diff --git a/Zockerhoehle/Views/AccessoryDetailView.swift b/Zockerhoehle/Views/AccessoryDetailView.swift index b061641..d3fa6f0 100644 --- a/Zockerhoehle/Views/AccessoryDetailView.swift +++ b/Zockerhoehle/Views/AccessoryDetailView.swift @@ -11,19 +11,28 @@ import SwiftUI struct AccessoryDetailView : View { var accessory : Accessory? + @ObservedObject var accessoryVM : AccessoryViewModel + var body: some View { - Text(accessory?.name ?? "N/A").color(Color.red) + Form { + TextField("Accessory name", text: $accessoryVM.name) + + + Toggle(isOn: $accessoryVM.inWishlist, label: { + Text("In Wunschliste") + }) + }.navigationBarTitle(Text("\(accessoryVM.name)"), displayMode: .automatic) } - init(accessory : Accessory?) { - self.accessory = accessory + init(accessoryVM : AccessoryViewModel?) { + self.accessoryVM = accessoryVM! } } #if DEBUG struct AccessoryDetailView_Previews : PreviewProvider { static var previews: some View { - AccessoryDetailView(accessory: nil) + AccessoryDetailView(accessoryVM: nil) } } #endif diff --git a/Zockerhoehle/Views/ConsoleLibraryView.swift b/Zockerhoehle/Views/ConsoleLibraryView.swift new file mode 100644 index 0000000..a5287e6 --- /dev/null +++ b/Zockerhoehle/Views/ConsoleLibraryView.swift @@ -0,0 +1,94 @@ +// +// ConsoleLibraryView.swift +// Zockerhoehle +// +// Created by Julian-Steffen Müller on 01.08.19. +// Copyright © 2019 Julian-Steffen Müller. All rights reserved. +// + +import SwiftUI + + +struct ConsoleLibraryView : View { + @State var isVideogamesSelected = true + var console : Console? + @ObservedObject var gameStore : GameStore + @ObservedObject var accessoryStore : AccessoryStore + + @State var showWishlist = false + + @State var isModal: Bool = false + + var modal: some View { + NavigationView { + Form { + Text("bl") + } + .font(.caption) + .navigationBarTitle(self.isVideogamesSelected ? Text("New Game") : Text("New Accessory")) + .navigationBarItems(trailing: Button(action: { self.isModal = false } ) { Text("Done") }) + } + } + + var body: some View { + VStack { + HStack { + Spacer() + Picker("Options", selection: $isVideogamesSelected) { + Text("Videogames").tag(true) + Text("Accessories").tag(false) + + }.pickerStyle(SegmentedPickerStyle()) + Spacer() + } + if self.isVideogamesSelected { + List { + ForEach(gameStore.games.filter({$0.inWishlist == self.showWishlist})) { game in + NavigationLink(destination: GameDetailView(gameVM: GameViewModel(game: game))) { + Text("\(game.name)") + } + } + } + }else { + List { + + ForEach(accessoryStore.accessories.filter({$0.inWishlist == self.showWishlist})) { accessory in + NavigationLink(destination: AccessoryDetailView(accessoryVM: AccessoryViewModel(accessory: accessory))) { + Text("\(accessory.name)") + } + } + } + } + }.navigationBarTitle(Text("\(self.console?.name ?? "N/A")"), displayMode: .automatic) + .navigationBarItems(trailing: + HStack { + Button(action: { + self.isModal = true + }) { + Image(systemName: "plus") + }.padding(5) + Button(action: { + self.showWishlist.toggle() + }) { + Image(systemName: "star") + }.accentColor(self.showWishlist ? Color.red : Color.blue) + }) + .sheet(isPresented: $isModal, onDismiss: {}, content: { + self.modal + }) + } + + init(console : Console?) { + self.console = console + self.gameStore = GameStore(console: console) + self.accessoryStore = AccessoryStore(console: console) + } +} + +#if DEBUG +struct ConsoleLibraryView_Previews : PreviewProvider { + static var previews: some View { + ConsoleLibraryView(console: .none) + } +} +#endif diff --git a/Zockerhoehle/Views/ConsolesListView.swift b/Zockerhoehle/Views/ConsolesListView.swift new file mode 100644 index 0000000..99e8d0f --- /dev/null +++ b/Zockerhoehle/Views/ConsolesListView.swift @@ -0,0 +1,37 @@ +// +// ConsolesListView.swift +// Zockerhoehle +// +// Created by Julian-Steffen Müller on 01.08.19. +// Copyright © 2019 Julian-Steffen Müller. All rights reserved. +// + +import Foundation +import SwiftUI + +struct ConsolesListView : View { + @ObservedObject var consoleStore : ConsoleStore = ConsoleStore() + @ObservedObject var gameStore : GameStore + + var body: some View { + NavigationView { + List { + ForEach(consoleStore.consoles) {console in + //TODO environmentObject should not be passed through the hierarchy + //This is only for fixin a swiftui bug + NavigationLink(destination: ConsoleLibraryView(console: console)) { + Text("\(console.name)") + } + } + }.navigationBarTitle(Text("Zockerhöhle")) + } + } +} + +#if DEBUG +struct ConsolesListView_Previews : PreviewProvider { + static var previews: some View { + ConsolesListView(gameStore: GameStore(console: .none)) + } +} +#endif diff --git a/Zockerhoehle/Views/GameDetailView.swift b/Zockerhoehle/Views/GameDetailView.swift index c9dbffe..a817d63 100644 --- a/Zockerhoehle/Views/GameDetailView.swift +++ b/Zockerhoehle/Views/GameDetailView.swift @@ -9,20 +9,54 @@ import SwiftUI struct GameDetailView : View { - var game : Game? + //@Binding var g : Game + @ObservedObject var gameVM : GameViewModel + + @State var hasFinishedDate : Bool = false + @State var playthroughDate : Date = Date() + var body: some View { - Text(game?.name ?? "N/A") + Form { + TextField("Videogame name", text: $gameVM.name) + + Toggle(isOn: $gameVM.isDigital, label: { + Text("Nur Digital") + }) + + Toggle(isOn: $gameVM.inWishlist, label: { + Text("In Wunschliste") + }) + + Toggle(isOn: $gameVM.isFinished , label: { + Text("Durchgezockt") + }) + + if gameVM.isFinished { + Toggle(isOn: $hasFinishedDate, label: { + Text("Gibts ein Datum") + }) + } + + if hasFinishedDate && gameVM.isFinished { + DatePicker("Durchgezockt am", + selection: $playthroughDate, + in: ...Date(), + displayedComponents: [.date]) + } + + }.navigationBarTitle(Text("\(gameVM.name)"), displayMode: .automatic) + } - init(game : Game?) { - self.game = game + init(gameVM : GameViewModel?) { + self.gameVM = gameVM! } } #if DEBUG struct GameDetailView_Previews : PreviewProvider { static var previews: some View { - GameDetailView(game: nil) + GameDetailView(gameVM: nil) } } #endif diff --git a/Zockerhoehle/Zockerhoehle.xcdatamodeld/Zockerhoehle.xcdatamodel/contents b/Zockerhoehle/Zockerhoehle.xcdatamodeld/Zockerhoehle.xcdatamodel/contents index 0a345bc..0f3e4d3 100644 --- a/Zockerhoehle/Zockerhoehle.xcdatamodeld/Zockerhoehle.xcdatamodel/contents +++ b/Zockerhoehle/Zockerhoehle.xcdatamodeld/Zockerhoehle.xcdatamodel/contents @@ -1,6 +1,7 @@ + @@ -8,46 +9,48 @@ + - + - + - + + - + - + - + - - + + - - + + \ No newline at end of file diff --git a/Zockerhoehle/de.lproj/Main.strings b/Zockerhoehle/de.lproj/Main.strings deleted file mode 100644 index 8b13789..0000000 --- a/Zockerhoehle/de.lproj/Main.strings +++ /dev/null @@ -1 +0,0 @@ -