检索到的JSON数据未解码为xcode 12中的自定义结构



我目前正在学习如何从apache服务器上的mySQL数据库中检索编码的JSON数据,并将JSON解码为我自己的自定义结构的实例;

struct Person: Codable, FetchableRecord, MutablePersistableRecord {
var id: Int64
var firstName: String
var lastName: String
}

这是我在xcode 上请求网络的方法

func dataRequestDownload() {
let baseURL = URL(string: "http://example.com/db_request.php?action=request")

DispatchQueue.main.async {
if let url = baseURL {
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
let decoder = JSONDecoder()
let person = try? decoder.decode(Person.self, from: data)
print(person)
}
}
task.resume()
}
}
}
}

我的问题是person打印为nil,这让我认为数据没有被正确解码。

这是我为GET请求编写的PHP脚本。

<?php


$con=mysqli_connect("127.0.0.1","root","example_password","example_database");

if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

$sql = "SELECT * FROM person";

if ($result = mysqli_query($con, $sql))
{
// If so, then create a results array and a temporary one
// to hold the data
$resultArray = array();
$tempArray = array();

// Loop through each row in the result set
while($row = $result->fetch_object())
{
// Add each row into our results array
$tempArray = $row;
array_push($resultArray, $tempArray);
}

// Finally, encode the array to JSON and output the results
echo json_encode($resultArray);
}

// Close connections
mysqli_close($con)
?>

最后,我不确定这些信息是否重要,但在mySQL数据库中,表的设置就像我的结构一样,其中id是PRIMARY键。如果需要更多信息,请在评论中告诉我,但据我所知,这似乎与我的问题有关。

编辑:其他一些可能重要的信息是,当调用print(data)print(response)时,我得到

48 bytes
{ Status Code: 200, Headers {
Connection =     (
"Keep-Alive"
);
"Content-Length" =     (
48
);
"Content-Type" =     (
"text/html; charset=UTF-8"
);
Date =     (
"Thu, 17 Jun 2021 18:43:02 GMT"
);
"Keep-Alive" =     (
"timeout=5, max=100"
);
Server =     (
"Apache/2.4.46 (Win64) PHP/7.3.21"
);
"X-Powered-By" =     (
"PHP/7.3.21"
);
} })

URL当然不受此限制。

根据评论中的要求;做了这个

let object = try? JSONSerialization.jsonObject(with: data)
print(object)

我得到

Optional(<__NSSingleObjectArrayI 0x281510080>(
{
firstName = John;
id = 0;
lastName = Doe;
}
)
)

第2版:运行时

do {
let person = try decoder.decode([Person].self, from: data)
print(person)
} catch {
print(error)
}

出现以下错误

typeMismatch(Swift.Int64, Swift.DecodingError.Context(codingPath [_JSONKey(stringValue: "Index 0", intValue: 0),
CodingKeys(stringValue: "id", intValue: nil)], debugDescription:
"Expected to decode Int64 but found a string/data instead.", underlyingError: nil))

以下是访问URL 时的实际JSON

[{"id":"0","firstName":"John","lastName":"Doe"}]

在解码JSON时,使用do/try/catch很有帮助,这样您就可以真正看到错误是什么。

在这种情况下,看起来您有一个数组(从PHP代码中可以清楚地看出(,但您正试图解码单个对象。试试这个:

do {
let person = try decoder.decode([Person].self, from: data)
print(person)
} catch {
print(error)
}

然后,由于person中有一个数组(此时可能更准确地命名为people(,因此您需要使用类似person.first的东西来访问它


根据编辑中添加的代码进行更新:

该错误告诉您id是JSON中的String。调整您的Person模型以使用String作为id的类型,而不是Int64,或者调整您的数据库和/或PHP代码以使用数字而不是使用String作为id

最新更新