Changed Console(View) to new core data swiftu ibest practices. Removed generation and added releaseDate. Adjustes Import/Export

This commit is contained in:
2021-05-18 15:36:12 +02:00
parent 0c40187409
commit 73ced9a452
14 changed files with 111 additions and 165 deletions

View File

@@ -15,7 +15,6 @@
B93D60D122E5009700DD390F /* GameViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93D60D022E5009700DD390F /* GameViewModel.swift */; }; B93D60D122E5009700DD390F /* GameViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B93D60D022E5009700DD390F /* GameViewModel.swift */; };
B94112DE233A37DD00159AE4 /* DateConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112DD233A37DD00159AE4 /* DateConversion.swift */; }; B94112DE233A37DD00159AE4 /* DateConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112DD233A37DD00159AE4 /* DateConversion.swift */; };
B94112E0233A4EF800159AE4 /* GamePickupsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112DF233A4EF800159AE4 /* GamePickupsView.swift */; }; B94112E0233A4EF800159AE4 /* GamePickupsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112DF233A4EF800159AE4 /* GamePickupsView.swift */; };
B94112E2233B55B100159AE4 /* ConsoleViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112E1233B55B100159AE4 /* ConsoleViewModel.swift */; };
B94112E4233B597D00159AE4 /* ConsoleEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112E3233B597D00159AE4 /* ConsoleEditView.swift */; }; B94112E4233B597D00159AE4 /* ConsoleEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94112E3233B597D00159AE4 /* ConsoleEditView.swift */; };
B94CB4FF22D1352F0029BFAD /* Accessory+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */; }; B94CB4FF22D1352F0029BFAD /* Accessory+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */; };
B94CB50022D1352F0029BFAD /* Accessory+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F422D1352F0029BFAD /* Accessory+CoreDataProperties.swift */; }; B94CB50022D1352F0029BFAD /* Accessory+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = B94CB4F422D1352F0029BFAD /* Accessory+CoreDataProperties.swift */; };
@@ -45,6 +44,7 @@
B9A0550322F8C2740054D9A0 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550222F8C2740054D9A0 /* MainView.swift */; }; B9A0550322F8C2740054D9A0 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550222F8C2740054D9A0 /* MainView.swift */; };
B9A0550522F8CB400054D9A0 /* GameSeriesLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550422F8CB400054D9A0 /* GameSeriesLibraryView.swift */; }; B9A0550522F8CB400054D9A0 /* GameSeriesLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A0550422F8CB400054D9A0 /* GameSeriesLibraryView.swift */; };
B9BCCEB92653BDEA005F46D6 /* ICloudManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */; }; B9BCCEB92653BDEA005F46D6 /* ICloudManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */; };
B9BCCEBB2653CA8E005F46D6 /* SwiftUIBindingExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9BCCEBA2653CA8E005F46D6 /* SwiftUIBindingExtension.swift */; };
B9BCF4CA2168ACB600ECBAAC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */; }; B9BCF4CA2168ACB600ECBAAC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */; };
B9D2C6F722E98ED800797F67 /* AccessoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */; }; B9D2C6F722E98ED800797F67 /* AccessoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */; };
B9E2A079233B69D400EAEB14 /* GameSeriesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */; }; B9E2A079233B69D400EAEB14 /* GameSeriesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */; };
@@ -95,7 +95,6 @@
B93D60D022E5009700DD390F /* GameViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewModel.swift; sourceTree = "<group>"; }; B93D60D022E5009700DD390F /* GameViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewModel.swift; sourceTree = "<group>"; };
B94112DD233A37DD00159AE4 /* DateConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateConversion.swift; sourceTree = "<group>"; }; B94112DD233A37DD00159AE4 /* DateConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateConversion.swift; sourceTree = "<group>"; };
B94112DF233A4EF800159AE4 /* GamePickupsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GamePickupsView.swift; sourceTree = "<group>"; }; B94112DF233A4EF800159AE4 /* GamePickupsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GamePickupsView.swift; sourceTree = "<group>"; };
B94112E1233B55B100159AE4 /* ConsoleViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleViewModel.swift; sourceTree = "<group>"; };
B94112E3233B597D00159AE4 /* ConsoleEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleEditView.swift; sourceTree = "<group>"; }; B94112E3233B597D00159AE4 /* ConsoleEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleEditView.swift; sourceTree = "<group>"; };
B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Accessory+CoreDataClass.swift"; sourceTree = "<group>"; }; B94CB4F322D1352F0029BFAD /* Accessory+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Accessory+CoreDataClass.swift"; sourceTree = "<group>"; };
B94CB4F422D1352F0029BFAD /* Accessory+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Accessory+CoreDataProperties.swift"; sourceTree = "<group>"; }; B94CB4F422D1352F0029BFAD /* Accessory+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Accessory+CoreDataProperties.swift"; sourceTree = "<group>"; };
@@ -129,6 +128,7 @@
B9A0550222F8C2740054D9A0 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.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>"; }; 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>"; }; B9BCCEB82653BDEA005F46D6 /* ICloudManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICloudManager.swift; sourceTree = "<group>"; };
B9BCCEBA2653CA8E005F46D6 /* SwiftUIBindingExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIBindingExtension.swift; sourceTree = "<group>"; };
B9BCF4C92168ACB600ECBAAC /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; 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>"; }; 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>"; }; B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameSeriesViewModel.swift; sourceTree = "<group>"; };
@@ -201,6 +201,7 @@
B9EC09812383F94B004BC9AB /* LibraryExport.swift */, B9EC09812383F94B004BC9AB /* LibraryExport.swift */,
B90E03EA238557D900E79643 /* LibraryImport.swift */, B90E03EA238557D900E79643 /* LibraryImport.swift */,
B98CBBE2265045AC00B1B7AC /* URLExtension.swift */, B98CBBE2265045AC00B1B7AC /* URLExtension.swift */,
B9BCCEBA2653CA8E005F46D6 /* SwiftUIBindingExtension.swift */,
); );
path = Utils; path = Utils;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -248,7 +249,6 @@
B93D60CF22E5006F00DD390F /* ViewModel */ = { B93D60CF22E5006F00DD390F /* ViewModel */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
B94112E1233B55B100159AE4 /* ConsoleViewModel.swift */,
B93D60D022E5009700DD390F /* GameViewModel.swift */, B93D60D022E5009700DD390F /* GameViewModel.swift */,
B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */, B9E2A078233B69D400EAEB14 /* GameSeriesViewModel.swift */,
B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */, B9D2C6F622E98ED800797F67 /* AccessoryViewModel.swift */,
@@ -432,7 +432,6 @@
B98CBBE3265045AC00B1B7AC /* URLExtension.swift in Sources */, B98CBBE3265045AC00B1B7AC /* URLExtension.swift in Sources */,
B9839992233A0E19002F9946 /* GameSeriesCover+CoreDataClass.swift in Sources */, B9839992233A0E19002F9946 /* GameSeriesCover+CoreDataClass.swift in Sources */,
B94112E0233A4EF800159AE4 /* GamePickupsView.swift in Sources */, B94112E0233A4EF800159AE4 /* GamePickupsView.swift in Sources */,
B94112E2233B55B100159AE4 /* ConsoleViewModel.swift in Sources */,
B9A0550522F8CB400054D9A0 /* GameSeriesLibraryView.swift in Sources */, B9A0550522F8CB400054D9A0 /* GameSeriesLibraryView.swift in Sources */,
B9839983233A086A002F9946 /* Overview.swift in Sources */, B9839983233A086A002F9946 /* Overview.swift in Sources */,
B93C1B9D21496BFD0014FD6E /* AppDelegate.swift in Sources */, B93C1B9D21496BFD0014FD6E /* AppDelegate.swift in Sources */,
@@ -462,6 +461,7 @@
B9E2A07B233B6A8F00EAEB14 /* GameSeriesEditView.swift in Sources */, B9E2A07B233B6A8F00EAEB14 /* GameSeriesEditView.swift in Sources */,
B926F14721502D53004D36B7 /* CodableExtensionAny.swift in Sources */, B926F14721502D53004D36B7 /* CodableExtensionAny.swift in Sources */,
B94CB50422D1352F0029BFAD /* Game+CoreDataProperties.swift in Sources */, B94CB50422D1352F0029BFAD /* Game+CoreDataProperties.swift in Sources */,
B9BCCEBB2653CA8E005F46D6 /* SwiftUIBindingExtension.swift in Sources */,
B9F44AE922F4655600FC6B29 /* AccessoryStore.swift in Sources */, B9F44AE922F4655600FC6B29 /* AccessoryStore.swift in Sources */,
B98A736022C1738800FB3410 /* CDManager.swift in Sources */, B98A736022C1738800FB3410 /* CDManager.swift in Sources */,
B94CB50222D1352F0029BFAD /* Cover+CoreDataProperties.swift in Sources */, B94CB50222D1352F0029BFAD /* Cover+CoreDataProperties.swift in Sources */,

View File

@@ -48,7 +48,7 @@ extension Accessory : Encodable {
try container.encode(manufacturer, forKey: .manufacturer) try container.encode(manufacturer, forKey: .manufacturer)
try container.encode(name, forKey: .name) try container.encode(name, forKey: .name)
try container.encode(inWishlist, forKey: .inWishlist) try container.encode(inWishlist, forKey: .inWishlist)
try container.encode(console?.uuid!.uuidString ?? "", forKey: .console) try container.encode(console?.uuid.uuidString ?? "", forKey: .console)
try container.encode(lentTo, forKey: .lentTo) try container.encode(lentTo, forKey: .lentTo)
} }
} }

