如何从Node.js WebService获取数据并在iOS应用中解析展示?
解决iOS解析Node.js API返回JSON的类型转换问题
首先,你的核心问题是API返回的JSON结构和代码里的解析逻辑完全不匹配,加上滥用强制类型转换和强制解包,才导致了类型转换崩溃。让我们一步步修正:
错误原因拆解
- API返回的是嵌套JSON结构,其中
recordset是字典数组,但你强行把整个JSON转成[String:String]——这必然报错,因为recordsets、recordset都是数组类型,根本不是字符串。 - 你错误地遍历了字典的键值对(
for jsonResult in jsonArray),这完全不符合API返回的结构,应该遍历recordset里的每个用户字典。 User初始化时用了USERNAME字段,但API返回的是USERCODE,字段名不匹配会导致强制解包崩溃。
修正后的完整代码
首先确保你的User结构体字段和API返回严格对应:
struct User { let usrID: String let firstName: String let lastName: String let password: String let usrClass: String }
然后替换HomeModel里的parseJson方法,同时添加控制台打印逻辑:
func parseJson(data: Data) { var usrArray = [User]() do { // 1. 先解析成[String: Any],因为JSON包含数组、字典等多种类型 guard let jsonDict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else { print("无法将数据解析为JSON字典") return } // 2. 从顶层字典中取出recordset数组 guard let recordset = jsonDict["recordset"] as? [[String: Any]] else { print("找不到recordset字段或字段类型不匹配") return } // 3. 在控制台打印完整的recordset数据 print("=== Recordset原始数据 ===") print(recordset) // 4. 遍历recordset里的每个用户字典 for userDict in recordset { // 安全解包每个字段,避免强制解包崩溃 guard let userCode = userDict["USERCODE"] as? String, let firstName = userDict["FIRSTNAME"] as? String, let lastName = userDict["LASTNAME"] as? String, let password = userDict["PASSWORD"] as? String, let userClass = userDict["USERCLASS"] as? String else { print("用户字段缺失或类型错误,跳过该用户") continue } // 创建User实例(字段名对应API的USERCODE) let usr = User(usrID: userCode, firstName: firstName, lastName: lastName, password: password, usrClass: userClass) usrArray.append(usr) } // 通知代理传递解析后的用户数组 delegate?.usersDownloaded(users: usrArray) } catch let error { print("JSON解析出错:\(error.localizedDescription)") } }
关键修改说明
- 用
guard let替代强制类型转换(as!),既避免崩溃,又能做明确的错误提示。 - 严格匹配API的JSON结构:先拿顶层字典,再提取
recordset数组,这才是正确的解析路径。 - 字段名和API返回完全对齐(
USERCODE代替原来的USERNAME)。 - 添加了控制台打印
recordset的逻辑,方便你直观查看返回数据。 - 对每个用户字段做安全解包,防止因API返回字段缺失导致的崩溃。
现在运行代码,你应该能在控制台看到完整的recordset数据,同时正确解析出User数组传递给代理了。
内容的提问来源于stack exchange,提问作者Nooh Ahamad
相关产品推荐
相关产品推荐

