I am trying to just upload one image to my server but my code is not working.Here is my swift code:
import UIKit
import Alamofire
import SwiftyJSON
class ViewController: UIViewController {
#IBOutlet weak var theOneImage: UIImageView!
let url = "http://xxx.xxx.xxx.xxx/Twitter/UploadImage.php"
let avaImage = UIImage(named: "cupid")
override func viewDidLoad() {
super.viewDidLoad()
theOneImage.image = avaImage
uploadImage(image: avaImage)
}
func uploadImage(image : UIImage?){
let imageData = avaImage?.pngData()
Alamofire.upload(multipartFormData: { (MultipartFormData) in
MultipartFormData.append(imageData!, withName: "image")
}, to: url) { (encodingResult) in
switch encodingResult{
case .success(let upload, _, _):
upload.responseJSON{ response in
print(response.request!) // original URL request
print(response.response!) // URL response
print(response.data!) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
case .failure(let encodingError):
print(encodingError)
}
}
}
}
here is my php code:
if (empty($_FILES["image"])){
$response = array("error" => "no data");
}else{
$response["error"] = "NULL";
$filename = uniqid() . ".jpg";
if(move_uploaded_file($_FILES['image']['test'],'/ava')){
$response["status"] = "success";
$response["filepath"] = "http:" . $filename;
$response["filename"] = "" . $_FILES["file"]["name"];
}else{
$response['status'] = "Failure";
$response['error'] = "".$_FILES["image"]["error"];
$response['name'] = "".$_FILES["image"]["name"];
$response['path'] = "".$_FILES["image"]["tmp_name"];
$response['type'] = "".$_FILES["image"]["type"];
$response['size'] = "".$_FILES["image"]["size"];
}
}
echo json_encode($response);
the response I am getting is telling me that in UploadImage.php, $_FILE["image"] is empty
here is my directories of my server:
server screen shot
please help. Thank you all!
Related
I have an IOS app that uses PHP for my API. My file upload is working fine but the name of the file is not appending to the file. I've mirrored other pages in my app but it's still not working although others are working fine. I’m able to see the file on the server, but the name is notes-.jpg. It’s not appending the puuid to the name per the code. I've implemented MessageKit on the ViewController that isn't working (just in case it makes a difference). Here is my code below, I feel like I'm looking for a needle in a haystack. The code is a little sloppy (please don't judge).
func createBodyWithParams(_ parameters: [String: String]?, filePathKey: String?, imageDataKey: Data, boundary: String) -> Data {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
// if file is not selected, it will not upload a file to server, because we did not declare a name file
var filename = ""
if imageSelected == true {
filename = "notes-\(puuid).jpg"
print("name of file", filename)
}
let mimetype = "image/jpg"
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.append(imageDataKey)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body as Data
}
func uploadImage(_ image: UIImage, completion: #escaping (URL?) -> Void) {
print("im in upload")
let avame = user!["ava"]
let user_id = user!["id"] as! String
let me = user!["username"] as! String
let recipientfe = getmessages["recipient"]
let uuidfe = getmessages["uuid"] as! String
let recipient = getmessages["username"] as! String
let rid = String(describing: getmessages["sender_id"]!)
let puuid = UUID().uuidString
let text = ""
let url = URL(string: "https://localhost/messagepost.php")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let parameters = ["sender_id": user_id, "uuid": uuidfe, "sender": me, "recipient_id": rid, "recipient": recipient, "puuid": puuid, "text": text]
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var data = Data()
if image != nil {
data = image.jpegData(compressionQuality: 0.5)!
}
request.httpBody = createBodyWithParams(parameters, filePathKey: "file", imageDataKey: data, boundary: boundary)
URLSession.shared.dataTask(with: request) { data, response, error in
DispatchQueue.main.async(execute: {
if error != nil {
Helper().showAlert(title: "Server Error", message: error!.localizedDescription, in: self)
print("Server Error")
return
}
do {
guard let data = data else {
Helper().showAlert(title: "Data Error", message: error!.localizedDescription, in: self)
print("Data Error")
return
}
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary
guard let parsedJSON = json else {
return
}
if parsedJSON["status"] as! String == "200" {
let newurl = parsedJSON["path"]
self.isSendingPhoto = true
guard let url = newurl else {
return
}
var message = Message(messageuser: self.sender, image: image)
message.downloadURL = url as? URL
self.save(message)
self.messagesCollectionView.scrollToBottom()
} else {
if parsedJSON["message"] != nil {
let message = parsedJSON["message"] as! String
Helper().showAlert(title: "Error", message: message, in: self)
print("where am i", parsedJSON["message"] as Any)
}
}
} catch {
Helper().showAlert(title: "JSON Error", message: error.localizedDescription, in: self)
print("where am i 2")
}
})
}.resume()
}
PHP Upload File
<?php
if (!empty($_REQUEST["uuid"])) {
$id = htmlentities($_REQUEST["id"]);
$recipient = htmlentities($_REQUEST["recipient"]);
$recipient_id = htmlentities($_REQUEST["recipient_id"]);
$uuid = htmlentities($_REQUEST["uuid"]);
$puuid = htmlentities($_REQUEST["puuid"]);
$text = htmlentities($_REQUEST["text"]);
$sender = htmlentities($_REQUEST["sender"]);
$sender_id = htmlentities($_REQUEST["sender_id"]);
if (isset($_FILES['file']) && $_FILES['file']['size'] > 1) {
$folder = "/home/xxxxx/public_html/notes/" . $uuid;
// if no posts folder, create it
if (!file_exists($folder)) {
mkdir($folder, 0777, true);
}
$picture = $folder . "/" . basename($_FILES["file"]["name"]);
chmod($picture,0777);
if (move_uploaded_file($_FILES["file"]["tmp_name"], $picture)) {
$path = "http://localhost/notes/" . $uuid . "/notes-" . $puuid . ".jpg";
$returnArray["message"] = "Post has been made with picture";
$returnArray["path"] = $path;
$returnArray["status"] = "200";
} else {
$returnArray["message"] = "Post has been made without picture";
$path = "";
}
$result=$access->insertMessage($recipient, $recipient_id, $uuid, $sender,$sender_id, $text, $path);
// STEP 2.5 If posts are found, append them to $returnArray
if (!empty($result)) {
$returnArray["message"] = $result;
$result = $access->updatebadge($recipient_id);
}
else {
$returnArray["message"] = "Couldnt insert". $puuid ."";
}
// if data is not passed - show posts except id of the user
}
else {
$username = htmlentities($_REQUEST["username"]);
$uuid = htmlentities($_REQUEST["uuid"]);
$recipient_id = htmlentities($_REQUEST["recipient_id"]);
$message = $access->conversation($username, $uuid, $recipient_id);
if (!empty($message)) {
$returnArray["message"] = $message;
}
}
}
$access->disconnect();
echo json_encode($returnArray);
?>
I figured it out. The body and headers in Swift were incorrect and weren't sending the correct file name.
I changed the body to:
// web development and MIME Type of passing information to the web server
let boundary = "Boundary-\(NSUUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
// access / convert image to Data for sending to the server
var data = Data()
// if picture has been selected, compress the picture before sending to the server
if image != nil {
data = image.jpegData(compressionQuality: 0.5)!
}
// building the full body along with the string, text, file parameters
request.httpBody = Helper().body(with: parameters, filename: "notes-\(puuid).jpg", filePathKey: "file", imageDataKey: data, boundary: boundary) as Data
I want to upload multiple images to my server using Alamofire Lib, but it's uploading 1 image only.
I'm using an image picker that returns an array of UIImage which is Named
imagesdata
This is my code:
#IBAction func uploadimages(_ sender: Any) {
Alamofire.upload(
multipartFormData: { multipartFormData in
for img in self.imagesdata{
let imgdata = UIImageJPEGRepresentation(img, 1.0)
multipartFormData.append(imgdata!,withName: "image", fileName: "image.jpg", mimeType: "image/jpeg")
print("$$$$$$$$$$ : \(imgdata!)")
}
},
to: "http://localhost/maarathtest/MAPI/img_upload.php",
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
)
}
and my PHP:
<?php
$response = array();
if (empty($_FILES["image"])) {
$response['File'] = "NOFILE";;
} else {
$filename = uniqid() . ".jpg";
// If the server can move the temporary uploaded file to the server
if (move_uploaded_file($_FILES['image']['tmp_name'], "images/" . $filename)) {
$response['status'] = "Success";
$response['filepath'] = "https://serverName/MAPI/images/" . $filename;
} else {
$response['status'] = "Failure";
}
}
echo json_encode($response);
?>
And my console log:
$$$$$$$$$$ : 5849743 bytes
$$$$$$$$$$ : 3253337 bytes
[Request]: POST http://localhost/maarathtest/MAPI/img_upload.php
[Response]: <NSHTTPURLResponse: 0x600000620940> { URL: http://localhost/maarathtest/MAPI/img_upload.php } { status code: 200, headers {
Connection = "Keep-Alive";
"Content-Length" = 101;
"Content-Type" = "text/html";
Date = "Thu, 25 May 2017 10:08:08 GMT";
"Keep-Alive" = "timeout=5, max=100";
Server = "Apache/2.4.18 (Unix) OpenSSL/1.0.2h PHP/5.5.35 mod_perl/2.0.8-dev Perl/v5.16.3";
"X-Powered-By" = "PHP/5.5.35";
} }
[Data]: 101 bytes
[Result]: SUCCESS: {
filepath = "https://serverName/MAPI/images/5926ad083b770.jpg";
status = Success;
}
I have changed my code as below,
Alamofire.upload(
multipartFormData: { multipartFormData in
var count = 1
for img in self.imagesdata{
let imgdata = UIImageJPEGRepresentation(img, 1.0)
multipartFormData.append(imgdata!,withName: "image\(count)", fileName: "image\(count).jpg", mimeType: "image/jpeg")
count += 1
}
},...
<?php
$response = array();
if (empty($_FILES["image1"])) {
$response['File1'] = "NOFILE";
} else {
$filename = uniqid() . ".jpg";
// If the server can move the temporary uploaded file to the server
if (move_uploaded_file($_FILES['image1']['tmp_name'], "images/" . $filename)) {
$response['status1'] = "Success";
$response['filepath1'] = "https://serverName/MAPI/images/" . $filename;
} else {
$response['status1'] = "Failure";
}
}
if (empty($_FILES["image2"])) {
$response['File2'] = "NOFILE";
} else {
$filename = uniqid() . ".jpg";
// If the server can move the temporary uploaded file to the server
if (move_uploaded_file($_FILES['image2']['tmp_name'], "images/" . $filename)) {
$response['status2'] = "Success";
$response['filepath2'] = "https://serverName/MAPI/images/" . $filename;
} else {
$response['status2'] = "Failure";
}
}
echo json_encode($response);
?>
Now it's uploading the images, but I don't think this is the proper way to do it, since I don't know how many images users want to upload!
How can I do this properly?
I have solved the issue, the code below hope to help some 1
Swift :
#IBAction func uploadimages(_ sender: Any) {
Alamofire.upload(
multipartFormData: { multipartFormData in
var count = 1
for img in self.imagesdata{
let imgdata = UIImageJPEGRepresentation(img, 0.5)
// the name should be as array other wise want work
multipartFormData.append(imgdata!,withName: "image[]", fileName: "image\(count).jpg", mimeType: "image/jpeg")
count += 1
}
},
to: "http://localhost/maarathtest/MAPI/img_upload.php",
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
)
}
PHP code sample :
<?php
$response = array();
if (empty($_FILES["image"])) {
$response['File1'] = "NOFILE";
}else {
//$filename = uniqid() . ".jpg";
// loop through files array from IOS app
foreach ($_FILES["image"]["tmp_name"] as $index => $tmp_name) {
$filePath = "images/" . basename($_FILES["image"]["name"][$index]);
if (move_uploaded_file($tmp_name, $filePath)) {
// Images are stored in file path , do what ever is needed
$response['filepath'][$index] = $filePath;
}
$response['status'] = "Success";
}
}
echo json_encode($response);
?>
Use this below code to upload multiple images to your server. I've put this in a method that takes in NSMutableArray of UIImage objects and their corresponding names in another array. You could change NSMutableArray to Swift Array if you want. After successful upload, the completion handler will get called and would return a mapped object based on your response:Code:
public func executeMultipleImageUpload<T: Mappable>(type: T.Type, url: String, parameters: Dictionary<String, String>, images: NSMutableArray?, names: [String], view: UIView, completion: #escaping(_ result: DataResponse<T>?)-> Void) {
//Calling Alamofire Upload method here...
Alamofire.upload(multipartFormData: { multipartFormData in // This is first param, the part data itself
if images == nil || images?.count == 0 {
print("There are no images to upload..!!")
} else {
//Append image data from array of images to multipart form data
var count = 1
for image in images! {
if let imageData = UIImageJPEGRepresentation(image as! UIImage, 0.76) {
multipartFormData.append(imageData, withName: names[count - 1], fileName: names[count - 1], mimeType: "image/jpeg")
}
count += 1
}
}
//We are encoding the parameters to be sent here in the multipart as well..
for (key, value) in parameters {
multipartFormData.append((value.data(using: .utf8))!, withName: key)
}}, to: url, method: .post, headers: ["": ""], //This is second param (to:)
encodingCompletion: { encodingResult in // This is third param (encodingCompletion:)
switch encodingResult {
case .success(let upload, _, _):
upload.response { [weak self] response in
guard self != nil else {
return
}
debugPrint(response)
}.validate().responseObject{
(response: DataResponse<T>) in
completion(response)
}
case .failure(let encodingError):
print("error:\(encodingError)")
}
})
}
I am trying to upload an image using Alamofire and PHP on my server, I checked all the different questions on here but for some reason it wont work. I have tested my PHP file with HTML and it succeeded in uploading an image, so it narrows down to my swift code.
Swift:
let URL = "http://example.com/post_pic.php"
let imageData = UIImageJPEGRepresentation(imageView.image!, 1)
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData!, withName: "imageFile", mimeType: "image/jpeg")
}, to:URL)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (Progress) in
print("Upload Progress: \(Progress.fractionCompleted)")
})
upload.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
// self.showSuccesAlert()
//self.removeImage("frame", fileExtension: "txt")
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
case .failure(let encodingError):
print("Failure:")
print(encodingError)
}
}
PHP:
if(isset($_FILES['imageFile'])){
$errors= array();
$file_name = $_FILES['imageFile']['name'];
$file_size =$_FILES['imageFile']['size'];
$file_tmp =$_FILES['imageFile']['tmp_name'];
$file_type=$_FILES['imageFile']['type'];
$file_ext=strtolower(end(explode('.',$_FILES['imageFile']['name'])));
print_r($_FILES['imageFile']);
if(empty($errors)==true){
move_uploaded_file($file_tmp,"images/".$file_name);
}
else
{
echo '{"response":"file_move_error"}';
}
}
else
{
echo '{"response":"file_error"}';
}
The response I get is:
Optional(<NSHTTPURLResponse: 0x17022df20> { URL: http://example.com/post_pic.php } {
status code: 200, headers {
Connection = "Keep-Alive";
"Content-Length" = 25;
"Content-Type" = "application/json";
Date = "Wed, 25 Jan 2017 10:16:29 GMT";
"Keep-Alive" = "timeout=5, max=100";
Server = "Apache/2.4.7 (Ubuntu)";
"X-Powered-By" = "PHP/5.5.9-1ubuntu4.20";
} })
Optional(25 bytes)
SUCCESS
JSON: {
response = "file_error";
}
I can use this code into my app
let URL = "http://example.com/post_pic.php"
let imageData = UIImageJPEGRepresentation(imageView.image!, 1)
upload(multipartFormData: { multipartFormData in
multipartFormData.append(imageData!, withName: "imageFile", fileName: "file.jpg", mimeType: "image/jpeg")
},
to: URL, method: .post,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.validate()
upload.responseJSON { response in
if response.result.error != nil {
print("failure")
UIAlertView(title: "Fail", message: "Please retry again.", delegate: nil, cancelButtonTitle: "Ok").show()
} else {
print("success")
}
}
case .failure(let encodingError):
print(encodingError)
}
}
)
Please I have been trying to upload pictures from a xamarin form application to a php server but seems not to be working. The server receives an empty $_FILES request. This is the c# code.
public async Task<bool> Upload(MediaFile mediaFile, string filename)
{
byte[] bitmapData;
var stream = new MemoryStream();
mediaFile.GetStream().CopyTo(stream);
bitmapData = stream.ToArray();
var fileContent = new ByteArrayContent(bitmapData);
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileUpload",
FileName = filename
};
string boundary = "---8393774hhy37373773";
MultipartFormDataContent multipartContent = new MultipartFormDataContent(boundary);
multipartContent.Add(fileContent);
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.PostAsync("http://www.url.com/upload.php", multipartContent);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
return true;
}
return false;
}
Below is the php file to receive the uploaded image. I tried to save the content of the posted image to file but the file only has an empty array and always return "failure". Please what am i missing wrong? I have searched the web but cant seem to understand the problem.
$uploads_dir = 'uploads/';
$req_dump = print_r( $_FILES, true );
$fp = file_put_contents( 'data.txt', $req_dump );
if (isset($_FILES["fileUpload"]["tmp_name"]) AND is_uploaded_file($_FILES["fileUpload"]["tmp_name"]))
{
$tmp_name = $_FILES["fileUpload"]["tmp_name"];
$name = $_FILES["fileUpload"]["name"];
$Result = move_uploaded_file($tmp_name, "$uploads_dir/$name");
echo "Success";
}
else
{
echo "Failure";
}
The AND operator is really not a good choice for you. (On line 4).
Sometimes it shows some really unexpected behaviour. (I can refer you to 'AND' vs '&&' as operator for more info).
If you want a logical AND use the && operator instead.
The line would be
if (isset($_FILES["fileUpload"]["tmp_name"]) && is_uploaded_file($_FILES["fileUpload"]["tmp_name"]))
I know this is an old post but this is how I upload an image from Xamarin Forms to PHP
http://gjhdigital.com/xamarin/xamarin-forms-upload-image-to-php/
Xamarin c# code
using Plugin.Media;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace UploadPicToServer
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private async void btnUpload_Clicked(object sender, EventArgs e)
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert("Photos Not Supported", ":( Permission not granted to photos.", "OK");
return;
}
var file = await Plugin.Media.CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
});
if (file == null)
return;
string fileName = file.Path;
image.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
//UploadImage1(file.AlbumPath);
UploadImage(file.GetStream(), fileName);
}
private async void UploadImage(Stream mfile, string fileName)
{
int authorID = 2;
string username = "yourusername";
var url = "https://yourwebsite.com/ba-add-profile-pic.php";
url += "?id="+ authorID +"&username="+ username; //any parameters you want to send to the php page.
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://yourwebsite.com/");
MultipartFormDataContent form = new MultipartFormDataContent();
//HttpContent content = new StringContent("fileToUpload");
//form.Add(content, "fileToUpload");
var stream = mfile;
StreamContent content = new StreamContent(stream);
//get file's ext
string fileExt = fileName.Substring(fileName.Length - 4);
string fName = "User-Name-Here-123" + fileExt.ToLower();
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileToUpload",
FileName = fName
};
form.Add(content);
var response = await client.PostAsync(url, form);
var result = response.Content.ReadAsStringAsync().Result;
}
catch (Exception e)
{
//debug
Debug.WriteLine("Exception Caught: " + e.ToString());
return;
}
}
public static byte[] ToArray(Stream s)
{
if (s == null)
throw new ArgumentNullException(nameof(s));
if (!s.CanRead)
throw new ArgumentException("Stream cannot be read");
MemoryStream ms = s as MemoryStream;
if (ms != null)
return ms.ToArray();
long pos = s.CanSeek ? s.Position : 0L;
if (pos != 0L)
s.Seek(0, SeekOrigin.Begin);
byte[] result = new byte[s.Length];
s.Read(result, 0, result.Length);
if (s.CanSeek)
s.Seek(pos, SeekOrigin.Begin);
return result;
}
}
}
PHP code
//parameters send in via querystring
if (!isset($_REQUEST['author']) || !isset($_REQUEST['username']) ) {
die('{"status" : "Bad", "reason" : "Invalid Access"}');
}
$userID = $_REQUEST['author'];
$isGood = false;
try{
$uploaddir = '../someFolderToStoreTheImage/';
$fileName = basename($_FILES['fileToUpload']['name']);
$uploadfile = $uploaddir . basename($_FILES['fileToUpload']['name']);
//CHECK IF ITS AN IMAGE OR NOT
$allowed_types = array ('image/jpeg', 'image/png', 'image/bmp', 'image/gif' );
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$detected_type = finfo_file( $fileInfo, $_FILES['fileToUpload']['tmp_name'] );
if ( !in_array($detected_type, $allowed_types) ) {
die ( '{"status" : "Bad", "reason" : "Not a valid image"}' );
}
//
if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $uploadfile)) {
//echo "File is valid, and was successfully uploaded.\n";
echo '{"status" : "Success", "reason" "'. $fileName .'"}';
$isGood = true;
} else {
//echo "Possible file upload attack!\n";
echo '{"status" : "Bad", "reason" : "Unable to Upload Profile Image"}';
}
}
catch(Exception $e) {
echo '{"status" : "Bad", "reason" : "'.$e->getMessage().'"}';
}
I'm having a huge issue trying to upload my images to php.
my script works fine but when I go to view the image online it shows a broken image and if I download it and try to open in photoshop it says the image is corrupt.
Swift file upload script
func percentEscapeString(string: String) -> String {
return CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
string,
nil,
":/?#!$&'()*+,;=",
CFStringBuiltInEncodings.UTF8.rawValue) as String;
}
func imagePost(params : NSMutableDictionary, image: UIImage, url: String, postCompleted: (succeeded: Bool, msg: AnyObject) -> ()){
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
let imageData = UIImageJPEGRepresentation(image, 0.9)
var base64String = self.percentEscapeString(imageData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))) // encode the image
print(base64String)
params["image"] = [ "content_type": "image/jpeg", "filename":"test.jpg", "file_data": base64String]
do{
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions(rawValue: 0))
}catch{
print(error)
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
NSOperationQueue.mainQueue().addOperationWithBlock {
var err: NSError?
var json:NSDictionary?
do{
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
}catch{
print(error)
err = error as NSError
}
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
if(err != nil) {
print("Response: \(response)")
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData!)")
print(err!.localizedDescription)
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: '\(jsonStr)'")
postCompleted(succeeded: false, msg: "Error")
}else {
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
if let success = parseJSON["success"] as? Bool {
//print("Success: \(success)")
postCompleted(succeeded: success, msg: parseJSON["message"]!)
}
return
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: \(jsonStr)")
postCompleted(succeeded: false, msg: "Unable to connect")
}
}
}
})
task.resume()
}
PHP script
$json = file_get_contents('php://input');
$obj = json_decode($json);
if($obj->image->content_type == "image/jpeg"){
$filename = $obj->id . time() . ".jpg";
$target_file = "userImages/$filename";
if(file_put_contents($target_file, $obj->image->file_data)){
$return_data = ["success"=>true, "message"=>"The photo has been uploaded."];
} else {
$return_data = ["success"=>false, "message"=>"Sorry, there was an error uploading your photo."];
}
}else{
$return_data = ["success"=>false,"message"=>"Not a JPEG image"];
}
part of the base64 before uploading.
%2F9j%2F4AAQSkZJRgABAQAASABIAAD%2F4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAlqADAAQAAAABAAAAyAAAAAD%2F7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs%2BEJ%2B%2F8AAEQgAyACWAwEiAAIRAQMRAf
part of the base64 after uploading.
%2F9j%2F4AAQSkZJRgABAQAASABIAAD%2F4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAlqADAAQAAAABAAAAyAAAAAD%2F7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs%2BEJ%2B%2F8AAEQgAyACWAwEiAAIRAQMRAf
Can anyone see any problems?
It seems that this code for replacing unwanted characters in the base64 doesn't work for php.
func percentEscapeString(string: String) -> String {
return CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
string,
nil,
":/?#!$&'()*+,;=",
CFStringBuiltInEncodings.UTF8.rawValue) as String;
}
I took it out and altered my php code to replace the unwanted characters.
if($obj->image->content_type == "image/jpeg"){
$filename = $obj->id . time() . ".jpg";
$target_file = "userImages/$filename";
$data = str_replace(' ', '+', $obj->image->file_data);
$data = base64_decode($data);
if(file_put_contents($target_file, $data)){
$return_data = ["success"=>true, "message"=>"The photo has been uploaded."];
} else {
$return_data = ["success"=>false, "message"=>"Sorry, there was an error uploading your photo."];
}
}else{
$return_data = ["success"=>false,"message"=>"Not a JPEG image"];
}
This fixed it for me.
|*| Swift2 Code : To Convert Image to String for sending to Php Server
let NamImjVar = UIImage(named: "NamImjFyl")
let ImjDtaVar = UIImageJPEGRepresentation(NamImjVar!, 1)
let ImjSrgVar = ImjDtaVar!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue:0))
|*| Php Code : To Convert String data back to image and save in server
<?php
$NamImjSrgVar = $_REQUEST["ImjKey"];
header('Content-Type: image/jpeg');
$NamImjDtaVar = str_replace(' ', '+', $NamImjSrgVar);
$NamImjHexVar = base64_decode($NamImjDtaVar);
file_put_contents("NamFyl.jpg", $NamImjHexVar)
?>