View File

@@ -14,32 +14,6 @@ import UIKit
@objc(Console) @objc(Console)
public class Console: NSManagedObject, Identifiable { public class Console: NSManagedObject, Identifiable {
var logoAsUIImage : UIImage? {
get {
if let logoImage = self.logo?.image {
return logoImage
}
return .none
}
set {
if let logoImage = newValue {
let newLogo = Logo(context: CDManager.shared.viewContext)
newLogo.console = self
newLogo.image = logoImage
self.logo = newLogo
}/*else{
//This deletes the cover?
if let logo = self.logo {
print("Console::logoImage::set DELETE Logo")
CDManager.shared.viewContext.delete(logo)
}
}*/
}
}
public static func compareConsolesByNewestGame(consoleA : Console, consoleB : Console) -> Bool { public static func compareConsolesByNewestGame(consoleA : Console, consoleB : Console) -> Bool {
guard let newestGameConsoleA = (consoleA.games!.allObjects as! [Game]).max(by:{ guard let newestGameConsoleA = (consoleA.games!.allObjects as! [Game]).max(by:{
Game.compareByCreationDate(gameA: $0, gameB: $1) Game.compareByCreationDate(gameA: $0, gameB: $1)
@@ -59,6 +33,13 @@ public class Console: NSManagedObject, Identifiable {
return self.objectID return self.objectID
} }
} }
// Defining default values during creation
public override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
super.init(entity: entity, insertInto: context)
self.uuid = UUID()
self.releaseDate = Date()
}
} }
extension Console : Encodable { extension Console : Encodable {
@@ -67,12 +48,11 @@ extension Console : Encodable {
case uuid case uuid
case name case name
case shortName case shortName
case generation
case manufacturer case manufacturer
case accessories case accessories
case games case games
case logo
case logo_icloud_path case logo_icloud_path
case releaseDate
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
@@ -80,9 +60,10 @@ extension Console : Encodable {
try container.encode(uuid, forKey: .uuid) try container.encode(uuid, forKey: .uuid)
try container.encode(name, forKey: .name) try container.encode(name, forKey: .name)
try container.encode(shortName ?? "", forKey: .shortName) try container.encode(shortName ?? "", forKey: .shortName)
try container.encode(generation, forKey: .generation)
try container.encode(manufacturer ?? "", forKey: .manufacturer) try container.encode(manufacturer ?? "", forKey: .manufacturer)
try container.encode(logo_icloud_path ?? "", forKey: .logo_icloud_path) try container.encode(logo_icloud_path ?? "", forKey: .logo_icloud_path)
print("Encode releaseDate: \(releaseDate)")
try container.encode(releaseDate, forKey: .releaseDate)
var accessoryList : [String] = [] var accessoryList : [String] = []
for accessory in accessories! { for accessory in accessories! {
if let accessory = accessory as? Accessory { if let accessory = accessory as? Accessory {
@@ -98,8 +79,5 @@ extension Console : Encodable {
} }
} }
try container.encode(gamesList, forKey: .games) try container.encode(gamesList, forKey: .games)
let logoBase64 = logo?.image?.pngData()?.base64EncodedString() ?? ""
try container.encode(logoBase64, forKey: .logo)
} }
} }

View File

@@ -17,16 +17,15 @@ extension Console {
return NSFetchRequest<Console>(entityName: "Console") return NSFetchRequest<Console>(entityName: "Console")
} }
@NSManaged public var circumstances: String?
@NSManaged public var generation: Int64 @NSManaged public var generation: Int64
@NSManaged public var manufacturer: String? @NSManaged public var manufacturer: String?
@NSManaged public var name: String? @NSManaged public var name: String?
@NSManaged public var shortName: String? @NSManaged public var shortName: String?
@NSManaged public var uuid: UUID? @NSManaged public var uuid: UUID
@NSManaged public var accessories: NSSet? @NSManaged public var accessories: NSSet?
@NSManaged public var games: NSSet? @NSManaged public var games: NSSet?
@NSManaged public var logo: Logo?
@NSManaged public var logo_icloud_path : String? @NSManaged public var logo_icloud_path : String?
@NSManaged public var releaseDate : Date
} }

