【发布时间】:2021-09-02 14:02:42
【问题描述】:
我目前正在学习如何从 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 键。如果需要更多信息,请在 cmets 中告诉我,但据我所知,这似乎与我的问题有关。
编辑:其他一些可能重要的信息是当我调用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"
);
} })
网址当然不受此限制。
根据 cmets 中的请求;这样做了
let object = try? JSONSerialization.jsonObject(with: data)
print(object)
我明白了
Optional(<__NSSingleObjectArrayI 0x281510080>(
{
firstName = John;
id = 0;
lastName = Doe;
}
)
)
Edit2:运行时
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"}]
【问题讨论】:
-
您能否提供从您的 API 请求返回的 JSON 示例?
-
我现在正在写一个答案。同时,您能否发布实际的 JSON,以便我确定(即,当您访问 URL 时返回的内容 - 而不是您尝试使用 Swift 解码时发生的情况)
-
该错误(自编辑以来)告诉您
id是 JSON 中的字符串。调整您的Person模型以使用String来表示id而不是Int64的类型,或者调整您的数据库和/或 PHP 代码以使用数字而不是字符串作为 id。 -
添加到答案中
-
您可能需要阅读stackoverflow.com/questions/1390983/… 以获得一些关于让您的PHP 将
id编码为Int的提示。您可以看到,在 JSON 中,它显然是String,所以这在 Swift 方面不是问题。