我有一个提供数据的外部api,我需要对其进行解码并将其分配给视图中的标签。
我在collectionView中使用以下内容,所以不要介意collectionView.tag
和indexPath.row
我也在使用SwiftyJson
解析json值.string
提供和可选值
let value = servicesResponse["data"][collectionView.tag]["subcategories"][indexPath.row]["name"].string
现在,当我尝试将此值分配给标签时
cell.serviceName.text = value
我收到一个错误:
'NSInvalidArgumentException', reason: '*** -[NSPlaceholderString initWithString:]: nil argument'
我在赋值时必须将值放在这样的东西内:
`"\(value)"`
这可以正常工作,但是在值附近有Optional
文本。
我也试图:
cell.serviceName.text = value!
给出相同的错误.stringValue
,而不是.string
,它给出了非可选的值,给出了相同的错误-使用.rawString
而不是.string
会出现相同的错误if let value = servicesResponse["data"][collectionView.tag]
["subcategories"][indexPath.row]["name"].string {
cell.serviceName.text = value
}
相同错误
cell.serviceName.text = value ?? "default"
同样的错误我只是试图像这样检查所有响应:
if servicesResponse["data"] != JSON.null{
if servicesResponse["data"][collectionView.tag] != JSON.null{
if servicesResponse["data"][collectionView.tag]["subcategories"] != JSON.null{
if servicesResponse["data"][collectionView.tag]["subcategories"][indexPath.row] != JSON.null{
if servicesResponse["data"][collectionView.tag]["subcategories"][indexPath.row]["name"] != JSON.null{
print("ALL PASS=========================")
}
}
}
}
}
和所有通行证
原始JSON:
{
"statusCode": 200,
"message": "Success",
"data": [
{
"_id": "someid",
"isActive": true,
"subcategories": [
{
"_id": "id",
"photo": "image/url/30973327066756228460065.png",
"services": [
{
"_id": "id",
"properties": [
{
"_id": "id",
"isMultiSelect": false,
"responses": [
"1",
"2",
"3",
"4",
"5"
],
"other_name": "የክፍሎች ቁጥር",
"name": "Number of rooms"
}
],
"other_name": "ጽዳት",
"name": "Cleaning"
}
],
"other_name": "ጽዳት",
"name": "Cleaning",
"other_subcategory_label": "ጽዳት",
"subcategory_label": "Cleaning"
}
],
"name": "Home Cleaning",
"__v": 0,
"other_name": "የቤት ጽዳት"
},
{
"_id": "id",
"isActive": true,
"subcategories": [
{
"_id": "id",
"photo": "image/url/30973327066756228460065.png",
"services": [
{
"_id": "id",
"properties": [
{
"_id": "id",
"isMultiSelect": false,
"responses": [
"Tap",
"Sink"
],
"name": "Is it the tap or Sink?"
}
],
"name": "Taps and Sinks"
}
],
"name": "Taps and Sinks",
"subcategory_label": "Taps and Sinks"
},
{
"_id": "id",
"photo": "image/url/30973327066756228460065.png",
"services": [
{
"_id": "id",
"properties": [
{
"_id": "id",
"isMultiSelect": false,
"responses": [
"Yes",
"No"
],
"name": "Can you send a photo?"
}
],
"name": "Drains"
}
],
"name": "Drains",
"subcategory_label": "Drains"
}
],
"name": "Plumbing",
"__v": 0
},
{
"_id": "id",
"isActive": true,
"subcategories": [
{
"_id": "id",
"photo": "image/url/30973327066756228460065.png",
"services": [
{
"_id": "id",
"properties": [
{
"_id": "id",
"isMultiSelect": false,
"responses": [
"Yes",
"No"
],
"name": "Do you have power?"
}
],
"name": "Electrical Faults"
}
],
"name": "Electrical Faults",
"subcategory_label": "Electrical Faults"
},
{
"_id": "id",
"photo": "image/url/30973327066756228460065.png",
"services": [
{
"_id": "id",
"properties": [
{
"_id": "id",
"isMultiSelect": false,
"responses": [
"Yes",
"No"
],
"name": "Can you bring the appliance to a repair shop"
}
],
"name": "Electrical Appliances"
}
],
"name": "Electrical Appliances",
"subcategory_label": "Electrical Appliances"
}
],
"name": "Electrical",
"__v": 0
},
{
"_id": "id",
"isActive": true,
"subcategories": [
{
"_id": "id",
"photo": "image/url/30973327066756228460065.png",
"services": [
],
"other_name": "Painting",
"name": "Painting",
"other_subcategory_label": "Painting",
"subcategory_label": "Painting"
}
],
"other_name": "Finishing",
"name": "Finishing",
"__v": 0
}
]
}
我想知道是否有一种方法可以删除文本Optional
,而该值仍然是可选的,或者是否有人知道此错误的含义以及发生的原因。
仅在iOS13
上发生错误。在早期版本上可以正常工作
谢谢。
value
变量是一个可选字符串,这就是为什么在打印时显示Optional()
的原因。
要打开可选的包装,您可以执行以下操作:
if let unwrappedValue = value {
cell.serviceName.text = unwrappedValue
}
或者,如果您愿意,也可以使用nil合并运算符在一行中完成:
cell.serviceName.text = value ?? "Text in case of nil"
这是因为您的值是可选的。
尝试这种方式
if let value = servicesResponse["data"][collectionView.tag]["subcategories"][indexPath.row]["name"] {
cell.serviceName.text = value.stringValue
}
错误显示使用nil参数初始化字符串,因此json数据或解码方式不太正确。
为什么不分阶段而不是一个班轮地展开。当您处理未知错误时,最好将流程分解成小块,然后逐一检查。当您发现问题出在哪里时,您可以随时应用所学的知识,回到原来的状态。
这是我想出(并经过测试)来说明在JSON逐步解码过程中进行调试的一种方法。
给出原始的json字符串:
let rawString = """
{"statusCode":200,"message":"Success","data":[{"_id":"someid","isActive":true,"subcategories":[{"_id":"id","photo":"image/url/30973327066756228460065.png","services":[{"_id":"id","properties":[{"_id":"id","isMultiSelect":false,"responses":["1","2","3","4","5"],"other_name":"የክፍሎች ቁጥር","name":"Number of rooms"}],"other_name":"ጽዳት","name":"Cleaning"}],"other_name":"ጽዳት","name":"Cleaning","other_subcategory_label":"ጽዳት","subcategory_label":"Cleaning"}],"name":"Home Cleaning","__v":0,"other_name":"የቤት ጽዳት"}]}
"""
我们可以逐渐解码,验证并在最后解开名称值。
let parsedJson = JSON.init(parseJSON: rawString)
let verifiedDataJson = parsedJson["data"]
guard verifiedDataJson != JSON.null else {
return
}
let verifiedCollectionViewTagJson = verifiedDataJson[0]
guard verifiedCollectionViewTagJson != JSON.null else {
return
}
let verifiedSubCategoriesJson = verifiedCollectionViewTagJson["subcategories"]
guard verifiedSubCategoriesJson != JSON.null else {
return
}
let verifiedIndexPathRowJson = verifiedSubCategoriesJson[0]
guard verifiedIndexPathRowJson != JSON.null else {
return
}
guard let unwrappedNameValue = verifiedIndexPathRowJson["name"].string as String? else {
return
}