使用swift(php、json、swift)将图像上载到服务器
我正在做一个项目,我想选择一个图像,然后上传到服务器上。我可以点击上传图像按钮,选择图像,然后在iOS模拟器中更改图像,但上传失败。当我在使用swift(php、json、swift)将图像上载到服务器,php,ios,swift,post,image-uploading,Php,Ios,Swift,Post,Image Uploading,我正在做一个项目,我想选择一个图像,然后上传到服务器上。我可以点击上传图像按钮,选择图像,然后在iOS模拟器中更改图像,但上传失败。当我在request.httpBody=createbodywithparams()语句之后包含print(request)时,它表明原始url没有更改。我正在使用XAMPP设置一个虚拟服务器,并使用php与之通信 我的代码: // upload image button clicked @IBAction func edit_click(_ sender: Any
request.httpBody=createbodywithparams()语句之后包含print(request)
时,它表明原始url没有更改。我正在使用XAMPP设置一个虚拟服务器,并使用php与之通信
我的代码:
// upload image button clicked
@IBAction func edit_click(_ sender: Any) {
// select image
let picker = UIImagePickerController()
picker.delegate = self
//picker.sourceType = UIImagePickerControllerSourceType.photoLibrary
picker.allowsEditing = true
self.present(picker, animated: true, completion: nil)
}
// selected image
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
avaImg.image = info[UIImagePickerControllerEditedImage] as? UIImage
self.dismiss(animated: true, completion: nil)
// call function of uploading image file to server
uploadImage()
}
// create body of HTTP request to upload image file
func createBodyWithParams(parameters: [String : String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString(string: "\(value)\r\n")
}
}
let filename = "image.jpg"
let mimetype = "image/jpg"
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
body.append(imageDataKey as Data)
body.appendString(string: "\r\n")
body.appendString(string: "--\(boundary)--\r\n")
return body
}
// upload image to server
func uploadImage() {
let id = user!["id"] as! String
let address = URL(string: "http://localhost/project/uploadImage.php")!
var request = URLRequest(url: address)
request.httpMethod = "POST"
let param = ["id" : id]
let boundary = "Boundary-\(NSUUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = UIImageJPEGRepresentation(avaImg.image!, 0.5)
if imageData == nil {
return
}
request.httpBody = createBodyWithParams(parameters: param, filePathKey: "file", imageDataKey: imageData! as NSData, boundary: boundary) as Data
// launch session
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
// get main queue to communicate back to user
DispatchQueue.main.async {
if error == nil {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
guard let parseJSON = json else {
print("error while parsing")
return
}
print(parseJSON)
} catch {
print("Caught an error: \(error)")
}
} else {
print(error)
}
}
})
task.resume()
}
扩展如下:
// creating protocol of appending string to var of type data
extension NSMutableData {
appendString(string : String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}
我已经参考了以下几页寻求帮助,并尝试修改代码以反映他们方法的差异,但我的头撞到了墙上
编辑1:
忘记了错误消息(dur):捕获到一个错误:error Domain=NSCocoaErrorDomain code=3840“JSON文本没有以数组或对象开头,允许未设置片段的选项。”UserInfo={NSDebugDescription=JSON文本没有以数组或对象开头,允许未设置片段的选项。}
do
语句中的某个地方出错。我认为请求发生了一些问题,因为测试http://localhost/project/uploadImage.php
在我的浏览器中返回数组{“消息”:“缺少所需信息”}
编辑2:PHP代码
uploadImage.php
<?php
// report all errors except E_NOTICE
error_reporting(E_ALL & ~E_NOTICE);
// Part 1: Upload File
// Step 1: check data passed to this php file
if (empty($_REQUEST["id"])) {
$returnArray["message"] = "Missing required information";
print json_encode($returnArray);
return;
}
// request user id
$id = htmlentities($_REQUEST["id"]);
// step 2: create a folder for user with id as folder name
$folder = "/Applications/XAMPP/xamppfiles/htdocs/project/image/" . $id;
// if folder doesn't exist
if (!file_exists($folder)) {
mkdir($folder, 0777, true);
}
// step 3: move uploaded file
$folder = $folder . "/" . basename($_FILES["file"]["name"]);
if (move_uploaded_file($_FILES["file"]["tempname"], $folder)) {
$returnArray["status"] = "200";
$returnArray["message"] = "The file has been uploaded successfully.";
} else {
$returnArray["status"] = "300";
$returnArray["message"] = "Error while uploading.";
}
// Part 2: Updating image path
// build secure connection
$file = parse_ini_file("../../../project.ini");
// store variable information from ini file in php as variables
$host = trim($file["dbhost"]);
$user = trim($file["dbuser"]);
$pass = trim($file["dbpass"]);
$name = trim($file["dbname"]);
// include access.php to call connect function from access.php file
require ("secure/access.php");
$access = new access($host, $user, $pass, $name);
$access->connect();
// STEP 5: save path to uploaded file in database
$path = "http://localhost/project/image/" . $id . "/ava.jpg";
$access->updateImagePath($path, $id);
// STEP 6: get new user information after updating
$user = $access->selectUserViaID($id);
$returnArray["id"] = $user["id"];
$returnArray["username"] = $user["username"];
$returnArray["fullname"] = $user["fullname"];
$returnArray["email"] = $user["email"];
$returnArray["image"] = $user["image"];
// Step 7. Close Connection
$access->disconnect();
// Step 8. feedback array to app
echo json_encode($returnArray);
?>
在@OOper的帮助下,在注释中,我能够跟踪由我的主uploadImage.php文件(参见main post)调用的函数中的语法错误,以及在我应该使用“tmp_name”时使用的“tempname”
在@OOper的帮助下,在注释中,我能够跟踪由我的主uploadImage.php文件调用的函数中的语法错误(参见主帖子),以及在我应该使用“tmp_name”时使用的“tempname”
。当它打印到控制台窗口时,错误会显示什么?如果您将打印(字符串)放在(数据:数据!编码:.utf8))
在DispatchQueue.main.async
?@OOPer当我添加打印时(字符串(数据:数据!编码:.utf8))
DispatchQueue.main.async之前
我在主要帖子中包含的错误消息之前得到了以下信息:
注意:未定义索引:第31行
{“状态”:“300”,“消息”:“上传时出错”,“id”:“98”,“用户名”:“用户名”,“全名”:“全名”,“电子邮件”:“******@me.com”,“图像”:“http:\/\/localhost\/project\/image\/98\/ava,jpg”}
@Pierce我在原始帖子中添加了错误。我想这与createBodyWithParams()有关
函数和最终的请求
@OOPer我看到URL上出现了一些奇怪的东西。我猜我在添加正文时出错了。有什么见解吗?当它打印到控制台窗口时会显示什么错误?如果您将打印(字符串(数据:data!,编码:.utf8))会得到什么
在DispatchQueue.main.async之前
?@OOPer当我添加打印时(字符串(数据:数据!编码:.utf8))
DispatchQueue.main.async之前
我在主要帖子中包含的错误消息之前得到了以下信息:
注意:未定义索引:第31行
{“状态”:“300”,“消息”:“上传时出错”,“id”:“98”,“用户名”:“用户名”,“用户名”全名“:”全名“,”电子邮件“:”*****@me.com“,”图像“:”http:\/\/localhost\/project\/image\/98\/ava,jpg”}
@Pierce我在原始帖子中添加了错误。我想这与createBodyWithParams()有关
函数和最终的请求
@OOPer我看到URL出现了一些奇怪的东西。我猜我在添加正文时出了问题。有什么见解吗?