View File

@@ -85,7 +85,7 @@ extension Game : Encodable {
try container.encode(isFinished, forKey: .isFinished) try container.encode(isFinished, forKey: .isFinished)
try container.encode(inWishlist, forKey: .inWishlist) try container.encode(inWishlist, forKey: .inWishlist)
let consoleUUID : String = console?.uuid?.uuidString ?? "" let consoleUUID : String = console?.uuid.uuidString ?? ""
let gameSeriesUUID : String = series?.uuid.uuidString ?? "" let gameSeriesUUID : String = series?.uuid.uuidString ?? ""
try container.encode(consoleUUID, forKey: .console) try container.encode(consoleUUID, forKey: .console)
try container.encode(gameSeriesUUID, forKey: .gameSeries) try container.encode(gameSeriesUUID, forKey: .gameSeries)

View File

@@ -12,12 +12,6 @@ import CoreData
import UIKit.UIImage import UIKit.UIImage
extension Logo { extension Logo {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Logo> {
return NSFetchRequest<Logo>(entityName: "Logo")
}
@NSManaged public var image: UIImage? @NSManaged public var image: UIImage?
@NSManaged public var console: Console?
} }

View File

@@ -112,12 +112,8 @@ class LibraryImport {
cdConsole.uuid = console.uuid cdConsole.uuid = console.uuid
cdConsole.manufacturer = console.manufacturer cdConsole.manufacturer = console.manufacturer
cdConsole.shortName = console.shortName cdConsole.shortName = console.shortName
cdConsole.generation = Int64(console.generation) cdConsole.logo_icloud_path = console.logo_icloud_path
cdConsole.releaseDate = console.releaseDate
let cdLogo = Logo(context: CDManager.shared.viewContext)
cdLogo.image = console.logo
cdLogo.console = cdConsole
cdConsole.logo = cdLogo
return cdConsole return cdConsole
} }
@@ -290,9 +286,9 @@ struct BHLGameSeries : Decodable {
struct BHLConsole : Decodable { struct BHLConsole : Decodable {
let uuid : UUID let uuid : UUID
let name : String let name : String
let logo : UIImage? let logo_icloud_path : String?
let generation : Int
let manufacturer : String? let manufacturer : String?
let releaseDate : Date
let shortName : String? let shortName : String?
let accessories : [UUID] let accessories : [UUID]
let games : [UUID] let games : [UUID]
@@ -300,9 +296,9 @@ struct BHLConsole : Decodable {
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case uuid case uuid
case name case name
case logo case logo_icloud_path
case generation
case manufacturer case manufacturer
case releaseDate
case shortName case shortName
case accessories case accessories
case games case games
@@ -312,17 +308,12 @@ struct BHLConsole : Decodable {
let container = try decoder.container(keyedBy: CodingKeys.self) let container = try decoder.container(keyedBy: CodingKeys.self)
uuid = try container.decode(UUID.self, forKey: .uuid) uuid = try container.decode(UUID.self, forKey: .uuid)
name = try container.decode(String.self, forKey: .name) name = try container.decode(String.self, forKey: .name)
generation = try container.decode(Int.self, forKey: .generation) logo_icloud_path = try container.decode(String.self, forKey: .logo_icloud_path)
manufacturer = try container.decode(String?.self, forKey: .manufacturer) manufacturer = try container.decode(String?.self, forKey: .manufacturer)
shortName = try container.decode(String?.self, forKey: .shortName) shortName = try container.decode(String?.self, forKey: .shortName)
accessories = try container.decode([UUID].self, forKey: .accessories) accessories = try container.decode([UUID].self, forKey: .accessories)
releaseDate = try container.decode(Date.self, forKey: .releaseDate)
print("Decode releaseDate: \(releaseDate)")
games = try container.decode([UUID].self, forKey: .games) games = try container.decode([UUID].self, forKey: .games)
if let coverBase64 = try container.decode(String?.self, forKey: .logo),
let coverData = Data(base64Encoded: coverBase64) {
logo = UIImage(data: coverData)
}else {
logo = .none
}
} }
} }

View File

@@ -0,0 +1,17 @@
//
// SwiftUIBindingExtension.swift
// Zockerhoehle
//
// Created by Julian-Steffen Müller on 18.05.21.
// Copyright © 2021 Julian-Steffen Müller. All rights reserved.
//
import Foundation
import SwiftUI
func ??<T>(lhs: Binding<Optional<T>>, rhs: T) -> Binding<T> {
Binding(
get: { lhs.wrappedValue ?? rhs },
set: { lhs.wrappedValue = $0 }
)
}

View File

@@ -1,55 +0,0 @@
//
// ConsoleViewModel.swift
// Zockerhoehle
//
// Created by Julian-Steffen Müller on 25.09.19.
// Copyright © 2019 Julian-Steffen Müller. All rights reserved.
//
import SwiftUI
import Combine
class ConsoleViewModel : ObservableObject {
//var objectWillChange = ObservableObjectPublisher()
init(_ console: Console) {
self.console = console
self.name = console.name!
}
private var console : Console? {
didSet {
guard let console = console else { return }
self.name = console.name!
}
}
@Published var name : String {
didSet {
guard let console = console else { return }
console.name = name
}
}
var logo : UIImage? {
get {
if let logoImage = self.console?.logo?.image {
return logoImage
}
return .none
}
set {
if let console = self.console {
if let logoImage = newValue {
let newLogo = Logo(context: CDManager.shared.viewContext)
newLogo.console = console
newLogo.image = logoImage
console.logo = newLogo
}
}
}
}
}

View File

@@ -16,18 +16,24 @@ struct ModalAddConsoleToLibrary : View {
@State var modalConsoleName : String = "" @State var modalConsoleName : String = ""
@State var modalConsoleLogoICloudPath : String? = .none @State var modalConsoleLogoICloudPath : String? = .none
@State var modalConsoleShortName : String = ""
@State var isImporting : Bool = false @State var modalConsoleManufacturer : String = ""
@State var modalConsoleReleaseDate : Date = Date()
@State var isImportingLogo : Bool = false
let defaultImage = UIImage() let defaultImage = UIImage()
var addButton : some View { var addButton : some View {
return Button(action: { return Button(action: {
let console = Console(context: viewContext) let console = Console(context: viewContext)
console.name = self.modalConsoleName console.name = modalConsoleName
console.logo_icloud_path = self.modalConsoleLogoICloudPath console.shortName = modalConsoleShortName
console.manufacturer = modalConsoleManufacturer
console.releaseDate = modalConsoleReleaseDate
self.presentationMode.wrappedValue.dismiss()}, console.logo_icloud_path = self.modalConsoleLogoICloudPath
self.presentationMode.wrappedValue.dismiss()},
label: { Text("Fertig") }) label: { Text("Fertig") })
.disabled(self.modalConsoleName.trimmingCharacters(in: .whitespacesAndNewlines) == "" ) .disabled(self.modalConsoleName.trimmingCharacters(in: .whitespacesAndNewlines) == "" )
} }
@@ -36,11 +42,16 @@ struct ModalAddConsoleToLibrary : View {
NavigationView { NavigationView {
Form { Form {
TextField("Name", text: $modalConsoleName) TextField("Name", text: $modalConsoleName)
TextField("Abkürzung", text: $modalConsoleShortName)
TextField("Hersteller", text: $modalConsoleManufacturer)
DatePicker(selection: $modalConsoleReleaseDate, in: ...Date(), displayedComponents: .date) {
Text("Erscheinungsjahr")
}
Image(uiImage: ICloudManager.imageFrom(path: self.modalConsoleLogoICloudPath) ?? defaultImage) Image(uiImage: ICloudManager.imageFrom(path: self.modalConsoleLogoICloudPath) ?? defaultImage)
.resizable() .resizable()
.scaledToFit() .scaledToFit()
Button(action: { Button(action: {
isImporting = true; isImportingLogo = true;
}, label: { Text("Bla")}) }, label: { Text("Bla")})
} }
.font(.caption) .font(.caption)
@@ -51,7 +62,7 @@ struct ModalAddConsoleToLibrary : View {
trailing: addButton) trailing: addButton)
.navigationViewStyle(StackNavigationViewStyle()) .navigationViewStyle(StackNavigationViewStyle())
.fileImporter( .fileImporter(
isPresented: $isImporting, isPresented: $isImportingLogo,
allowedContentTypes: [.jpeg, .png], allowedContentTypes: [.jpeg, .png],
allowsMultipleSelection: false allowsMultipleSelection: false
) { result in ) { result in
@@ -70,7 +81,6 @@ struct ModalAddConsoleToLibrary : View {
}catch{ }catch{
print("ConsoleAllView::ModalAddConsoleToLibrary Error getting result '\(result)'") print("ConsoleAllView::ModalAddConsoleToLibrary Error getting result '\(result)'")
} }
} }
} }
} }

