Makes DTOs implement Codable instead of just Encodable and Decodable.
Adds MonsterDocument to load/save .monster files.
This commit is contained in:
		| @@ -22,6 +22,7 @@ | |||||||
| 		E216B7B7260C5A9800FB205F /* ChallengeRatingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E216B7B6260C5A9800FB205F /* ChallengeRatingViewModel.swift */; }; | 		E216B7B7260C5A9800FB205F /* ChallengeRatingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E216B7B6260C5A9800FB205F /* ChallengeRatingViewModel.swift */; }; | ||||||
| 		E216B7BC260C691400FB205F /* EditChallengeRating.swift in Sources */ = {isa = PBXBuildFile; fileRef = E216B7BB260C691400FB205F /* EditChallengeRating.swift */; }; | 		E216B7BC260C691400FB205F /* EditChallengeRating.swift in Sources */ = {isa = PBXBuildFile; fileRef = E216B7BB260C691400FB205F /* EditChallengeRating.swift */; }; | ||||||
| 		E216B7C1260C6B6000FB205F /* MCChallengeRatingPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E216B7C0260C6B6000FB205F /* MCChallengeRatingPicker.swift */; }; | 		E216B7C1260C6B6000FB205F /* MCChallengeRatingPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E216B7C0260C6B6000FB205F /* MCChallengeRatingPicker.swift */; }; | ||||||
|  | 		E216E465261FDA2E00FD9262 /* MonsterDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = E216E464261FDA2E00FD9262 /* MonsterDocument.swift */; }; | ||||||
| 		E2182E6425B22F8A00DFAEF8 /* Monster+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */; }; | 		E2182E6425B22F8A00DFAEF8 /* Monster+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */; }; | ||||||
| 		E219247B261989B400C84E12 /* MonsterDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219247A261989B400C84E12 /* MonsterDTO.swift */; }; | 		E219247B261989B400C84E12 /* MonsterDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219247A261989B400C84E12 /* MonsterDTO.swift */; }; | ||||||
| 		E2192480261989F700C84E12 /* SavingThrowDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219247F261989F700C84E12 /* SavingThrowDTO.swift */; }; | 		E2192480261989F700C84E12 /* SavingThrowDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219247F261989F700C84E12 /* SavingThrowDTO.swift */; }; | ||||||
| @@ -102,6 +103,7 @@ | |||||||
| 		E216B7B6260C5A9800FB205F /* ChallengeRatingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeRatingViewModel.swift; sourceTree = "<group>"; }; | 		E216B7B6260C5A9800FB205F /* ChallengeRatingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeRatingViewModel.swift; sourceTree = "<group>"; }; | ||||||
| 		E216B7BB260C691400FB205F /* EditChallengeRating.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditChallengeRating.swift; sourceTree = "<group>"; }; | 		E216B7BB260C691400FB205F /* EditChallengeRating.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditChallengeRating.swift; sourceTree = "<group>"; }; | ||||||
| 		E216B7C0260C6B6000FB205F /* MCChallengeRatingPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCChallengeRatingPicker.swift; sourceTree = "<group>"; }; | 		E216B7C0260C6B6000FB205F /* MCChallengeRatingPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCChallengeRatingPicker.swift; sourceTree = "<group>"; }; | ||||||
|  | 		E216E464261FDA2E00FD9262 /* MonsterDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonsterDocument.swift; sourceTree = "<group>"; }; | ||||||
| 		E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Monster+CoreDataClass.swift"; sourceTree = "<group>"; }; | 		E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Monster+CoreDataClass.swift"; sourceTree = "<group>"; }; | ||||||
| 		E219247A261989B400C84E12 /* MonsterDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonsterDTO.swift; sourceTree = "<group>"; }; | 		E219247A261989B400C84E12 /* MonsterDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonsterDTO.swift; sourceTree = "<group>"; }; | ||||||
| 		E219247F261989F700C84E12 /* SavingThrowDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavingThrowDTO.swift; sourceTree = "<group>"; }; | 		E219247F261989F700C84E12 /* SavingThrowDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavingThrowDTO.swift; sourceTree = "<group>"; }; | ||||||
| @@ -216,13 +218,13 @@ | |||||||
| 		E2570FB725B1AC520055B23B /* MonsterCards */ = { | 		E2570FB725B1AC520055B23B /* MonsterCards */ = { | ||||||
| 			isa = PBXGroup; | 			isa = PBXGroup; | ||||||
| 			children = ( | 			children = ( | ||||||
| 				E2570FC625B1AC550055B23B /* Info.plist */, |  | ||||||
| 				E2570FB825B1AC520055B23B /* MonsterCardsApp.swift */, |  | ||||||
| 				E2570FC125B1AC550055B23B /* Persistence.swift */, |  | ||||||
| 				E2570FBC25B1AC550055B23B /* Assets.xcassets */, | 				E2570FBC25B1AC550055B23B /* Assets.xcassets */, | ||||||
| 				E2D473FB25B5328800CB36D7 /* Helpers */, | 				E2D473FB25B5328800CB36D7 /* Helpers */, | ||||||
|  | 				E2570FC625B1AC550055B23B /* Info.plist */, | ||||||
| 				E257101225B1B2790055B23B /* Models */, | 				E257101225B1B2790055B23B /* Models */, | ||||||
| 				E2570FC325B1AC550055B23B /* MonsterCards.xcdatamodeld */, | 				E2570FC325B1AC550055B23B /* MonsterCards.xcdatamodeld */, | ||||||
|  | 				E2570FB825B1AC520055B23B /* MonsterCardsApp.swift */, | ||||||
|  | 				E2570FC125B1AC550055B23B /* Persistence.swift */, | ||||||
| 				E2570FBE25B1AC550055B23B /* Preview Content */, | 				E2570FBE25B1AC550055B23B /* Preview Content */, | ||||||
| 				E2570FEB25B1ADA90055B23B /* Views */, | 				E2570FEB25B1ADA90055B23B /* Views */, | ||||||
| 			); | 			); | ||||||
| @@ -301,6 +303,7 @@ | |||||||
| 				E219249326198A8200C84E12 /* LanguageDTO.swift */, | 				E219249326198A8200C84E12 /* LanguageDTO.swift */, | ||||||
| 				E216B790260C1FE800FB205F /* LanguageViewModel.swift */, | 				E216B790260C1FE800FB205F /* LanguageViewModel.swift */, | ||||||
| 				E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */, | 				E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */, | ||||||
|  | 				E216E464261FDA2E00FD9262 /* MonsterDocument.swift */, | ||||||
| 				E219247A261989B400C84E12 /* MonsterDTO.swift */, | 				E219247A261989B400C84E12 /* MonsterDTO.swift */, | ||||||
| 				E20209FA25D8E19100EFE733 /* MonsterViewModel.swift */, | 				E20209FA25D8E19100EFE733 /* MonsterViewModel.swift */, | ||||||
| 				E219247F261989F700C84E12 /* SavingThrowDTO.swift */, | 				E219247F261989F700C84E12 /* SavingThrowDTO.swift */, | ||||||
| @@ -497,6 +500,7 @@ | |||||||
| 				E219248F26198A6A00C84E12 /* DamageTypeDTO.swift in Sources */, | 				E219248F26198A6A00C84E12 /* DamageTypeDTO.swift in Sources */, | ||||||
| 				E20209F425D8E04300EFE733 /* ProficiencyType.swift in Sources */, | 				E20209F425D8E04300EFE733 /* ProficiencyType.swift in Sources */, | ||||||
| 				E2CB0DC526086E5F00142591 /* SizeType.swift in Sources */, | 				E2CB0DC526086E5F00142591 /* SizeType.swift in Sources */, | ||||||
|  | 				E216E465261FDA2E00FD9262 /* MonsterDocument.swift in Sources */, | ||||||
| 				E254F906260D0818009295A5 /* AbilityViewModel.swift in Sources */, | 				E254F906260D0818009295A5 /* AbilityViewModel.swift in Sources */, | ||||||
| 				E2570FFA25B1AE020055B23B /* Collections.swift in Sources */, | 				E2570FFA25B1AE020055B23B /* Collections.swift in Sources */, | ||||||
| 				E24ACE5B2607F0F2009BF703 /* EditSpeed.swift in Sources */, | 				E24ACE5B2607F0F2009BF703 /* EditSpeed.swift in Sources */, | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ private enum LanguageDTOCodingKeys: String, CodingKey { | |||||||
|     case speaks = "speaks" |     case speaks = "speaks" | ||||||
| } | } | ||||||
|  |  | ||||||
| extension LanguageDTO: Decodable { | extension LanguageDTO: Codable { | ||||||
|          |          | ||||||
|     init(from decoder: Decoder) throws { |     init(from decoder: Decoder) throws { | ||||||
|          |          | ||||||
| @@ -25,9 +25,6 @@ extension LanguageDTO: Decodable { | |||||||
|         self.name = (try? container.decode(String.self, forKey: .name)) ?? "" |         self.name = (try? container.decode(String.self, forKey: .name)) ?? "" | ||||||
|         self.speaks = (try? container.decode(Bool.self, forKey: .speaks)) ?? false |         self.speaks = (try? container.decode(Bool.self, forKey: .speaks)) ?? false | ||||||
|     } |     } | ||||||
| } |  | ||||||
|  |  | ||||||
| extension LanguageDTO: Encodable { |  | ||||||
|      |      | ||||||
|     func encode(to encoder: Encoder) throws { |     func encode(to encoder: Encoder) throws { | ||||||
|      |      | ||||||
|   | |||||||
| @@ -69,6 +69,70 @@ struct MonsterDTO { | |||||||
|     var doubleColumns: Bool |     var doubleColumns: Bool | ||||||
|     var separationPoint: Int |     var separationPoint: Int | ||||||
|     var damage: [DamageTypeDTO] // TODO: figure this out |     var damage: [DamageTypeDTO] // TODO: figure this out | ||||||
|  |      | ||||||
|  |     init() { | ||||||
|  |         self.abilities = [] | ||||||
|  |         self.actions = [] | ||||||
|  |         self.alignment = "" | ||||||
|  |         self.armorName = "" | ||||||
|  |         self.blind = false | ||||||
|  |         self.blindsight = 0 | ||||||
|  |         self.burrowSpeed = 0 | ||||||
|  |         self.chaPoints = 0 | ||||||
|  |         self.climbSpeed = 0 | ||||||
|  |         self.conPoints = 0 | ||||||
|  |         self.conditions = [] | ||||||
|  |         self.cr = "" | ||||||
|  |         self.customCr = "" | ||||||
|  |         self.customHP = false | ||||||
|  |         self.customProf = 0 | ||||||
|  |         self.customSpeed = false | ||||||
|  |         self.damage = [] | ||||||
|  |         self.damageTypes = [] | ||||||
|  |         self.darkvision = 0 | ||||||
|  |         self.dexPoints = 0 | ||||||
|  |         self.doubleColumns = false | ||||||
|  |         self.flySpeed = 0 | ||||||
|  |         self.hitDice = 0 | ||||||
|  |         self.hover = false | ||||||
|  |         self.hpText = "" | ||||||
|  |         self.intPoints = 0 | ||||||
|  |         self.isLair = false | ||||||
|  |         self.isLegendary = false | ||||||
|  |         self.isRegional = false | ||||||
|  |         self.lairs = [] | ||||||
|  |         self.languages = [] | ||||||
|  |         self.legendaries = [] | ||||||
|  |         self.lairDescription = "" | ||||||
|  |         self.legendaryDescription = "" | ||||||
|  |         self.lairDescriptionEnd = "" | ||||||
|  |         self.name = "" | ||||||
|  |         self.natArmorBonus = 0 | ||||||
|  |         self.otherArmorDesc = "" | ||||||
|  |         self.reactions = [] | ||||||
|  |         self.regionals = [] | ||||||
|  |         self.regionalDescription = "" | ||||||
|  |         self.regionalDescriptionEnd = "" | ||||||
|  |         self.size = "" | ||||||
|  |         self.speed = 0 | ||||||
|  |         self.skills = [] | ||||||
|  |         self.sthrows = [] | ||||||
|  |         self.strPoints = 0 | ||||||
|  |         self.swimSpeed = 0 | ||||||
|  |         self.speedDesc = "" | ||||||
|  |         self.shortName = "" | ||||||
|  |         self.specialDamage = [] | ||||||
|  |         self.shieldBonus = 0 | ||||||
|  |         self.separationPoint = 0 | ||||||
|  |         self.type = "" | ||||||
|  |         self.tag = "" | ||||||
|  |         self.telepathy = 0 | ||||||
|  |         self.truesight = 0 | ||||||
|  |         self.tremorsense = 0 | ||||||
|  |         self.understandsBut = "" | ||||||
|  |         self.wisPoints = 0 | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| enum MonsterDTOCodingKeys: String, CodingKey { | enum MonsterDTOCodingKeys: String, CodingKey { | ||||||
| @@ -135,7 +199,7 @@ enum MonsterDTOCodingKeys: String, CodingKey { | |||||||
|     case damage = "damage" |     case damage = "damage" | ||||||
| } | } | ||||||
|  |  | ||||||
| extension MonsterDTO: Decodable { | extension MonsterDTO: Codable { | ||||||
|     init(from decoder: Decoder) throws { |     init(from decoder: Decoder) throws { | ||||||
|         let container = try decoder.container(keyedBy: MonsterDTOCodingKeys.self) |         let container = try decoder.container(keyedBy: MonsterDTOCodingKeys.self) | ||||||
|         self.name = (try? container.decode(String.self, forKey: .name)) ?? "Imported Monster" |         self.name = (try? container.decode(String.self, forKey: .name)) ?? "Imported Monster" | ||||||
| @@ -207,9 +271,6 @@ extension MonsterDTO: Decodable { | |||||||
|         self.damageTypes = (try? container.decode([DamageTypeDTO].self, forKey: .damageTypes)) ?? [] |         self.damageTypes = (try? container.decode([DamageTypeDTO].self, forKey: .damageTypes)) ?? [] | ||||||
|         self.languages = (try? container.decode([LanguageDTO].self, forKey: .languages)) ?? [] |         self.languages = (try? container.decode([LanguageDTO].self, forKey: .languages)) ?? [] | ||||||
|     } |     } | ||||||
| } |  | ||||||
|  |  | ||||||
| extension MonsterDTO: Encodable { |  | ||||||
|      |      | ||||||
|     func encode(to encoder: Encoder) throws { |     func encode(to encoder: Encoder) throws { | ||||||
|         var container = encoder.container(keyedBy: MonsterDTOCodingKeys.self) |         var container = encoder.container(keyedBy: MonsterDTOCodingKeys.self) | ||||||
| @@ -266,7 +327,7 @@ extension MonsterDTO: Encodable { | |||||||
|         try container.encode(self.isRegional, forKey: .isRegional) |         try container.encode(self.isRegional, forKey: .isRegional) | ||||||
|         try container.encode(self.regionalDescription, forKey: .regionalDescription) |         try container.encode(self.regionalDescription, forKey: .regionalDescription) | ||||||
|         try container.encode(self.regionalDescriptionEnd, forKey: .regionalDescriptionEnd) |         try container.encode(self.regionalDescriptionEnd, forKey: .regionalDescriptionEnd) | ||||||
| //        try container.encode(self.properties, forKey: .properties) |         try container.encode([] as [TraitDTO], forKey: .properties) | ||||||
|         try container.encode(self.lairs, forKey: .lairs) |         try container.encode(self.lairs, forKey: .lairs) | ||||||
|         try container.encode(self.regionals, forKey: .regionals) |         try container.encode(self.regionals, forKey: .regionals) | ||||||
|         try container.encode(self.specialDamage, forKey: .specialDamage) |         try container.encode(self.specialDamage, forKey: .specialDamage) | ||||||
|   | |||||||
							
								
								
									
										37
									
								
								MonsterCards/Models/MonsterDocument.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								MonsterCards/Models/MonsterDocument.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | // | ||||||
|  | //  Document.swift | ||||||
|  | //  MonsterCards | ||||||
|  | // | ||||||
|  | //  Created by Tom Hicks on 4/7/21. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | import UIKit | ||||||
|  | import SceneKit | ||||||
|  |  | ||||||
|  | class MonsterDocument: UIDocument { | ||||||
|  |  | ||||||
|  |     var monsterDTO: MonsterDTO? | ||||||
|  |     var error: Error? | ||||||
|  |      | ||||||
|  |     override func contents(forType typeName: String) throws -> Any { | ||||||
|  |         let encoder = JSONEncoder() | ||||||
|  |         do { | ||||||
|  |             let data = try encoder.encode(monsterDTO) | ||||||
|  |             return data | ||||||
|  |         } catch { | ||||||
|  |             return Data() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     override func load(fromContents contents: Any, ofType typeName: String?) throws { | ||||||
|  |         let decoder = JSONDecoder() | ||||||
|  |         do { | ||||||
|  |             let data = contents as! Data | ||||||
|  |             monsterDTO = try decoder.decode(MonsterDTO.self, from: data) | ||||||
|  |         } catch { | ||||||
|  |             monsterDTO = MonsterDTO() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -17,7 +17,7 @@ private enum SavingThrowDTOCodingKeys: String, CodingKey { | |||||||
|     case order = "order" |     case order = "order" | ||||||
| } | } | ||||||
|  |  | ||||||
| extension SavingThrowDTO: Decodable { | extension SavingThrowDTO: Codable { | ||||||
|      |      | ||||||
|     init(from decoder: Decoder) throws { |     init(from decoder: Decoder) throws { | ||||||
|          |          | ||||||
| @@ -25,9 +25,6 @@ extension SavingThrowDTO: Decodable { | |||||||
|         self.name = (try? container.decode(String.self, forKey: .name)) ?? "" |         self.name = (try? container.decode(String.self, forKey: .name)) ?? "" | ||||||
|         self.order = (try? container.decode(Int.self, forKey: .order)) ?? 0 |         self.order = (try? container.decode(Int.self, forKey: .order)) ?? 0 | ||||||
|     } |     } | ||||||
| } |  | ||||||
|  |  | ||||||
| extension SavingThrowDTO: Encodable { |  | ||||||
|      |      | ||||||
|     func encode(to encoder: Encoder) throws { |     func encode(to encoder: Encoder) throws { | ||||||
|      |      | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ private enum SkillDTOCodingKeys: String, CodingKey { | |||||||
|     case note = "note" |     case note = "note" | ||||||
| } | } | ||||||
|  |  | ||||||
| extension SkillDTO: Decodable { | extension SkillDTO: Codable { | ||||||
|      |      | ||||||
|     init(from decoder: Decoder) throws { |     init(from decoder: Decoder) throws { | ||||||
|          |          | ||||||
| @@ -28,9 +28,6 @@ extension SkillDTO: Decodable { | |||||||
|         self.note = (try? container.decode(String.self, forKey: .note)) ?? "" |         self.note = (try? container.decode(String.self, forKey: .note)) ?? "" | ||||||
|         self.stat = (try? container.decode(String.self, forKey: .stat)) ?? "" |         self.stat = (try? container.decode(String.self, forKey: .stat)) ?? "" | ||||||
|     } |     } | ||||||
| } |  | ||||||
|  |  | ||||||
| extension SkillDTO: Encodable { |  | ||||||
|      |      | ||||||
|     func encode(to encoder: Encoder) throws { |     func encode(to encoder: Encoder) throws { | ||||||
|      |      | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ private enum TraitDTOCodingKeys: String, CodingKey { | |||||||
|     case desc = "desc" |     case desc = "desc" | ||||||
| } | } | ||||||
|  |  | ||||||
| extension TraitDTO: Decodable { | extension TraitDTO: Codable { | ||||||
|      |      | ||||||
|     init(from decoder: Decoder) throws { |     init(from decoder: Decoder) throws { | ||||||
|          |          | ||||||
| @@ -28,9 +28,6 @@ extension TraitDTO: Decodable { | |||||||
|         self.note = (try? container.decode(String.self, forKey: .note)) ?? "" |         self.note = (try? container.decode(String.self, forKey: .note)) ?? "" | ||||||
|         self.desc = (try? container.decode(String.self, forKey: .desc)) ?? "" |         self.desc = (try? container.decode(String.self, forKey: .desc)) ?? "" | ||||||
|     } |     } | ||||||
| } |  | ||||||
|  |  | ||||||
| extension TraitDTO: Encodable { |  | ||||||
|          |          | ||||||
|     func encode(to encoder: Encoder) throws { |     func encode(to encoder: Encoder) throws { | ||||||
|      |      | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user