我正在尝试NSDictionary
的arrayobject中的第二级数组,但是它返回nil
我首先定义了NSDictionary
,然后访问了数组的第一级,直到现在一切都很好为止。
let dict = JSON(responseObject as! NSDictionary)
let arrayData = dict["data"].arrayObject! as NSArray
print("arrayData", arrayData)
打印arrayData
时,我得到以下回报
data = (
{
categories = (
{
categories = "<null>";
"category_id" = 333;
image = "https://www.example.com/images/1.jpg";
name = "Sub Category One";
"parent_id" = 1000;
},
{
categories = "<null>";
"category_id" = 444;
image = "https://www.example.com/images/2.jpg";
name = "Sub Category Two";
"parent_id" = 1000;
},
{
categories = "<null>";
"category_id" = 555;
image = "https://www.example.com/images/3.jpg";
name = "Sub Category Three";
"parent_id" = 1000;
}
);//end of categories array
"category_id" = 1000;
image = "https://www.examples.com/images/category.jpg";
name = "Parent Category";
"parent_id" = 0;
},
)
现在我正尝试从上面返回的数组访问并打印categories
所以我尝试了以下操作:
if dict["categories"].arrayObject != nil{
let arrayData2 = dict["categories"].arrayObject! as NSArray
print("arrayData2", arrayData2)
}
我也尝试过
if dict["data"]["categories"].arrayObject != nil{
let arrayData2 = dict["data"]["categories"].arrayObject! as NSArray
print("arrayData2", arrayData2)
}
两种方式都可以得到 nil 值,而应该获得真实值。
已编辑:在ViewController和dataModel结构中添加了API调用
View Controller中的callingHTTPAPI函数
func callingHttppApi(){
DispatchQueue.main.async{
NetworkManager.sharedInstance.showLoader()
let sessionId = self.defaults.object(forKey:"token");
self.categoriesTableView.isUserInteractionEnabled = false
var requstParams = [String:Any]();
requstParams["token"] = sessionId
NetworkManager.sharedInstance.callingHttpRequest(params:requstParams, apiname:"api/cat", cuurentView: self){success,responseObject in
if success == 1{
let dict = responseObject as! NSDictionary;
if dict.object(forKey: "fault") != nil{
let fault = dict.object(forKey: "fault") as! Bool;
if fault == true{
self.loginRequest()
}
}else{
NetworkManager.sharedInstance.dismissLoader()
self.view.isUserInteractionEnabled = true
self.categoriesTableView.isUserInteractionEnabled = true
let dict = JSON(responseObject as! NSDictionary)
let arrayData = dict["data"].arrayObject! as NSArray
if dict["categories"].arrayObject != nil{
let arrayData2 = dict["categories"].arrayObject! as NSArray
print("arrayData2", arrayData2)
}
print("arrayData", arrayData)
if dict["error"].intValue == 1{
NetworkManager.sharedInstance.showErrorMessageWithBack(view: self, message: NetworkManager.sharedInstance.language(key: "error"))
}else{
self.categoriesCollModel = CategoriesViewModel(data:JSON(responseObject as! NSDictionary))
dump (self.categoriesCollModel)
}
}
}else if success == 2{
NetworkManager.sharedInstance.dismissLoader()
self.callingHttppApi()
}
}
}
}
用于投射值的dataModel结构
//
// CategoriesViewModel.swift
//
import Foundation
class Categories: NSObject{
var id:String = ""
var name:String = ""
var image:String = ""
init(data:JSON){
self.id = data["category_id"].stringValue
self.name = data["name"].stringValue
self.image = data["image"].stringValue
}
}
class SubCategories:NSObject{
var pid:String = ""
var id:String = ""
var name:String = ""
var image:String = ""
init(data:JSON) {
self.pid = data["parent_id"].stringValue
self.id = data["category_id"].stringValue
self.name = data["name"].stringValue
self.image = data["image"].stringValue
}
}
struct Categories_Data{
var id:String = ""
var categoriesArray = [SubCategories]()
init(data:JSON) {
self.id = data["category_id"].stringValue
if let arrayData = data["data"]["categories"].arrayObject {
categoriesArray = arrayData.map({(value) -> SubCategories in
return SubCategories(data:JSON(value))
})
}
}
}
class CategoriesViewModel:NSObject{
var categoryModel = [Categories]()
var subCategories = [SubCategories]()
var categories_Data = [Categories_Data]()
init(data:JSON) {
let arrayData = data["data"].arrayObject! as NSArray
categoryModel = arrayData.map({(value) -> Categories in
return Categories(data:JSON(value))
})
if data["data"]["categories"].arrayObject != nil{
let arrayData2 = data["data"]["categories"].arrayObject! as NSArray
categories_Data = arrayData2.map({(value) -> Categories_Data in
return Categories_Data(data:JSON(value))
})
}
//categoryModel = Categories(data:data)
}
var getCategories:Array<Categories>{
return categoryModel
}
var getSubCategories:Array<SubCategories>{
return subCategories
}
}
答案 0 :(得分:3)
我强烈建议放下SwiftyJSON
并使用Decodable
。
CategoriesViewModel
可以简化为
struct Root: Decodable {
let data : [Category]
}
struct Category: Decodable {
let categories : [Category]?
let categoryId : Int
let image : URL
let name : String
let parentId : Int
}
您需要从网络请求中获取原始数据(在下面的名为data
的代码中),然后您可以简单地将数据解码为结构并使用点符号获取值。
我添加了一个辅助函数,可以递归地打印嵌套的类别
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Root.self, from: data)
printCategories(result.data)
} catch { print(error) }
func printCategories(_ categories : [Category]) {
for item in categories {
if let subCategories = item.categories {
printCategories(subCategories)
}
print(item.name, item.categoryId)
}
}
答案 1 :(得分:0)
您以错误的方式检索对象。始终使用check nil值检索对象或值...
检查以下代码以检索您的类别。
let dict = JSON(responseObject as! NSDictionary)
if let data = dict["data"] as? Array<Any>
{
if let categoryArray = data["categories"] as? Array<Dictionary<String,Any>>
{
if categoryArray.count > 0
{
print(categoryArray)
}
}
}
答案 2 :(得分:0)
看起来很复杂,但是非常简单,只需遵循层次结构
例如,说您要访问“数据->类别->名称”,因为您可以在回复中像这样
这是您的主要词典,里面包含了所有内容。
if let dict = responceObject as? NSDictionary {
// now lets say you want go to your categories which is array of dictionaries
if let arrDict = dict["categories"] as? NSArray {
print("arrDict")
// Now you can go anywhere in that array of dictionaries
// For example you want to get name you can do like this
for obj in arrDict {
if let name = obj["name"] as? String {
print(name)
}
}
}
}
我要在此处添加编辑部分
// In your webcall lets say you receive a JSON(i am naming it as "json") object with type Any
if let jsonObj = json as? [String: Any], let mainDict = jsonObj["data"] as? [[String: Any]] {
for arr in mainDict {
if let arrDict = arr["categories"] as? [[String: Any]] {
print(arrDict)
// Now you can dig that dict which is array of dictionaries
for obj in arrDict {
if let name = obj["name"] as? String {
print(name)
}
if let id = obj["id"] as? Int { // Int or whatever it is
print(id)
}
}
}
}
}
希望这会起作用。
答案 3 :(得分:0)
初始化模型对象时,还应该使用guard
来验证值:
init(data: JSON) {
guard
let id = data["category_id"] as? Int,
let name = data["name"] as? String,
let image = data["image"] as? String
else {
return
}
self.id = id
self.name = name
self.image = image
}
请注意,id是整数值,而不是字符串,因此您应该更改模型。
还可以检出Codable。
答案 4 :(得分:0)
首先了解print("arrayData", arrayData)
的响应。它是array
中的Dictionaries
。
添加时:
let arrayData = dict["data"].arrayObject! as NSArray
您正在将数据保存在dictionary
中的数组中。
现在要获取类别,您必须使用arrayData
:
let firstDict = arrayData[0] as! [String:Any]
let arrayData2 = firstDict["categories"] as! [[String:Any]]
print("arrayData2", arrayData2)
我添加了此代码以显示一个数据。
有关更多数据,您可以用于循环:
for dictData in arrayData {
let arrayData2 = dictData["categories"] as! [[String:Any]]
print("arrayData2", arrayData2)
}
并使用此循环可以管理或保存相关数据。
还有一件别忘了添加零处理部分。
快速处理时的另一件事不要使用NSArray
或NSDictionary
。
尝试使用Codable
。互联网上有很多示例,可以使您的代码更简洁。