Ios RestKit 0.20:映射复杂的动态嵌套JSON
我对iOS开发和RestKit框架(使用版本0.20.3)非常陌生。单个实体映射的工作方式很有魅力。然而,当谈到动态嵌套JSON的关系映射时,我在过去几天里一直在苦苦挣扎。我尝试映射以下JSON响应:Ios RestKit 0.20:映射复杂的动态嵌套JSON,ios,objective-c,core-data,restkit,restkit-0.20,Ios,Objective C,Core Data,Restkit,Restkit 0.20,我对iOS开发和RestKit框架(使用版本0.20.3)非常陌生。单个实体映射的工作方式很有魅力。然而,当谈到动态嵌套JSON的关系映射时,我在过去几天里一直在苦苦挣扎。我尝试映射以下JSON响应: "chargerstations": [ { "csmd": { "id": 1190, "name": "Tammasaarenkatu 7", "Street": "Tammasaarenkatu", "H
"chargerstations": [
{
"csmd": {
"id": 1190,
"name": "Tammasaarenkatu 7",
"Street": "Tammasaarenkatu",
"House_number": "7",
"Zipcode": "00180",
"City": "Ruoholahti",
"Municipality_ID": "091",
"Municipality": "Helsinki",
"County_ID": "01",
"County": "Uusimaa",
"Description_of_location": "",
"Owned_by": "Helen",
"Number_charging_points": 1,
"Position": "(60.16172,24.90679)",
"Image": "Kommer",
"Available_charging_points": 1,
"User_comment": "",
"Contact_info": "",
"Created": "2012-03-30 11:40:48",
"Updated": "2013-04-16 11:52:47",
"Station_status": 1,
"Land_code": "FIN",
"International_id": "FIN_01190"
},
"attr": {
"st": {
"2": {
"attrtypeid": "2",
"attrname": "Availability",
"attrvalid": "1",
"trans": "Public",
"attrval": ""
},
"3": {
"attrtypeid": "3",
"attrname": "Location",
"attrvalid": "1",
"trans": "Street",
"attrval": ""
},
"6": {
"attrtypeid": "6",
"attrname": "Time limit",
"attrvalid": "2",
"trans": "No",
"attrval": ""
},
"7": {
"attrtypeid": "7",
"attrname": "Parking fee",
"attrvalid": "2",
"trans": "No",
"attrval": false
},
"21": {
"attrtypeid": "21",
"attrname": "Real-time information",
"attrvalid": "2",
"trans": "No",
"attrval": ""
},
"22": {
"attrtypeid": "22",
"attrname": "Public funding",
"attrvalid": "4",
"trans": "None",
"attrval": ""
},
"24": {
"attrtypeid": "24",
"attrname": "Open 24h",
"attrvalid": "1",
"trans": "Yes",
"attrval": "1"
}
},
"conn": {
"1": {
"1": {
"attrtypeid": "1",
"attrname": "Accessibility",
"attrvalid": "6",
"trans": "Cellular phone",
"attrval": ""
},
"4": {
"attrtypeid": "4",
"attrname": "Connector",
"attrvalid": "32",
"trans": "Mennekes-type 2 (IEC 62196-2) \n",
"attrval": ""
},
"5": {
"attrtypeid": "5",
"attrname": "Charging capacity",
"attrvalid": "11",
"trans": "400V 3-phase max 32A",
"attrval": ""
},
"17": {
"attrtypeid": "17",
"attrname": "Vehicle type",
"attrvalid": "1",
"trans": "All vehicles",
"attrval": ""
},
"18": {
"attrtypeid": "18",
"attrname": "Reservable",
"attrvalid": "2",
"trans": "No",
"attrval": ""
},
"20": {
"attrtypeid": "20",
"attrname": "Charge mode",
"attrvalid": "3",
"trans": "Mode 3",
"attrval": ""
},
"25": {
"attrtypeid": "25",
"attrname": "Fixed cable",
"attrvalid": "2",
"trans": "No",
"attrval": ""
}
}
"2": {
"1": {same structure as above
}
}
"<conn no. x>": {
"1": {same structure as above
}
}
}
}
}
]
“收费站”:[
{
“csmd”:{
“id”:1190,
“名称”:“Tammasaarenkatu 7号”,
“街道”:“Tammasaarenkatu”,
“房屋编号”:“7”,
“Zipcode”:“00180”,
“城市”:“若霍拉赫蒂”,
“市政ID”:“091”,
“自治市”:“赫尔辛基”,
“县ID”:“01”,
“县”:“Uusimaa”,
“位置的描述”:“,
“所有人”:“海伦”,
“充电点数”:1,
“位置”:“(60.16172,24.90679)”,
“图像”:“Kommer”,
“可用充电点数”:1,
“用户注释”:“,
“联系人信息”:“,
“已创建”:“2012-03-30 11:40:48”,
“更新”:“2013-04-16 11:52:47”,
“车站状态”:1,
“土地代码”:“FIN”,
“国际id”:“FIN 01190”
},
“属性”:{
“st”:{
"2": {
“attrtypeid”:“2”,
“属性名称”:“可用性”,
“attrvalid”:“1”,
“trans”:“Public”,
“attrval”:”
},
"3": {
“attrtypeid”:“3”,
“属性名称”:“位置”,
“attrvalid”:“1”,
“trans”:“Street”,
“attrval”:”
},
"6": {
“attrtypeid”:“6”,
“attrname”:“时限”,
“attrvalid”:“2”,
“trans”:“否”,
“attrval”:”
},
"7": {
“attrtypeid”:“7”,
“名称”:“停车费”,
“attrvalid”:“2”,
“trans”:“否”,
“attrval”:false
},
"21": {
“attrtypeid”:“21”,
“属性名称”:“实时信息”,
“attrvalid”:“2”,
“trans”:“否”,
“attrval”:”
},
"22": {
“attrtypeid”:“22”,
“名称”:“公共资金”,
“attrvalid”:“4”,
“trans”:“无”,
“attrval”:”
},
"24": {
“attrtypeid”:“24”,
“属性名称”:“24小时开放”,
“attrvalid”:“1”,
“trans”:“是”,
“attrval”:“1”
}
},
“康涅狄格州”:{
"1": {
"1": {
“attrtypeid”:“1”,
“属性名”:“可访问性”,
“有效”:“6”,
“trans”:“手机”,
“attrval”:”
},
"4": {
“attrtypeid”:“4”,
“属性名称”:“连接器”,
“attrvalid”:“32”,
“trans”:“Mennekes类型2(IEC 62196-2)\n”,
“attrval”:”
},
"5": {
“attrtypeid”:“5”,
“属性名称”:“充电容量”,
“attrvalid”:“11”,
“trans”:“400V三相最大32A”,
“attrval”:”
},
"17": {
“attrtypeid”:“17”,
“属性名称”:“车辆类型”,
“attrvalid”:“1”,
“trans”:“所有车辆”,
“attrval”:”
},
"18": {
“attrtypeid”:“18”,
“attrname”:“可预订”,
“attrvalid”:“2”,
“trans”:“否”,
“attrval”:”
},
"20": {
“attrtypeid”:“20”,
“属性名称”:“充电模式”,
“有效”:“3”,
“trans”:“模式3”,
“attrval”:”
},
"25": {
“attrtypeid”:“25”,
“attrname”:“固定电缆”,
“attrvalid”:“2”,
“trans”:“否”,
“attrval”:”
}
}
"2": {
“1”:{与上述结构相同
}
}
"": {
“1”:{与上述结构相同
}
}
}
}
}
]
我创建了一个包含2个实体的核心数据模型;“ChargingStation”包含来自“csmd”和“attr.st”字典的数据,“Connector”包含来自JSON(attr.conn)动态嵌套部分的数据。一个充电站可能有多个连接器,但一个连接器只能属于一个充电站。因此,我定义了从“ChargingStation”到“Connector”的多对多关系,与“Connector”实体的关系相反
我的模型是使用mogenerator生成的。以下是我迄今为止关于映射本身的代码(在AppDelegate.m中):
RKEntityMapping*chargingStationMapping=[RKEntityMappingForEntityForName:@“ChargingStation”
inManagedObjectStore:managedObjectStore];
[chargingStationMapping addAttributeMappingsFromDictionary:@{
@“属性st.2.trans”:@“可用性类型”,
@“csmd.City”:@“City”,
@“csmd.位置”:@“坐标”,
@“csmd.房屋编号”:@“房屋编号”,
@“csmd.id”:@“stationID”,
@“csmd.International_id”:“internationalID”,
@“csmd.位置描述”:@“位置描述”,
@“csmd.Image”:@“locationImage”,
RKEntityMapping *chargingStationMapping = [RKEntityMapping mappingForEntityForName:@"ChargingStation"
inManagedObjectStore:managedObjectStore];
[chargingStationMapping addAttributeMappingsFromDictionary:@{
@"attr.st.2.trans" : @"availabilityType",
@"csmd.City" : @"city",
@"csmd.Position" : @"coordinates",
@"csmd.House_number" : @"houseNumber",
@"csmd.id" : @"stationID",
@"csmd.International_id" : @"internationalID",
@"csmd.Description_of_location" : @"locationDescription",
@"csmd.Image" : @"locationImage",
@"attr.st.3.trans" : @"locationName",
@"csmd.name" : @"name",
@"csmd.Available_charging_points" : @"numChargingPoints",
@"attr.st.24.trans" : @"openingHours",
@"attr.st.7.trans" : @"parkingFee",
@"attr.st.22.trans" : @"publicFunding",
@"attr.st.21.trans" : @"realtimeInfo",
@"csmd.Street" : @"street",
@"attr.st.6.trans" : @"timeLimit",
@"csmd.Zipcode" : @"zipCode"
}];
chargingStationMapping.identificationAttributes = @[@"stationID"];
RKDynamicMapping *dynamicConnectorMapping = [[RKDynamicMapping alloc] init];
[dynamicConnectorMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {
RKEntityMapping *connectorMapping = [RKEntityMapping mappingForEntityForName:@"Connector"
inManagedObjectStore:managedObjectStore];
NSDictionary *connectors = [representation valueForKeyPath:@"attr.conn"];
for (NSString *attr in connectors) {
NSDictionary *connector = [connectors objectForKey:attr];
[connector enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) {
NSLog(@"Attr from outer connector object: %@", attr);
if ([key isEqualToString:@"1"]) {
[chargingStationMapping addAttributeMappingsFromDictionary:@{
[NSString stringWithFormat:@"attr.conn.%@.%@.trans", attr, key]: @"accessibility"
}];
} else if ([key isEqualToString:@"4"]) {
[chargingStationMapping addAttributeMappingsFromDictionary:@{
[NSString stringWithFormat:@"attr.conn.%@.%@.trans", attr, key]: @"connector"
}];
} else if ([key isEqualToString:@"5"]) {
[chargingStationMapping addAttributeMappingsFromDictionary:@{
[NSString stringWithFormat:@"attr.conn.%@.%@.trans", attr, key]: @"chargingCapacity"
}];
} else if ([key isEqualToString:@"17"]) {
[chargingStationMapping addAttributeMappingsFromDictionary:@{
[NSString stringWithFormat:@"attr.conn.%@.%@.trans", attr, key]: @"vehicleType"
}];
} else if ([key isEqualToString:@"18"]) {
[chargingStationMapping addAttributeMappingsFromDictionary:@{
[NSString stringWithFormat:@"attr.conn.%@.%@.trans", attr, key]: @"reservable"
}];
} else if ([key isEqualToString:@"20"]) {
[chargingStationMapping addAttributeMappingsFromDictionary:@{
[NSString stringWithFormat:@"attr.conn.%@.%@.trans", attr, key]: @"chargeMode"
}];
} else if ([key isEqualToString:@"23"]) {
[chargingStationMapping addAttributeMappingsFromDictionary:@{
[NSString stringWithFormat:@"attr.conn.%@.%@.trans", attr, key]: @"manufacturer"
}];
} else if ([key isEqualToString:@"25"]) {
[chargingStationMapping addAttributeMappingsFromDictionary:@{
[NSString stringWithFormat:@"attr.conn.%@.%@.trans", attr, key]: @"fixedCable"
}];
}
}];
}
connectorMapping.identificationAttributes = @[@"id"];
[connectorMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"ChargingStation"
toKeyPath:@"chargingstation"
withMapping:chargingStationMapping]];
return connectorMapping;
}];
RKResponseDescriptor *connectorDescription = [RKResponseDescriptor responseDescriptorWithMapping:dynamicConnectorMapping method:RKRequestMethodGET pathPattern:nil keyPath:@"chargerstations" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
RKResponseDescriptor *chargingStationDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:chargingStationMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"chargerstations.attr.conn" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:chargingStationDescriptor];
[objectManager addResponseDescriptor:connectorDescription];
[objectManager getObjectsAtPath:<URL_request>"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
ChargingStation *cstation = [mappingResult firstObject];
NSLog(@"House number: %@", cstation.houseNumber);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {}];
Assertion failure in -[RKEntityMapping addPropertyMapping:], /<my_project_directory>/Pods/RestKit/Code/ObjectMapping/RKObjectMapping.m:237
2014-04-21 18:30:55.200 ChargeIt[844:530b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unable to add mapping for keyPath connector, one already exists...'
connectors = "<relationship fault: 0x9fb5fe0 'connectors'>";
RKEntityMapping *chargingStationMapping = [RKEntityMapping mappingForEntityForName:@"ChargingStation"
inManagedObjectStore:managedObjectStore];
[chargingStationMapping addAttributeMappingsFromDictionary:@{
@"attr.st.2.trans" : @"availabilityType",
@"chargerstations.csmd.City" : @"city",
@"csmd.Position" : @"coordinates",
@"csmd.House_number" : @"houseNumber",
@"csmd.id" : @"stationID",
@"csmd.International_id" : @"internationalID",
@"csmd.Description_of_location" : @"locationDescription",
@"csmd.Image" : @"locationImage",
@"attr.st.3.trans" : @"locationName",
@"csmd.name" : @"name",
@"csmd.Available_charging_points" : @"numChargingPoints",
@"attr.st.24.trans" : @"openingHours",
@"attr.st.7.trans" : @"parkingFee",
@"attr.st.22.trans" : @"publicFunding",
@"attr.st.21.trans" : @"realtimeInfo",
@"csmd.Street" : @"street",
@"attr.st.6.trans" : @"timeLimit",
@"csmd.Zipcode" : @"zipCode"
}];
chargingStationMapping.identificationAttributes = @[@"stationID"];
RKEntityMapping *connectorMapping = [RKEntityMapping mappingForEntityForName:@"Connector"
inManagedObjectStore:managedObjectStore];
connectorMapping.forceCollectionMapping = YES;
[connectorMapping addAttributeMappingFromKeyOfRepresentationToAttribute:@"connectorID"];
[connectorMapping addAttributeMappingsFromDictionary:@{
@"(connectorID).1.trans": @"accessibility",
@"(connectorID).4.trans": @"connector",
@"(connectorID).5.trans": @"chargingCapacity",
@"(connectorID).17.trans": @"vehicleType",
@"(connectorID).18.trans": @"reservable",
@"(connectorID).20.trans": @"chargeMode",
@"(connectorID).23.trans": @"manufacturer",
@"(connectorID).25.trans": @"fixedCable"
}];
[chargingStationMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"attr.conn"
toKeyPath:@"connectors"
withMapping:connectorMapping]];
RKResponseDescriptor *chargingStationDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:chargingStationMapping
method:RKRequestMethodAny
pathPattern:nil
keyPath:@"chargerstations"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:chargingStationDescriptor];
[objectManager getObjectsAtPath:@"datadump.php?apikey=<API_KEY>&file=false&format=json&countrycode=FIN"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
ChargingStation *cstation = [mappingResult firstObject];
NSLog(@"Connectors: %@", cstation);
NSLog(@"Connector info: %i", cstation.connectorsSet.count);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {}];
to object <ChargingStation: 0x9c84cf0> (entity: ChargingStation; id: 0x151c4f00 <x-coredata://77C8299D-FDDB-4810-8D22-C13538858DA1/ChargingStation/p18> ; data: {
availabilityType = Public;
city = nil;
connectors = "<relationship fault: 0x9c84270 'connectors'>";
coordinates = "(60.16172,24.90679)";
houseNumber = 7;
internationalID = "FIN_01190";
locationDescription = "";
locationImage = Kommer;
locationName = Street;
name = "Tammasaarenkatu 7";
numChargingPoints = 1;
openingHours = Yes;
parkingFee = No;
paymentMethods = nil;
publicFunding = None;
realtimeInfo = No;
stationID = 1190;
street = Tammasaarenkatu;
timeLimit = No;
zipCode = 00180;
}) with object mapping (null)
2014-04-30 19:35:06.949 ChargeIt[6131:5613] D restkit.object_mapping:RKMappingOperation.m:766 Collection mapping forced for NSDictionary, mapping each key/value independently...
2014-04-30 19:35:06.950 ChargeIt[6131:5613] D restkit.object_mapping:RKMappingOperation.m:640 Mapping one to many relationship value at keyPath 'attr.conn' to 'connectors'
2014-04-30 19:35:06.951 ChargeIt[6131:3d13] D restkit.object_mapping:RKPropertyInspector.m:131 Cached property inspection for Class 'Connector': {
accessibility = {
isPrimitive = 0;
keyValueCodingClass = NSString;
name = accessibility;
};
...
};
vehicleType = {
isPrimitive = 0;
keyValueCodingClass = NSString;
name = vehicleType;
};
}
2014-04-30 19:35:06.984 ChargeIt[6131:5613] I restkit.core_data:RKInMemoryManagedObjectCache.m:94 Caching instances of Entity 'Connector' by attributes 'connectorID'
2014-04-30 19:35:07.042 ChargeIt[6131:5613] T restkit.object_mapping:RKMappingOperation.m:541 Performing nested object mapping using mapping <RKRelationshipMapping: 0x9e4ce70 attr.conn => connectors> for data: {
1 = {
1 = {
attrname = Accessibility;
attrtypeid = 1;
attrval = "";
attrvalid = 6;
trans = "Cellular phone";
};
17 = {
attrname = "Vehicle type";
attrtypeid = 17;
attrval = "";
attrvalid = 1;
trans = "All vehicles";
};
18 = {
attrname = Reservable;
attrtypeid = 18;
attrval = "";
attrvalid = 2;
trans = No;
};
20 = {
attrname = "Charge mode";
attrtypeid = 20;
attrval = "";
attrvalid = 3;
trans = "Mode 3";
};
25 = {
attrname = "Fixed cable";
attrtypeid = 25;
attrval = "";
attrvalid = 2;
trans = No;
};
4 = {
attrname = Connector;
attrtypeid = 4;
attrval = "";
attrvalid = 32;
trans = "Mennekes-type 2 (IEC 62196-2) \n";
};
5 = {
attrname = "Charging capacity";
attrtypeid = 5;
attrval = "";
attrvalid = 11;
trans = "400V 3-phase max 32A";
};
};
}
2014-04-30 19:35:07.043 ChargeIt[6131:5613] D restkit.object_mapping:RKMappingOperation.m:859 Starting mapping operation...
2014-04-30 19:35:07.044 ChargeIt[6131:5613] T restkit.object_mapping:RKMappingOperation.m:860 Performing mapping operation: <RKMappingOperation 0x9cdcdd0> for 'Connector' object. Mapping values from object {
1 = {
1 = {
attrname = Accessibility;
attrtypeid = 1;
attrval = "";
attrvalid = 6;
trans = "Cellular phone";
};
17 = {
attrname = "Vehicle type";
attrtypeid = 17;
attrval = "";
attrvalid = 1;
trans = "All vehicles";
};
18 = {
attrname = Reservable;
attrtypeid = 18;
attrval = "";
attrvalid = 2;
trans = No;
};
20 = {
attrname = "Charge mode";
attrtypeid = 20;
attrval = "";
attrvalid = 3;
trans = "Mode 3";
};
25 = {
attrname = "Fixed cable";
attrtypeid = 25;
attrval = "";
attrvalid = 2;
trans = No;
};
4 = {
attrname = Connector;
attrtypeid = 4;
attrval = "";
attrvalid = 32;
trans = "Mennekes-type 2 (IEC 62196-2) \n";
};
5 = {
attrname = "Charging capacity";
attrtypeid = 5;
attrval = "";
attrvalid = 11;
trans = "400V 3-phase max 32A";
};
};
} to object <Connector: 0x1965b460> (entity: Connector; id: 0x9e0a940 <x-coredata://77C8299D-FDDB-4810-8D22-C13538858DA1/Connector/p35> ; data: {
accessibility = Other;
chargeMode = "Mode 3";
chargingCapacity = "400V 3-phase max 32A";
chargingstation = "0x9c3f620 <x-coredata://77C8299D-FDDB-4810-8D22-C13538858DA1/ChargingStation/p35>";
connector = "Type 2 + Schuko CEE 7/4";
connectorID = 1;
fixedCable = No;
manufacturer = Manufacturer;
reservable = No;
vehicleType = "All vehicles";
}) with object mapping (null)
2014-04-30 19:35:07.047 ChargeIt[6131:5613] D restkit.object_mapping:RKMappingOperation.m:821 Found nested mapping definition to attribute 'connectorID'
2014-04-30 19:35:07.048 ChargeIt[6131:5613] D restkit.object_mapping:RKMappingOperation.m:824 Found nesting value of '1' for attribute 'connectorID'
2014-04-30 19:35:07.048 ChargeIt[6131:5613] T restkit.object_mapping:RKMappingOperation.m:438 Found transformable value at keyPath '<RK_NESTING_ATTRIBUTE>'. Transforming from class '__NSCFString' to 'NSNumber'
2014-04-30 19:35:07.048 ChargeIt[6131:5613] T restkit.object_mapping:RKMappingOperation.m:453 Mapping attribute value keyPath '<RK_NESTING_ATTRIBUTE>' to 'connectorID'
2014-04-30 19:35:07.049 ChargeIt[6131:5613] T restkit.object_mapping:RKMappingOperation.m:484 Skipped mapping of attribute value from keyPath '<RK_NESTING_ATTRIBUTE> to keyPath 'connectorID' -- value is unchanged (1)
2014-04-30 19:35:07.049 ChargeIt[6131:5613] T restkit.object_mapping:RKMappingOperation.m:507 Skipping attribute mapping for special keyPath '<RK_NESTING_ATTRIBUTE>'
2014-04-30 19:35:07.050 ChargeIt[6131:5613] T restkit.object_mapping:RKMappingOperation.m:438 Found transformable value at keyPath '1.4.trans'. Transforming from class '__NSCFString' to 'NSString'
2014-04-30 19:35:07.064 ChargeIt[6131:5613] T restkit.object_mapping:RKMappingOperation.m:453 Mapping attribute value keyPath '1.4.trans' to 'connector'
....
2014-04-30 19:35:07.118 ChargeIt[6131:5613] T restkit.object_mapping:RKMappingOperation.m:622 Mapped `NSSet` relationship object from keyPath 'attr.conn' to 'connectors'. Value: {(
<Connector: 0x1965b460> (entity: Connector; id: 0x9e0a940 <x-coredata://77C8299D-FDDB-4810-8D22-C13538858DA1/Connector/p35> ; data: {
accessibility = "Cellular phone";
chargeMode = "Mode 3";
chargingCapacity = "400V 3-phase max 32A";
chargingstation = "0x9c3f620 <x-coredata://77C8299D-FDDB-4810-8D22-C13538858DA1/ChargingStation/p35>";
connector = "Mennekes-type 2 (IEC 62196-2) \n";
connectorID = 1;
fixedCable = No;
manufacturer = Manufacturer;
reservable = No;
vehicleType = "All vehicles";
})
)}