View File

@@ -9,34 +9,47 @@
import SwiftUI import SwiftUI
struct ConsoleEditView: View { struct ConsoleEditView: View {
@ObservedObject var consoleViewModel : ConsoleViewModel @ObservedObject var console : Console
@State var showLogoImagePicker = false @State var isImportingLogo : Bool = false
let defaultImage = UIImage()
var body: some View { var body: some View {
Form { Form {
TextField("Name der Konsole", text: $consoleViewModel.name) TextField("Name der Konsole", text: $console.name ?? "n/a")
TextField("Abkürzung", text: $console.shortName ?? "")
consoleViewModel.logo.map { TextField("Hersteller", text: $console.manufacturer ?? "")
Image (uiImage: $0) DatePicker(selection: $console.releaseDate, in: ...Date(), displayedComponents: .date) {
.resizable() Text("Erscheinungsjahr")
.frame(width:100, height: 100)
} }
Button(action: { self.showLogoImagePicker = true }, label: { Text("Pick Image") }) Image(uiImage: ICloudManager.imageFrom(path: self.console.logo_icloud_path) ?? defaultImage)
.resizable()
.frame(width:100, height: 100)
Button(action: { self.isImportingLogo = true }, label: { Text("Pick Image") })
} }
.navigationBarTitle("Editiere Konsole") .navigationBarTitle("Editiere Konsole")
.sheet(isPresented: $showLogoImagePicker) { .fileImporter(
ImagePicker.shared.view isPresented: $isImportingLogo,
} allowedContentTypes: [.jpeg, .png],
.onReceive(ImagePicker.shared.objectWillChange, perform: { image in allowsMultipleSelection: false
if let image = image { ) { result in
self.consoleViewModel.logo = image 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)) {
console.logo_icloud_path = ICloudManager.relativePathFrom(url: selectedFile)
print("Selected Image in iCloud Path \(console.logo_icloud_path ?? "n/a")")
}else{
Alert(title: Text("Falscher Ordner"))
print("Außerhalb \(selectedFile.relativeString)")
}
}catch{
print("ConsoleAllView::ModalAddConsoleToLibrary Error getting result '\(result)'")
} }
}) }
}
init(_ console : Console) {
self.consoleViewModel = ConsoleViewModel(console)
} }
} }

