final class ShipMapper: JSONMapper {
- private static let ignoreKeys = ["api_gomes", "api_gomes2", "api_broken", "api_powup",
- "api_voicef", "api_afterlv", "api_aftershipid", "api_backs",
- "api_slotnum", "api_stype", "api_name", "api_yomi",
- "api_raig", "api_luck", "api_saku", "api_raim", "api_baku",
- "api_taik", "api_houg", "api_houm", "api_tyku",
- "api_ndock_item", "api_star",
- "api_ndock_time_str", "api_member_id",
- "api_fuel_max", "api_bull_max"]
+ private static let ignoreKeys: Set<String> = ["api_gomes", "api_gomes2", "api_broken", "api_powup",
+ "api_voicef", "api_afterlv", "api_aftershipid", "api_backs",
+ "api_slotnum", "api_stype", "api_name", "api_yomi",
+ "api_raig", "api_luck", "api_saku", "api_raim", "api_baku",
+ "api_taik", "api_houg", "api_houm", "api_tyku",
+ "api_ndock_item", "api_star",
+ "api_ndock_time_str", "api_member_id",
+ "api_fuel_max", "api_bull_max"]
let apiResponse: APIResponse
let configuration: MappingConfiguration<Ship>
required init(_ apiResponse: APIResponse) {
self.apiResponse = apiResponse
- self.configuration = MappingConfiguration(entity: Ship.entity,
+ self.configuration = MappingConfiguration(entity: Ship.self,
dataKeys: ShipMapper.dataKeys(apiResponse),
editorStore: ServerDataStore.oneTimeEditor(),
ignoreKeys: ShipMapper.ignoreKeys)
init(forSlotDepriveUnset apiResponse: APIResponse) {
self.apiResponse = apiResponse
- self.configuration = MappingConfiguration(entity: Ship.entity,
+ self.configuration = MappingConfiguration(entity: Ship.self,
dataKeys: ["api_data", "api_ship_data", "api_unset_ship"],
editorStore: ServerDataStore.oneTimeEditor(),
ignoreKeys: ShipMapper.ignoreKeys)
case .slotDeprive: return ["api_data", "api_ship_data", "api_set_ship"]
- case .ship: return ["api_data"]
+ case .ship, .ship2: return ["api_data"]
- default: return Logger.shared.log("Missing API: \(apiResponse.api)", value: ["api_data"])
+ default:
+
+ Logger.shared.log("Missing API: \(apiResponse.api)")
+
+ return ["api_data"]
}
}
private var registerIds: [Int] = []
private lazy var masterShips: [MasterShip] = {
- return ServerDataStore.default.sortedMasterShipsById()
+ guard let store = configuration.editorStore as? ServerDataStore else {
+
+ return []
+ }
+
+ return store.sortedMasterShipsById()
+
}()
private lazy var slotItems: [SlotItem] = {
- return ServerDataStore.default.sortedSlotItemsById()
+ guard let store = configuration.editorStore as? ServerDataStore else {
+
+ return []
+ }
+
+ return store.sortedSlotItemsById()
}()
- private var isDeleteNotExist: Bool {
+
+ private var needsDeleteUnregisteredShip: Bool {
switch apiResponse.api.endpoint {
- case .ship3, .getShip, .shipDeck,
- .powerup, .slotDeprive:
+
+ case .ship3, .getShip, .shipDeck, .powerup, .slotDeprive:
+
return false
+ case .ship2:
+ // 特殊任務のクリア時にship2がapi_shipid付きでリクエストされ、その艦娘のデータしかない時があるため
+
+ return !apiResponse.parameter["api_shipid"].valid
+
default:
+
return true
+
}
}
// 取得後破棄した装備のデータを削除するため保有IDを保存
if key == "api_id" {
- guard let id = value.int else { return false }
+ guard let id = value.int else {
+
+ return false
+ }
registerIds.append(id)
if key == "api_ship_id" {
- guard let masterId = value.int else { return false }
+ guard let masterId = value.int else {
+
+ return false
+ }
+
+ if ship.ship_id == masterId {
+
+ return true
+ }
setMaster(masterId, to: ship)
if key == "api_exp" {
- guard let exp = value[0].int else { return false }
+ guard let exp = value[0].int else {
+
+ return false
+ }
+
+ if ship.exp == exp {
+
+ return true
+ }
ship.exp = exp
if key == "api_slot_ex" {
- guard let ex = value.int else { return false }
+ guard let ex = value.int else {
+
+ ship.extraItem = nil
+
+ return false
+ }
+
+ if ship.slot_ex == ex {
+
+ return true
+ }
setExtraSlot(ex, to: ship)
- return false
+ ship.slot_ex = ex
+
+ return true
}
return false
func finishOperating() {
- if !isDeleteNotExist { return }
+ if !needsDeleteUnregisteredShip {
+
+ return
+ }
store?.ships(exclude: registerIds).forEach { store?.delete($0) }
}
private func setMaster(_ masterId: Int, to ship: Ship) {
- if ship.ship_id == masterId { return }
-
guard let mShip = masterShips.binarySearch(comparator: { $0.id ==? masterId }),
- let masterShip = store?.object(of: MasterShip.entity, with: mShip.objectID) else {
+ let masterShip = store?.exchange(mShip) else {
+
+ Logger.shared.log("Can not convert to current moc object masterShip")
- return Logger.shared.log("Can not convert to current moc object masterShip")
+ return
}
ship.master_ship = masterShip
private func setSlot(_ slotItems: JSON, to ship: Ship) {
- guard let converSlotItems = slotItems.arrayObject as? [Int] else { return }
- guard let store = store else { return }
+ guard let convertedSlotItems = slotItems.arrayObject as? [Int] else {
+
+ return
+ }
+ guard let store = store else {
+
+ return
+ }
- let newItems: [SlotItem] =
- converSlotItems.flatMap { item in
-
- if item == 0 || item == -1 { return nil }
+ let newItems: [SlotItem] = convertedSlotItems
+ .filter { $0 != 0 && $0 != -1 }
+ .compactMap { item in
guard let found = self.slotItems.binarySearch(comparator: { $0.id ==? item }),
- let slotItem = store.object(of: SlotItem.entity, with: found.objectID) else {
+ let slotItem = store.exchange(found) else {
- let maxV = converSlotItems.last
+ let maxV = convertedSlotItems.last
if maxV != nil, maxV! < item {
Debug.print("item is maybe unregistered, so it is new ship's equipment.")
+
return nil
}
Logger.shared.log("Can not convert to current moc object slotItem")
+
return nil
}
private func setExtraSlot(_ exSlotItem: Int, to ship: Ship) {
- guard exSlotItem != -1, exSlotItem != 0 else { return }
+ guard exSlotItem != -1, exSlotItem != 0 else {
+
+ ship.extraItem = nil
+
+ return
+ }
guard let found = slotItems.binarySearch(comparator: { $0.id ==? exSlotItem }),
- let ex = store?.object(of: SlotItem.entity, with: found.objectID) else {
+ let ex = store?.exchange(found) else {
+
+ Logger.shared.log("Can not convert to current moc object")
- return Logger.shared.log("Can not convert to current moc object")
+ return
}
ship.extraItem = ex