I am new to swift and tried many blog posts and github to take image from library and upload it to server(php server side). can you please write the code which takes photo from photo library and upload it to server using alamofire and any other method.
below is the code i was trying to upload photo from photolibrary
#IBAction func upload(_ sender: Any) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = UIImagePickerControllerSourceType.photoLibrary
picker.allowsEditing = false
self.present(picker, animated: true) {
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.image = originalImage
let image = UIImage.init(named: "\(originalImage)")
let imgData = UIImageJPEGRepresentation(image!, 0.2)!
let parameters = ["user":"Sol", "password":"secret1234"]
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "fileset",fileName: "file.jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
} //Optional for extra parameters
},
to:"website")
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
print(response.result.value)
}
case .failure(let encodingError):
print(encodingError)
}
}
}
self.dismiss(animated: true, completion: nil)
}
}
#IBAction func upload(_ sender: Any) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = UIImagePickerControllerSourceType.photoLibrary
picker.allowsEditing = false
self.present(picker, animated: true) {
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.image = originalImage
if let imgData = UIImageJPEGRepresentation(originalImage, 0.2) {
let parameters = ["user":"Sol", "password":"secret1234"]
upload(params: parameters, imageData: imgData)
}
}
picker.dismiss(animated: true, completion: nil)
}
func upload(params : [String: Any], imageData: Data) {
if let url = URL(string: "EnterUrl") {
Alamofire.upload(
multipartFormData: { (multipartdata) in
multipartdata.append(
imageData,
withName: "fileset",
fileName: String("\(Date().timeIntervalSince1970).jpg"),
mimeType: "image/jpg"
)
for (key,value) in params {
if let data = value as? String,
let data1 = data.data(using: .utf8)
{
multipartdata.append(
data1,
withName: key
)
}
}
},
to: url,
method: .post,
headers: nil,
encodingCompletion: { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON(completionHandler: { (response) in
if let err = response.error {
print(err.localizedDescription)
} else {
print(response.result.value ?? "No data")
}
})
case .failure(let error):
print(error.localizedDescription)
}
}
)
}
}
}
try this.
Related
Code Revised based on suggestion solution but still not working. Videos are uploading as 0 bytes. I have an app where a user should be able to record a video from their phone and when 'Use Video' is selected it uploads the video to our PHP Server. The file is uploading successfully and based on the size shown it is not empty. However when I go to play the video in the app or even directly through the browser it won't play. There's no issue with the playback code as I've hardcoded links to other videos on other sites and it works fine. Code is below, any help is much appreciated.
// Finished recording a video
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print("Got a video")
if let pickedVideo:URL = (info[UIImagePickerControllerMediaURL] as? URL) {
// Save video to the main photo album
let selectorToCall = #selector(CameraVideoViewController.videoWasSavedSuccessfully(_:didFinishSavingWithError:context:))
UISaveVideoAtPathToSavedPhotosAlbum(pickedVideo.relativePath, self, selectorToCall, nil)
imageSelected = true
uuid = UUID().uuidString
if imageSelected == true {
saveFileName = "video-\(uuid).mp4"
}
// Save the video to the app directory so we can play it later
let videoData = try? Data(contentsOf: pickedVideo)
let paths = NSSearchPathForDirectoriesInDomains(
FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let documentsDirectory: URL = URL(fileURLWithPath: paths[0])
let dataPath = documentsDirectory.appendingPathComponent(saveFileName)
try! videoData?.write(to: dataPath, options: [])
print("Saved to " + dataPath.absoluteString)
imagePicker.dismiss(animated: true, completion: {
// Anything you want to happen when the user saves an video
self.encodeVideo(dataPath: dataPath)
self.uploadVideo(videoData!)
})
} }
// MP4 Conversion of video
func encodeVideo(dataPath: URL){
let avAsset = AVURLAsset(url: dataPath)
let startDate = Date()
let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough)
let docDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let myDocPath = NSURL(fileURLWithPath: docDir).appendingPathComponent("temp.mp4")?.absoluteString
let docDir2 = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as NSURL
let filePath = docDir2.appendingPathComponent("rendered-Video.mp4")
//uploadVideo(filePath)
//self.encodeVideo(dataPath: dataPath)
deleteFile(filePath!)
if FileManager.default.fileExists(atPath: myDocPath!){
do{
try FileManager.default.removeItem(atPath: myDocPath!)
}catch let error{
print(error)
}
}
//self.uploadVideo((myDocPath as AnyObject) as! URL)
exportSession?.outputURL = filePath
exportSession?.outputFileType = AVFileType.mp4
exportSession?.shouldOptimizeForNetworkUse = true
let start = CMTimeMakeWithSeconds(0.0, 0)
let range = CMTimeRange(start: start, duration: avAsset.duration)
exportSession?.timeRange = range
exportSession!.exportAsynchronously{() -> Void in
switch exportSession!.status{
case .failed:
print("\(exportSession!.error!)")
case .cancelled:
print("Export cancelled")
case .completed:
let endDate = Date()
let time = endDate.timeIntervalSince(startDate)
print(time)
print("Successful")
print(exportSession?.outputURL ?? "")
default:
break
}
}
}
func deleteFile(_ filePath:URL) {
guard FileManager.default.fileExists(atPath: filePath.path) else {
return
}
do {
try FileManager.default.removeItem(atPath: filePath.path)
}catch{
fatalError("Unable to delete file: \(error) : \(#function).")
}
}
// Create Params
func createBodyWithParams(_ parameters: [String: String]?, filePathKey: String?, videoData: Data, boundary: String) -> Data {
var body = ""
if let params = parameters {
for (key, value) in params {
body += "--\(boundary)\r\n"
body += "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n"
body += "\(value)\r\n"
}
}
var filename = ""
if imageSelected {
filename = "video-\(uuid).mp4"
}
let mimetype = "video/mp4"
body += "--\(boundary)\r\n"
body += "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n"
body += "Content-Type: \(mimetype)\r\n\r\n"
body += String(data: videoData, encoding: .utf8)!
body += "\r\n"
body += "--\(boundary)--\r\n"
return Data(body.utf8)
}
// function sending request to PHP to upload a file
func uploadVideo(_ videoData: Data) {
let id = user!["id"] as! String
uuid = UUID().uuidString
let url = URL(string: "http://www.foo.com/videoposts.php")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let param = [
"id" : id,
"uuid" : uuid
]
// body
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
// if picture is selected, compress it by half
let imageData = Data()
// ... body
request.httpBody = createBodyWithParams(param, filePathKey: "file", videoData: imageData, boundary: boundary)
// launch session
URLSession.shared.dataTask(with: request) { data, response, error in
// get main queu to communicate back to user
DispatchQueue.main.async(execute: {
if error == nil {
do {
// json containes $returnArray from php
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
// declare new var to store json inf
guard let parseJSON = json else {
print("Error while parsing")
return
}
// get message from $returnArray["message"]
let message = parseJSON["message"]
// if there is some message - post is made
if message != nil {
// reset UI
self.postBtn.alpha = 0.4
self.imageSelected = false
// switch to another scene
self.tabBarController?.selectedIndex = 4
}
} catch {
// get main queue to communicate back to user
DispatchQueue.main.async(execute: {
let message = "\(error)"
appDelegate.infoView(message: message, color: colorSmoothRed)
})
return
}
} else {
// get main queue to communicate back to user
DispatchQueue.main.async(execute: {
let message = error!.localizedDescription
appDelegate.infoView(message: message, color: colorSmoothRed)
})
return
}
})
}.resume()
}
Okay, I did code something to actually encode and upload a video.
Unfortunately, doing a multipart/form-data in URLSession is actually pretty hard, so I used Alamofire to actually upload the video.
This is the code in parts:
UIImagePickerControllerDelegate (this is the one you should modify, check the //TODO comments)
// MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("Cancelled video operation.")
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let mediaType = info[UIImagePickerControllerMediaType] as? String else {
print("Error with media type. Cancelling.")
dismiss(animated: true, completion: nil)
return;
}
print("Media type: \(mediaType)")
if ( mediaType == "public.movie" ) { // Video selected
let videoURL: URL
if info[UIImagePickerControllerMediaURL] != nil {
videoURL = info[UIImagePickerControllerMediaURL] as! URL
}
else {
videoURL = info[UIImagePickerControllerReferenceURL] as! URL
}
if ( picker.sourceType == .camera ) {
// The original video came from the camera, so it's considered new
// Save it to the photo library
saveVideo(url: videoURL, albumName: "MyApp")
}
// Dismiss the media picker and then re-encode the video
dismiss(animated: true) {
self.exportVideoToMP4(url: videoURL) { (exportedVideoURL) in
guard let tempURL = exportedVideoURL else {
print("ERROR: Unknown error. The exported video URL is nil.")
return
}
print("Temporary video successfully exported to: \(tempURL.absoluteString)")
// TODO: Add your own POST parameters
let uuid = UUID().uuidString
let params = [
"uuid" : uuid,
"user" : "myUserNameOrWhatever"
]
// TODO: Change the parameters for uploading
self.upload( to: "http://yourweb.com/uploadVideo.php", // The URL to send the upload to
videoURL: tempURL, // The file URL of the temporary video file
parameters: params, // The POST parameters you want to send along with the upload
fileName: "vid-\(uuid).mp4", // The filename you want the server to receive.
fieldName: "video_file" // This is "name" from <input type="file" name="video_file" ... /> in HTML
) { (response) in
guard let resp = response else {
print("ERROR: Empty or unrecognizable response from server.")
return
}
print("Video uploaded. RESPONSE: \(resp)")
//: TODO Parse the server response after uploading
}
}
}
}
}
Photo Library helper methods
// MARK: Photo Library
func saveVideo(url: URL, albumName: String) {
// Check authorization status before trying to save the video
switch PHPhotoLibrary.authorizationStatus() {
case .notDetermined:
PHPhotoLibrary.requestAuthorization() { (status) in
switch status {
case .authorized:
self.saveVideo(url: url, albumName: albumName) // Re-try to save the video after authorization
return
default:
return
}
}
case .authorized:
// Save the video to the Photo Library here
if let assetCollection = assetCollection(albumName: albumName) {
// Asset collection exists, insert directly
insertVideo(url: url, assetCollection: assetCollection)
}
else {
// Asset collection doesn't exist, create it and then insert
PHPhotoLibrary.shared().performChanges({
PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: albumName)
}, completionHandler: { (success, error) in
guard success else {
print("ERROR: \(error!.localizedDescription)")
return
}
let createdAssetCollection = self.assetCollection(albumName: albumName)!
self.insertVideo(url: url, assetCollection: createdAssetCollection)
})
}
return
default:
// Not authorized
print("Not authorized to save a video to the Photo Library.")
return
}
}
func assetCollection(albumName: String) -> PHAssetCollection? {
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format:"title == '\(albumName)'")
let fetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumRegular, options: fetchOptions)
return fetchResult.firstObject
}
func insertVideo(url: URL?, assetCollection: PHAssetCollection) {
guard let videoURL = url else {
print("ERROR: The URL to insert into the Photo Library is empty.")
return
}
PHPhotoLibrary.shared().performChanges({
let createAssetRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL)
let assetPlaceholder = createAssetRequest?.placeholderForCreatedAsset
let changeRequest = PHAssetCollectionChangeRequest(for: assetCollection)
let enumeration: NSArray = [assetPlaceholder!]
changeRequest?.addAssets(enumeration)
}, completionHandler: { (success, error) in
guard success else {
print("ERROR: \(error!.localizedDescription)")
return
}
print("Video saved successfully to the Photo Library album.")
})
}
Video Uploading (using Alamofire, installed from CocoaPods)
// MARK: Video upload
func upload(to uploadAddress: String, videoURL: URL, parameters: [String:Any]?, fileName: String, fieldName: String, _ completion: ((String?) -> Void)?) {
Alamofire.upload(multipartFormData: { (multipartFormData) in
// Add the video file (if data is correct)
if let videoData = FileManager.default.contents(atPath: videoURL.path) {
multipartFormData.append(videoData, withName: fileName)
}
// Add the post params (if available)
if let params = parameters {
for (key, value) in params {
multipartFormData.append( (value as! String).data(using: .utf8)! , withName: key)
}
}
}, to: uploadAddress)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.responseString { (response) in
if let completionHandler = completion {
completionHandler(response.result.value)
}
}
case .failure(let encodingError):
print("ERROR: \(encodingError.localizedDescription)")
if let completionHandler = completion {
completionHandler(nil)
}
}
}
}
AVFoundation (the encoding method)
// MARK: AVFoundation
func exportVideoToMP4(url: URL, _ completion: #escaping ((URL?) -> Void)) {
// Show some sort of indicator here, as this could take a while
// Generate a temporary URL path to export the video
let relativePath = "myAppTempVideoExport.mp4";
let outputFilePath = NSTemporaryDirectory() + relativePath;
print("Temp file path: \(outputFilePath)")
// If there's any temp file from before at that path, delete it
if FileManager.default.fileExists(atPath: outputFilePath) {
do {
try FileManager.default.removeItem(atPath: outputFilePath)
}
catch {
print("ERROR: Can't remove temporary file from before. Cancelling export.")
completion(nil)
return
}
}
// Export session setup
let outputFileURL = URL(fileURLWithPath: outputFilePath)
let asset = AVAsset(url: url) // Original (source) video
// The original video codec is probably HEVC, so we'll force the system to re-encode it at the highest quality in MP4
// You probably want to use medium quality if this video is intended to be uploaded (as this example is doing)
if let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) {
exportSession.outputURL = outputFileURL
exportSession.outputFileType = .mp4
exportSession.exportAsynchronously {
// Hide the indicator for the export session
switch exportSession.status {
case .completed:
print("Video export completed.")
completion(outputFileURL)
return
case .failed:
print("ERROR: Video export failed. \(exportSession.error!.localizedDescription)")
completion(nil)
return
case .cancelled:
print("Video export cancelled.")
completion(nil)
return
default:
break
}
}
}
else {
print("ERROR: Cannot create an AVAssetExportSession.")
return
}
}
Now, for this to work, you obviously have to record a video, import frameworks and specify that your view controller conforms to protocols, so:
import AVFoundation
import Photos
import Alamofire
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
imagePicker.sourceType = .camera
imagePicker.delegate = self
imagePicker.showsCameraControls = true
imagePicker.allowsEditing = true
imagePicker.mediaTypes = ["public.movie"]
DispatchQueue.main.async {
self.present(self.imagePicker, animated: true, completion: nil)
}
}
}
I hope this is useful to you, feel free to ask.
So I'm in the middle of designing a social media application that displays posts, comprised of a picture and a description, on a newsfeed. I am able to upload posts to our database, however, I am having problems pulling the image from the database. Specifically, I am getting an error around the code
let image = post["path"] as! UIImage
Saying:
"Thread 1: signal SIGABRT", while the compiler says "Could not cast
value of type '__NSCFString' to 'UIImage'."
Here's the entirety of my code:
import UIKit
class SecondViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var activities = [AnyObject]()
var images = [UIImage]()
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
//tableView.contentInset = UIEdgeInsetsMake(2, 0, 0, 0)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return activities.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "activity", for: indexPath) as! CustomCell
let post = activities[indexPath.row]
print(post["path"])
let image = post["path"] as! UIImage
let username = post["username"] as? String
let text = post["text"] as? String
cell.titleLbl.text = text
cell.userLbl.text = username
cell.activityImage.image = image //as! UIImage
//cell.dateLbl.text = activities[indexPath.row]
//cell.activityImage.image = images[indexPath.row]
DispatchQueue.main.async {
}
return cell
}
override func viewWillAppear(_ animated: Bool) {
loadActivities()
}
func loadActivities() {
let id = user!["id"] as! String
let url = URL(string: "https://cgi.soic.indiana.edu/~team7/posts.php")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let body = "id=\(id)&text=&uuid="
request.httpBody = body.data(using: String.Encoding.utf8)
URLSession.shared.dataTask(with: request) { data, response, error in
DispatchQueue.main.async(execute: {
if error == nil {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
// clean up
self.activities.removeAll(keepingCapacity: false)
self.images.removeAll(keepingCapacity: false)
//self.tableView.reloadData()
guard let parseJSON = json else {
print("Error while parsing")
return
}
guard let posts = parseJSON["posts"] as? [AnyObject] else {
print("Error while parseJSONing")
return
}
self.activities = posts
for i in self.activities.indices {
print("printed")
let path = self.activities[i]["path"] as? String
if let actualPath = path, !actualPath.isEmpty, let url = URL(string: actualPath) {
if let imageData = try? Data(contentsOf: url) {
if let image = UIImage(data: imageData) {
self.images.append(image)
print(self.images)
}
}
}
/*
if path != "" {
//let url = URL(string: path!)!
let url = URL(fileURLWithPath: path!)
let imageData = try? Data(contentsOf: url)
//let imageData = try? Data(contentsOf: url)
let image = UIImage(data: imageData!)!
self.images.append(image)
*/
else {
let image = UIImage()
self.images.append(image)
}
}
self.tableView.reloadData()
} catch {
}
} else {
}
})
}.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension NSMutableData {
func appendString(_ string : String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}
If there is anything you think I should do to improve or make the code run correctly, please let me know!
I followed a tutorial online to upload image to server from swift. I used his sample interface and everything looks fine except I'm getting error "Message":"Sorry, there was an error uploading your file.","Status":Error,"userId":"9". My codes are
<?php
$firstName = $_POST["firstName"];
$lastName = $_POST["lastName"];
$userId = $_POST["userId"];
$target_dir = "percyteng.com/orbit/ios/image";if(!file_exists($target_dir))
{
mkdir($target_dir, 0777, true);
}
$target_dir = $target_dir . "/" . $_FILES["file"]["name"];
echo json_encode( $target_dir);
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir)) {
echo json_encode([
"Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
"Status" => "OK",
"userId" => $_REQUEST["userId"]
]);
} else {
echo json_encode([
"Message" => "Sorry, there was an error uploading your file.",
"Status" => "Error",
"userId" => $_REQUEST["userId"]
]);
}
?>
I have checked and the parameters did get passed from swift.
Here is my code in swift.
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
#IBOutlet weak var image: UIImageView!
#IBOutlet weak var myActivityIndicator: UIActivityIndicatorView!
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
#IBAction func selectImage(sender: AnyObject) {
let ImagePicker = UIImagePickerController()
ImagePicker.delegate = self
ImagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(ImagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.dismissViewControllerAnimated(true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func Upload(sender: AnyObject) {
myImageUploadRequest()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func myImageUploadRequest()
{
let myUrl = NSURL(string: "http://www.percyteng.com/orbit/ios/try.php");
//let myUrl = NSURL(string: "http://www.boredwear.com/utils/postImage.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";
let param = [
"firstName" : "Sergey",
"lastName" : "Kargopolov",
"userId" : "9"
]
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = UIImageJPEGRepresentation(image.image!, 1)
if(imageData==nil) { return; }
request.HTTPBody = createBodyWithParameters(param, filePathKey: "file", imageDataKey: imageData!, boundary: boundary)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
// You can print out response object
print("******* response = \(response)")
// Print out reponse body
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("****** response data = \(responseString!)")
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
dispatch_async(dispatch_get_main_queue(),{
// self.myActivityIndicator.stopAnimating()
self.image.image = nil;
});
/*
if let parseJSON = json {
var firstNameValue = parseJSON["firstName"] as? String
println("firstNameValue: \(firstNameValue)")
}
*/
}
task.resume()
}
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
var 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")
}
}
let filename = "user-profile.jpg"
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.appendData(imageDataKey)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().UUIDString)"
}
}
extension NSMutableData {
func appendString(string: String) {
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
appendData(data!)
}
}
Your iOS code works for me if I use move_uploaded_file() in the php script to move the image from the tempfile path to an existing dir on my server, so that I don't run into problems creating the dir (I also commented out the json conversion of the response). Therefore, the boundaries in the body of the request were all created correctly.
I suspect move_uploaded_file() is failing because of a directory problem. Try something like this:
if(!file_exists($target_dir))
{
mkdir($target_dir, 0777, true) or exit("Couldn't create $target_dir!");
}
I'm trying to upload UIImage to a server via a web api. I'm creating my web rest API with laravel 5.2.
Here is my function in Swift which should make a post request to my API with the UIImage and some parameters:
func uploadWithAlamofire(imageUpload: UIImage) {
let image = imageUpload
// define parameters
let parameters = [
"hometown": "abc",
"living": "abc"
]
// Begin upload
Alamofire.upload(.POST, "http://localhost:8888/buyIT/public/app/api/createPost",
// define your headers here
headers: ["Authorization": "auth_token"],
multipartFormData: { multipartFormData in
// import image to request
if let imageData = UIImageJPEGRepresentation(image, 1) {
multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: "myImage.png", mimeType: "image/png")
}
// import parameters
for (key, value) in parameters {
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}
},
// you can customise Threshold if you wish. This is the alamofire's default value
encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold,
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { response in
print(response)
}
case .Failure(let encodingError):
print(encodingError)
}
})
}
But I don't know how to get the image and then upload it to my server.
Here is what I tried in my web api:
public function createPost(Request $request)
{
$file = $request->input('file');
$input = $request->only('hometown');
//Create deals folder if not exist
if (!file_exists('Upload/images')) {
mkdir('Upload/images', 0777, true);
}
if(file_exists('Upload/images'))
{
// SET UPLOAD PATH
$destinationPath = 'Upload/images';
// GET THE FILE EXTENSION
if ($file != null) {
$extension = $file->getClientOriginalExtension();
// RENAME THE UPLOAD WITH RANDOM NUMBER
$fileName = rand(11111, 99999) . '.' . $extension;
// MOVE THE UPLOADED FILES TO THE DESTINATION DIRECTORY
$upload_success = $file->move($destinationPath, $fileName);
//$filePath = url('/').'/'.$destinationPath.'/'.$fileName;
if($upload_success)
{
return "success";
}
else {
return "failed !!!";
}
}
}
else
{
return "failed";
}
return $file;
}
Or , You can use AlamoFire
func createMultipart(image: UIImage, callback: Bool -> Void){
// use SwiftyJSON to convert a dictionary to JSON
var parameterJSON = JSON([
"id_user": "test"
])
// JSON stringify
let parameterString = parameterJSON.rawString(encoding: NSUTF8StringEncoding, options: nil)
let jsonParameterData = parameterString!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
// convert image to binary
let imageData = UIImageJPEGRepresentation(image, 0.7)
// upload is part of AlamoFire
upload(
.POST,
URLString: "http://httpbin.org/post",
multipartFormData: { multipartFormData in
// fileData: puts it in "files"
multipartFormData.appendBodyPart(fileData: jsonParameterData!, name: "goesIntoFile", fileName: "json.txt", mimeType: "application/json")
multipartFormData.appendBodyPart(fileData: imageData, name: "file", fileName: "iosFile.jpg", mimeType: "image/jpg")
// data: puts it in "form"
multipartFormData.appendBodyPart(data: jsonParameterData!, name: "goesIntoForm")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { request, response, data, error in
let json = JSON(data!)
println("json:: \(json)")
callback(true)
}
case .Failure(let encodingError):
callback(false)
}
}
)
}
let fotoImage = UIImage(named: "foto")
createMultipart(fotoImage!, callback: { success in
if success { }
})
I am trying to upload photos to my database in my server from my iPhone app. the language I am using is swift 2. please help me. I am attaching my code to upload the other details to the JSON link and I want to add image also to my link. please help me
import UIKit
class MealViewController: UIViewController, UITextFieldDelegate,
UIImagePickerControllerDelegate, UINavigationControllerDelegate {
// MARK: Properties
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var photoImageView: UIImageView!
#IBOutlet weak var ratingControl: RatingControl!
#IBOutlet weak var usernameLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Handle the text field’s user input through delegate callbacks.
nameTextField.delegate = self
let attributes = [
NSForegroundColorAttributeName: UIColor.blueColor(),
NSFontAttributeName: UIFont(name: "Avenir", size: 2)!
]
self.navigationController?.navigationBar.titleTextAttributes = attributes
}
// MARK: UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
}
// MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
// Dismiss the picker if the user canceled.
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
// The info dictionary contains multiple representations of the image, and this uses the original.
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
// Set photoImageView to display the selected image.
photoImageView.image = selectedImage
print("my image ", photoImageView)
// Dismiss the picker.
dismissViewControllerAnimated(true, completion: nil)
}
// MARK: Actions
#IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {
// Hide the keyboard.
//nameTextField.resignFirstResponder()
// UIImagePickerController is a view controller that lets a user pick media from their photo library.
let imagePickerController = UIImagePickerController()
// Only allow photos to be picked, not taken.
imagePickerController.sourceType = .PhotoLibrary
// Make sure ViewController is notified when the user picks an image.
imagePickerController.delegate = self
presentViewController(imagePickerController, animated: true, completion: nil)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
let isLoggedIn:Int = prefs.integerForKey("ISLOGGEDIN") as Int
if (isLoggedIn != 1) {
self.performSegueWithIdentifier("goto_login", sender: self)
} else {
self.usernameLabel.text = prefs.valueForKey("USERNAME") as? String
}
}
#IBAction func ratingSubmitButton(sender: UIButton) {
print(ratingControl.rating)
print(self.usernameLabel.text!)
let name:NSString = self.usernameLabel.text!
let value = ratingControl.rating
let imageData = UIImagePNGRepresentation(photoImageView.image!)
do {
let post:NSString = "name=\(name)&value=\(value)"
NSLog("PostData: %#",post);
let url:NSURL = NSURL(string:"http://kiran.com/insert.php")!
let postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
let postLength:NSString = String( postData.length )
let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: NSURLResponse?
var urlData: NSData?
do {
urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
} catch let error as NSError {
reponseError = error
urlData = nil
}
if ( urlData != nil ) {
let res = response as! NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
if (res.statusCode >= 200 && res.statusCode < 300)
{
let responseData:NSString = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!
NSLog("Response ==> %#", responseData);
//var error: NSError?
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
let success:NSInteger = jsonData.valueForKey("success") as! NSInteger
//[jsonData[#"success"] integerValue];
NSLog("Success: %ld", success);
if(success == 1)
{
NSLog("Login SUCCESS");
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
prefs.setObject(name, forKey: "USERNAME")
prefs.setInteger(1, forKey: "ISLOGGEDIN")
prefs.synchronize()
self.performSegueWithIdentifier("goto_rating", sender: self)
} else {
var error_msg:NSString
if jsonData["error_message"] as? NSString != nil {
error_msg = jsonData["error_message"] as! NSString
} else {
error_msg = "Unknown Error"
}
let alertView:UIAlertView = UIAlertView()
alertView.title = "Rating Failed"
alertView.message = error_msg as String
alertView.delegate = self
alertView.addButtonWithTitle("OK")
alertView.show()
}
} else {
}
} else {
}
} catch {
let alertView:UIAlertView = UIAlertView()
alertView.title = "Rating Success!"
alertView.message = "Thank You"
alertView.delegate = self
alertView.addButtonWithTitle("OK")
alertView.show()
}
}
#IBAction func logOutButton(sender: UIButton) {
let appDomain = NSBundle.mainBundle().bundleIdentifier
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain!)
self.performSegueWithIdentifier("goto_login", sender: self)
}
`