View File

@@ -129,7 +129,7 @@ struct ConsoleLibraryView : View {
.navigationBarTitle(Text("\(self.console?.name ?? "N/A")"), displayMode: .automatic) .navigationBarTitle(Text("\(self.console?.name ?? "N/A")"), displayMode: .automatic)
.navigationBarItems(trailing: .navigationBarItems(trailing:
HStack { HStack {
NavigationLink(destination: ConsoleEditView(self.console!)) { NavigationLink(destination: ConsoleEditView(console: self.console!)) {
Image(systemName: "pencil.and.ellipsis.rectangle") Image(systemName: "pencil.and.ellipsis.rectangle")
} }

View File

@@ -57,6 +57,8 @@ struct Overview: View {
@ObservedObject var featuredStore = FeaturedStore() @ObservedObject var featuredStore = FeaturedStore()
let defaultImage = UIImage()
var ConsolesOverview : some View { var ConsolesOverview : some View {
VStack(alignment: .leading) { VStack(alignment: .leading) {
OverviewHeader(title: "Aktivste Konsolen", destination: ConsolesListView()) OverviewHeader(title: "Aktivste Konsolen", destination: ConsolesListView())
@@ -70,12 +72,10 @@ struct Overview: View {
NavigationLink(destination: ConsoleLibraryView(console: console)) { NavigationLink(destination: ConsoleLibraryView(console: console)) {
VStack(alignment: .leading) { VStack(alignment: .leading) {
Group { Group {
console.logo?.image.map { Image(uiImage: ICloudManager.imageFrom(path: console.logo_icloud_path) ?? defaultImage)
Image(uiImage: $0) .resizable()
.resizable() .padding(10)
.padding(10) .cornerRadius(5)
.cornerRadius(5)
}
} }
.frame(width: 100, height: 100) .frame(width: 100, height: 100)
//.background(Color(UIColor.lightGray)) //.background(Color(UIColor.lightGray))
@@ -184,10 +184,11 @@ struct Overview: View {
Spacer() Spacer()
if featuredStore.featuredConsole != nil { if featuredStore.featuredConsole != nil {
NavigationLink(destination: ConsoleLibraryView(console: featuredStore.featuredConsole!)) { NavigationLink(destination: ConsoleLibraryView(console: featuredStore.featuredConsole!)) {
if featuredStore.featuredConsole?.logo?.image != nil { if ICloudManager.fileExists(at: featuredStore.featuredConsole?.logo_icloud_path) {
featuredStore.featuredConsole?.logo?.image.map { Image(uiImage: ICloudManager.imageFrom(path: featuredStore.featuredConsole?.logo_icloud_path) ?? defaultImage)
Image(uiImage: $0).resizable().frame(width: 200, height: 200) .resizable()
} .padding(10)
.cornerRadius(5)
}else{ }else{
//TODO: Symbol für fehlendes Bild //TODO: Symbol für fehlendes Bild
Image(systemName: "cave").frame(width: 200, height: 200) Image(systemName: "cave").frame(width: 200, height: 200)

View File

@@ -11,16 +11,15 @@
<relationship name="console" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Console" inverseName="accessories" inverseEntity="Console"/> <relationship name="console" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Console" inverseName="accessories" inverseEntity="Console"/>
</entity> </entity>
<entity name="Console" representedClassName="Console" syncable="YES"> <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="generation" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="logo_icloud_path" optional="YES" attributeType="String"/> <attribute name="logo_icloud_path" optional="YES" attributeType="String"/>
<attribute name="manufacturer" optional="YES" attributeType="String"/> <attribute name="manufacturer" optional="YES" attributeType="String"/>
<attribute name="name" attributeType="String" defaultValueString=""/> <attribute name="name" attributeType="String" defaultValueString=""/>
<attribute name="releaseDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="shortName" optional="YES" attributeType="String"/> <attribute name="shortName" optional="YES" attributeType="String"/>
<attribute name="uuid" optional="YES" attributeType="UUID" defaultValueString="00000000-0000-0000-0000-000000000000" usesScalarValueType="NO"/> <attribute name="uuid" optional="YES" attributeType="UUID" defaultValueString="00000000-0000-0000-0000-000000000000" usesScalarValueType="NO"/>
<relationship name="accessories" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Accessory" inverseName="console" inverseEntity="Accessory"/> <relationship name="accessories" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Accessory" inverseName="console" inverseEntity="Accessory"/>
<relationship name="games" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Game" inverseName="console" inverseEntity="Game"/> <relationship name="games" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Game" inverseName="console" inverseEntity="Game"/>
<relationship name="logo" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="Logo" inverseName="console" inverseEntity="Logo"/>
</entity> </entity>
<entity name="Cover" representedClassName="Cover" syncable="YES"> <entity name="Cover" representedClassName="Cover" syncable="YES">
<attribute name="image" optional="YES" attributeType="Transformable" valueTransformerName="NSSecureUnarchiveFromData"/> <attribute name="image" optional="YES" attributeType="Transformable" valueTransformerName="NSSecureUnarchiveFromData"/>
@@ -56,15 +55,14 @@
</entity> </entity>
<entity name="Logo" representedClassName="Logo" syncable="YES"> <entity name="Logo" representedClassName="Logo" syncable="YES">
<attribute name="image" optional="YES" attributeType="Transformable" valueTransformerName="NSSecureUnarchiveFromData"/> <attribute name="image" optional="YES" attributeType="Transformable" valueTransformerName="NSSecureUnarchiveFromData"/>
<relationship name="console" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Console" inverseName="logo" inverseEntity="Console"/>
</entity> </entity>
<elements> <elements>
<element name="Accessory" positionX="-265.9140625" positionY="29.15625" width="128" height="149"/> <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="179"/> <element name="Console" positionX="-535.7890625" positionY="56.03515625" width="128" height="164"/>
<element name="Cover" positionX="-66.69921875" positionY="223.48046875" width="128" height="59"/> <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="Game" positionX="-288.828125" positionY="276.7421875" width="128" height="245"/>
<element name="GameSeries" positionX="-686.828125" positionY="359.20703125" width="128" height="89"/> <element name="GameSeries" positionX="-686.828125" positionY="359.20703125" width="128" height="89"/>
<element name="GameSeriesCover" positionX="-477" positionY="180" width="128" height="59"/> <element name="GameSeriesCover" positionX="-477" positionY="180" width="128" height="59"/>
<element name="Logo" positionX="-66.7109375" positionY="110.9765625" width="128" height="73"/> <element name="Logo" positionX="-66.7109375" positionY="110.9765625" width="128" height="44"/>
</elements> </elements>
</model> </model>