I am currently in the process of learning how to retrieve encoded JSON data from a mySQL database on an apache server and decode the JSON into an instance of my own custom struct;
struct Person: Codable, FetchableRecord, MutablePersistableRecord {
var id: Int64
var firstName: String
var lastName: String
}
here is my method for the network request on 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()
}
}
}
}
My issue is that person
prints as nil
which makes me think the data isnt being decoded properly.
This is my PHP script for the GET request.
<?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)
?>
Finally I am not sure this info matters, but in the mySQL database the table is set up just like my struct where id is the PRIMARY
key. If more information is needed let me know in the comments, but as far as I know this is all that seems connected to my issue.
Edit: Some other possibly important information is when calling print(data)
and print(response)
I get
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"
);
} })
the URL is exempt from this of course.
Per the request in the comments; having done this
let object = try? JSONSerialization.jsonObject(with: data)
print(object)
I get
Optional(<__NSSingleObjectArrayI 0x281510080>(
{
firstName = John;
id = 0;
lastName = Doe;
}
)
)
Edit2: Upon running
do {
let person = try decoder.decode([Person].self, from: data)
print(person)
} catch {
print(error)
}
the following error appears
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))
Here is the actual JSON upon visiting the URL
[{"id":"0","firstName":"John","lastName":"Doe"}]