我目前正在学习如何从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
。