
くそ。。。。json_encodeのせいだったのだ…[boringssl] boringssl_metrics_log_metric_block_invoke(151) Failed to log metrics は関係なかったのだ…
PHPで作ったapiのデータの取得を試みても何度もエラーを吐きやがる
あまりに長時間ハマったので、記録しておきたいと思います。
そう、swiftは型に厳格だったわけです。
結論からいくと、PHPのjson_encodeは、Intを勝手にStringで吐き出したりしてやがりました。
$data_sql='SELECT item_id FROM table_name limit 3';
$data=$db->prepare($data_sql);
$data->execute();
$data=$data->fetchall(PDO::FETCH_ASSOC);
$result_array=array();
$result_array["item"]=$data;
$return_json=json_encode($result_array);
header('Content-type: application/json');
echo $return_json;
////item_idはDB上、bigint
と、こんな感じで作ってたのに、何度やってもswift側がうまく取得してくれない。
こんな感じで作ってて。req_urlとかの処理ははしょるけど。
class DataList:ObservableObject{
struct ResultJson:Codable{
struct Item:Codable{
let item_id:Int?
}
let item:[Item]?
}
let req = URLRequest(url:req_url)
let session = URLSession(configuration:.default,delegate:nil,delegateQueue:OperationQueue.main)
let task = session.dataTask(with:req,completionHandler:{
(data,response,error) in
session.finishTasksAndInvalidate()
do{
let decoder = JSONDecoder()
let json = try decoder.decode(ResultJson.self,from:data!)
print(json)
}catch{
print("エラー発生")
}
})
task.resume()
で、よく見たら、よーーーくみたら、PHPで作ったapiのデータ、こんな感じだった
{"item":[{"item_id":"5723651"},{"item_id":"7161644"},{"item_id":"7161645"}]}
DBの型に基づいてうまくやってくれると思ったら、Stringになってやがる。。
なので、API側を以下に修正
$return_json=json_encode($result_array);
から
$return_json=json_encode($result_array,JSON_NUMERIC_CHECK);
これでうまくはいくんだけど、でも完全じゃない。例えば乱数とか出して数字ばかりだったからだといって、Intにされると、同じカラムのはずなのに、値によって型を変えてしまう可能性があるのだ。
だから、明示的にですが
$data["item_id"]=(int)$d["item_id"]
みたいな感じでバカ丁寧に配列を作って、json_encodeするのがいいらしい。
もうこれで忘れないぞ!