SwiftでPHPにMultiPartPostでデータを渡したい
Swiftでテキストデータと画像データをPHPにPOSTしたいと思っています.
テキストデータは渡せたのですが,画像データを渡すところができていません.
※DateやUserIDなどの情報はデータベースに追加されているのを確認済みです.画像も同様に別データベースに追加されるはずですができていません.
そもそもPHPの知識があまりなく,画像データで渡さなければいけない情報がこれで合っているのかも分からない状態です.
おそらく,送る画像データに複数のパラメータも送らないといけないかと思います(type?など)
画像に関するデータのPOSTする方法が分かる方がいましたら,お教えいただければ幸いです.
取れているデータ
201910182027273320
Optional(405797 bytes)
パラメーター:["Name": "papapa", "UserID": "pepepe", "Comment": "pooooooooo", "Platform": "Xcode", "Date": "201910182027273320", "file": Optional(<UIImage: 0x600003bce060>, {472, 384}), "type": "image/png"]
<NSHTTPURLResponse: 0x6000010e5320> { URL: PHPのURL } { Status Code: 403, Headers {
"Accept-Ranges" = (
bytes
);
Connection = (
"keep-alive"
);
"Content-Length" = (
1422
);
"Content-Type" = (
"text/html"
);
Date = (
"Fri, 18 Oct 2019 11:28:09 GMT"
);
"Last-Modified" = (
"Wed, 08 Mar 2017 06:08:47 GMT"
);
Server = (
Apache
);
} }
parse error
Swift
class ViewController: UIViewController, URLSessionTaskDelegate {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var imageView: UIImageView!
var json: NSData!
// 仮でPOSTする情報
var date = "111"
var user_id = "pepepe"
var name = "papapa"
var comment = "pooooooooo"
var platform = "Xcode"
var imageData = UIImage(named: "res2.png")
var fileName = "image/png"
let path = "PHPのURL"
override func viewDidLoad() {
super.viewDidLoad()
self.getToday()
print(date)
}
@IBAction func buttonTapped(_ sender: Any) {
post()
}
// 日付を取得するメソッド
func getToday(format: String = "yyyyMMddHHmmssSSSS") {
let now = Date()
let formatter = DateFormatter()
formatter.dateFormat = format
date = formatter.string(from: now as Date)
}
// PHPにPOSTする
func post() {
let client = APIClient()
let parameters:[String: Any] = ["file": imageData , "type": fileName, "Date": date, "UserID": user_id, "Name": name, "Comment": comment, "Platform": platform]
client.multipartPost(urlString: path, parameters: parameters)
print("パラメーター:\(parameters)")
}
}
extension NSMutableData {
func appendString(_ string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: false)
append(data!)
}
}
class APIClient {
func multipartPost(urlString: String, parameters: [String: Any]) {
let url = URL(string: urlString)
var request = URLRequest(url: url!)
request.httpMethod = "POST"
let (headers, body) = APIClient.createMultiPartPost(parameters: parameters)
// ヘッダーの設定
for header in headers {
request.addValue(header.value, forHTTPHeaderField: header.key)
}
// Bodyの設定
request.httpBody = body
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data, let response = response {
print(response)
do {
let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments)
print(json)
} catch {
print("parse error")
}
} else {
print(error ?? "unknown error")
}
}
task.resume()
}
static func createMultiPartPost(parameters: [String: Any]) -> (headers: [String:String], body: Data) {
let uniqueId = UUID().uuidString
let boundary = "---------------------------\(uniqueId)"
let header = [
"Content-Type" : "multipart/form-data; boundary=\(boundary)"
]
var body = Data()
let boundaryText = "--\(boundary)\r\n"
for param in parameters {
switch param.value {
case let image as UIImage:
let imageData = image.pngData()
print(imageData)
// let ui8Bytes: [UInt8] = [ 0, 1, 2, 3, 4 ]
// let ui8Data = Data(bytes: ui8Bytes)
// let decodedUi8Bytes = [UInt8](imageData!)
body.append(boundaryText.data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"\(param.key)\"; filename=\"\(uniqueId).png\"\r\n".data(using: .utf8)!)
body.append("Content-Type: image/png\r\n\r\n".data(using: .utf8)!)
body.append(imageData!.base64EncodedData())
body.append("\r\n".data(using: .utf8)!)
case let string as String:
body.append(boundaryText.data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"\(param.key)\";\r\n\r\n".data(using: .utf8)!)
body.append(string.data(using: .utf8)!)
body.append("\r\n".data(using: .utf8)!)
default:
break
}
}
body.append("--\(boundary)--\r\n".data(using: .utf8)!)
return (header, body)
}
}
PHP
<?php
class Data
{
public function AddComment()
{
// 別スクリプトからDBへの接続を一括で行う
require_once('mysql_connect.php');
$pdo = connectDB();
$ID;
$Date = $_POST["Date"];
$UserID = $_POST["UserID"];
$Name = $_POST["Name"];
$Comment = $_POST["Comment"];
$Img = $_FILES["file"];
$Platform = $_POST["Platform"];
$UpdatedAt;
try{
// $pdo=new PDO($dnsinfo,$USER,$PW);//接続
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);//デバックする処理
if($pdo==null){
die("error");
}else{
print("投稿用DB接続しました");
}
$stmt=$pdo->prepare("INSERT INTO 19_comment_data VALUES(?,?,?,?,?,?,?)");
$res=$stmt->execute(array($ID,$Date,$UserID,$Name,$Comment,$Platform,$UpdatedAt));
$sql='SELECT * FROM 19_comment_data ORDER BY id DESC LIMIT 1';
$stmt=$pdo->prepare($sql);
$stmt->execute();
$val= $stmt->fetchAll();
print($val[0]['id']);
// アップロードされたファイルがpng形式か確認 効いてなくね?
if ($_FILES["file"]["type"] == "image/png") {
if ($_FILES["file"]["error"] > 0) {
echo "Return Code:" . $_FILES["file"]["error"] . "";
} else {
echo "Upload:" . $_FILES["file"]["name"] . "";
echo "Type:" . $_FILES["file"]["type"] . "";
echo "Size:" . ($_FILES["file"]["size"] / 1024) . "Kb";
echo "Temp file:" . $_FILES["file"]["tmp_name"] . "";
print($val[0]['id']);
// サーバー上に既にファイルが存在していないか確認
if (file_exists("upload/" . $_FILES["file"]["name"])) {
echo $_FILES["file"]["name"] . "already exists.";
} else {
// pngに変換する
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $val[0]['id'].".png");
$image = imagecreatefrompng("upload/" . $val[0]['id'].".png");
// pngのaを使えるようにする処理
imagealphablending($image, false);
imagesavealpha($image, true);
// png画像として再保存
imagepng($image, "upload/" . $val[0]['id'].".png");
imagedestroy($image);
echo "Stored in:" . "upload/" . $_FILES["file"]["name"];
}
}
} else {
echo "Invalid file";
}
// リサイズ処理 500kb以上ならリサイズ
if($_FILES["file"]["size"] / 1024 > 500)
{
list($width, $hight) = getimagesize("upload/" . $val[0]['id'].".png"); // 元の画像名を指定してサイズを取得
$baseImage = imagecreatefrompng("upload/" . $val[0]['id'].".png"); // 元の画像から新しい画像を作る準備
// 正方形とかに書き出すことも可能
$image = imagecreatetruecolor($width/10, $hight/10); // サイズを指定して新しい画像のキャンバスを作成
// 画像のコピーと伸縮
imagecopyresampled($image, $baseImage, 0, 0, 0, 0, $width/10, $hight/10, $width, $hight);
// コピーした画像を出力する
imagepng($image ,"upload/" . $val[0]['id'].".png");
imagedestroy($image);
}
}catch(PDOException $e)
{//エラー
$res=$e->getMessage();
}
if($res==TRUE){
print("投稿success");
}else if($res==FALSE){
print("投稿error");
}
}
}
$obj=new Data();
$obj->AddComment();
?>