error while trying to upload image with NSURLSession - ios

I'm using the following code to upload and image:
- (IBAction)uploadPic:(UIButton *)sender {
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:#[self.imageReferenceURL] options:nil];
PHAsset *asset = [result firstObject];
if (asset) {
PHImageManager *manager = [PHImageManager defaultManager];
[manager requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
// upload the `imageData`
NSURL *fileURL = info[#"PHImageFileURLKey"];
NSString *filename = [fileURL lastPathComponent];
NSString *mimeType = [self mimeTypeForPath:filename];
NSString *urlString = #"url";
NSMutableURLRequest* request= [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *postbody = [NSMutableData data];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"uploaded_file\"; filename=\"%#\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Type: %#\r\n\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:imageData];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:postbody completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response %#",responseString);
}];
[task resume];
}];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
self.imageReferenceURL = info[UIImagePickerControllerReferenceURL];
[picker dismissViewControllerAnimated:YES completion:nil];
}
and I got this error:
2015-09-30 10:35:42.921 udazz[874:453021] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
*** First throw call stack:
(0x183804f5c 0x198307f80 0x1836ee30c 0x1836f9db4 0x100020240 0x188d923e4 0x188d92360 0x188d7ac88 0x188d91c78 0x188d918a8 0x188d8aadc 0x188d5ba2c 0x188d59f18 0x1837bc5a4 0x1837bc038 0x1837b9d38 0x1836e8dc0 0x18e83c088 0x188dc2f60 0x1000315a4 0x198b328b8)
libc++abi.dylib: terminating with uncaught exception of type NSException

Related

Image gets uploaded through multipart POST service but I do not receive response from server

I use the following code to upload images to the server:
void call_MediaUploadAPI(NSArray *parameters, NSString *url, BOOL isAnUpdate, SuccessBlock successBlock, FailureBlock failureBlock)
{
NSString *boundary = #"----WebKitFormBoundary7MA4YWxkTrZu0gW";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#%#", BASEURL, url]]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:600.0];
[request setHTTPMethod:#"POST"];
NSString *token = [[NSUserDefaults standardUserDefaults]valueForKey:TOKEN];
NSString *authValue = [NSString stringWithFormat: #"JWT %#",token];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[request setValue:contentType forHTTPHeaderField: #"Content-Type"];
NSError *error;
NSMutableData *body = [NSMutableData data];
for (NSDictionary *param in parameters) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
if (param[#"fileName"]) {
NSString *mimetype = [[NetworkIntractor sharedManager] mimeTypeForPath:param[#"fileName"]];
NSData *imageData = [NSData dataWithContentsOfFile:param[#"fileName"]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition:form-data; name=\"%#\"; filename=\"%#\"\r\n", param[#"name"], param[#"fileName"]]dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Type: %#\r\n\r\n", mimetype]dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
if (error) {
NSLog(#"%#", error);
}
} else {
[body appendData:[[NSString stringWithFormat:#"Content-Disposition:form-data; name=\"%#\"\r\n\r\n", param[#"name"]]dataUsingEncoding:NSUTF8StringEncoding]];
if ([param[#"name"] isEqualToString:#"data"]) {
[body appendData:[NSJSONSerialization dataWithJSONObject:param[#"value"] options:0 error:nil] ];
}else{
[body appendData:[[NSString stringWithFormat:#"%#", param[#"value"]]dataUsingEncoding:NSUTF8StringEncoding] ];
}
}
}
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n", boundary]dataUsingEncoding:NSUTF8StringEncoding] ];
[request setHTTPBody:body];
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (dict != nil) {
NSLog(#"multipart api response : %#", dict);
successBlock(dict,response);
}else
{
NSLog(#"multipart api failure response : %#", error);
failureBlock(error,response);
}
}}];
[task resume];
}
I tried giving different combination of timeout intervals like this:
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.timeoutIntervalForRequest = 150.0f;
config.timeoutIntervalForResource = 300.0f;
self.session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];
But, for a bit larger image files, I never get response back from the server though the image gets uploaded as I can find them available in the admin panel.

SQLITE database Uploading

Is there any way to upload , download to a server read the .sqlite file present in document directory from your iPhone application and use it as your database.
I tried by converting to binary data and uploading but the file is getting encrypted I cannot read or write it after restoring/downloading it from server.
Any suggestion?
Uploading task fetching the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *chatDatabasePath = [documentsDirectory stringByAppendingPathComponent:#"ChatDB.sqlite"];
NSString *contactDatabasePath = [documentsDirectory stringByAppendingPathComponent:#"ContactDB.sqlite"];
NSURL*ChatDB_url = [NSURL fileURLWithPath:chatDatabasePath];
NSURL*ContactDB_url = [NSURL fileURLWithPath:contactDatabasePath];
self.ChatDBData = [NSData dataWithContentsOfURL:ChatDB_url];
self.ContactDBData = [NSData dataWithContentsOfURL:ContactDB_url];
Uploading
-(void)UploadDbToServer:(NSData*)DB_Data ForDbName:(NSString*)dbName forExtension:(NSString*)extension andCallback:(void (^)(id))callback{
NSString *urlString = [[NSString alloc]initWithString:[NSString stringWithFormat:#"%#chat-backup-upload",baseUrl]];
urlString=[urlString stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:100];
[request setHTTPMethod:#"POST"];
NSString *boundary = #"7MA4YWxkTrZu0gW";
// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request setValue:contentType forHTTPHeaderField: #"Content-Type"];
// post body
NSMutableData *body = [NSMutableData data];
// add DB data
if (DB_Data) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"DB\"; filename=\"%#.%#\"\r\n",dbName,extension] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: file/sqlite\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:DB_Data];
[body appendData:[[NSString stringWithFormat:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
NSURLSessionConfiguration *sessionConf = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConf];
NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
id jsonResponse= [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
callback ((id) jsonResponse);
}];
[task resume];}
Downloading
(void)startDownload:(NSURL*)url {
NSURL *Url= [NSURL URLWithString:[NSString stringWithFormat:#"%#",url]];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue setMaxConcurrentOperationCount:5];
self.activeUrlString=[NSString stringWithFormat:#"%#",Url];
if (!self.session) {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:#"image"];
self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:queue];
}
NSURLRequest* request = [NSURLRequest requestWithURL:Url];
self.task = [self.session downloadTaskWithRequest:request];
[self.task resume];}
Writing the downloaded file
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
//saving the files
NSData *DBData = [NSData dataWithContentsOfURL:location];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *chatDatabasePath = [documentsDirectory stringByAppendingPathComponent:#"ChatDB.sqlite"];
NSString *contactDatabasePath = [documentsDirectory stringByAppendingPathComponent:#"ContactDB.sqlite"];
if ([self.activeDownload isEqualToString:#"chat"]){
[DBData writeToFile:chatDatabasePath atomically:YES];
self.activeDownload = #"contact";
[self startDownload:[NSURL URLWithString:[NSString stringWithFormat:#"%#%#",pingovaURL,self.ContactDB_URL]]];
}else{
[DBData writeToFile:contactDatabasePath atomically:YES]; }}

Can not show progress bar while uploading image to server

I desperately need to show a progress bar or an activity indicator , because image uploading takes time. Below is my code, I cannot figure it out why progress bar is not showing. I have used ProgressHUD.
[ProgressHUD show:#"Please wait..."];
NSDictionary *params =#{ #"name":self->Name.text, #"contact_no":self->ContactNo.text,#"email_id":self->EmailId.text,#"s_date":Date,#"s_time":Time,#"streat":Street,#"city":City,#"state":State};
NSData *uploadData = Data;
NSString *urlString = [NSString stringWithFormat:#"http://fsttest.com/iosservice/supremo/add_supremo"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSString *kNewLine = #"\r\n";
NSMutableData *body = [NSMutableData data];
for (NSString *name in params.allKeys) {
NSData *values = [[NSString stringWithFormat:#"%#", params[name]] dataUsingEncoding:NSUTF8StringEncoding];
[body appendData:[[NSString stringWithFormat:#"--%#%#", boundary, kNewLine] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"", name] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#%#", kNewLine, kNewLine] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:values];
[body appendData:[kNewLine dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"file_name\"; filename=\"test\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:uploadData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
choice 1
as your way continution add the delegate and check like
- (void)connection:(NSURLConnection *)connection
didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
float progress = [[NSNumber numberWithInteger:totalBytesWritten] floatValue];
float total = [[NSNumber numberWithInteger: totalBytesExpectedToWrite] floatValue];
NSLog(#"progress/total %f",progress/total);
}
choice 2
modify your request from sendSynchronousRequest to sendAsynchronousRequest for e,g
// NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
call the method like
// set URL
[request setURL:[NSURL URLWithString:baseUrl]];
// add your progress bar here
[ProgressHUD show:#"Please wait..."];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
[ProgressHUD dismiss];
if ([httpResponse statusCode] == 200) {
NSLog(#"success");
if ([data length] > 0 && error == nil)
[delegate receivedData:data];
// hide the progress bar here
}
}];
You can use AFNetworking for easily upload image. here click on AFNeworking Download. Same as your code upload images.
-(void)imageUpload
{
#try
{
[self progressViewDispaly];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager.requestSerializer setTimeoutInterval:600.0];
[manager POST:YOUR_WEB_SERVICE_NAME parameters:YOUR_REQUEST_PARA constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData)
{
for(NSString *strImageName in ImageArray) //if multiple images use image upload
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:strImageName];
if (path != nil)
{
NSData *imageData = [NSData dataWithContentsOfFile:path];
[formData appendPartWithFileData:imageData name:[NSString stringWithFormat:#"job_files[]"] fileName:[NSString stringWithFormat:#"%#",[[strImageName componentsSeparatedByString:#"/"] lastObject]] mimeType:#"image/jpeg"];
}
else
{
}
}
} progress:^(NSProgress * _Nonnull uploadProgress)
{
[self performSelectorInBackground:#selector(makeAnimation:) withObject:[NSString stringWithFormat:#"%f",uploadProgress.fractionCompleted]];
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject)
{
[SVProgressHUD dismiss];
[_progressView removeFromSuperview];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
} #catch (NSException *exception)
{
NSLog(#"%#",exception.description);
}
}
-(void)makeAnimation:(NSString *)str
{
float uploadProgress = [str floatValue];
[_progressView setProgress:uploadProgress];
}
-(void)progressViewDispaly
{
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:#"statusBarWindow"] valueForKey:#"statusBar"];
_progressView = [[UIProgressView alloc] init];//WithProgressViewStyle:UIProgressViewStyleBar];
_progressView.frame = CGRectMake(0, 0, CGRectGetWidth(statusBar.frame),20);
_progressView.backgroundColor = [UIColor blueColor];
_progressView.progressTintColor = [UIColor whiteColor];
[statusBar addSubview:_progressView];
}

Upload image to Cloudinary IOS

I can't upload images to Cloudinary hosting via HTTPS POST request, I want to use the simple API methods instead of the SDK. I'm having a problem with formatting the image in a byte array buffer or as Base64 encoded.
Here's my code:
UIImage *image = [UIImage imageNamed:#"image.png"];
NSData *imageData = UIImagePNGRepresentation(image);
NSString *strImageData = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSURL *url = [NSURL URLWithString:#"https://api.cloudinary.com/v1_1/MYSECTER/image/upload"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = #"POST";
NSString *strRequest = [NSString stringWithFormat:#"file=%#&upload_preset=MYSECTER", strImageData];
request.HTTPBody = [strRequest dataUsingEncoding:NSUTF8StringEncoding];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *recievedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSLog(#"RECEIVED: %#", recievedData);
}] resume];
Unfortunately I receive the following answer from the server: "Unsupported source URL..."
I really tried a lot of other methods, but I can't get it to work.
UPDATE: When I put URL link at 'file' param all works fine.
I don't have any experience with the Cloudinary API but I hope this is helpful. I had a look at the docs on 'Uploading with a direct call to the API'.
I think you are required to provide the 'file' and 'upload_preset' as POST parameters (not concatenated as data in the body).
UIImage *image = [UIImage imageNamed:#"image.png"];
NSData *imageData = UIImagePNGRepresentation(image);
NSString *strImageData = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSURL *url = [NSURL URLWithString:#"https://api.cloudinary.com/v1_1/MYSECTER/image/upload"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = #"POST";
// Replace this:
//NSString *strRequest = [NSString stringWithFormat:#"file=%#&upload_preset=MYSECTER", strImageData];
//request.HTTPBody = [strRequest dataUsingEncoding:NSUTF8StringEncoding];
// With this:
NSString *imageDataStr = [[NSString alloc] initWithData:imageData encoding:NSUTF8StringEncoding];
[request setValue:imageDataStr forHTTPHeaderField:#"file"];
[request setValue:#"MYSECTER" forHTTPHeaderField:#"upload_preset"];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *recievedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSLog(#"RECEIVED: %#", recievedData);
}] resume];
You can use Cloudinary's SDK in order to perform an upload image task as explained here: http://cloudinary.com/blog/direct_upload_made_easy_from_browser_or_mobile_app_to_the_cloud
The following code samples show a direct unsigned upload API call in Objective-C for iOS...:
CLCloudinary *cloudinary = [[CLCloudinary alloc] init];
[cloudinary.config setValue:#"demo" forKey:#"cloud_name"];
NSString *imageFilePath = [[NSBundle mainBundle] pathForResource:#"logo"
ofType:#"png"];
CLUploader* uploader = [[CLUploader alloc] init:cloudinary delegate:self];
[uploader unsignedUpload:imageFilePath uploadPreset:#"zcudy0uz" options:#{}];
The following code samples show a more advanced example: specifying a custom public ID of user_sample_image_1002, making it possible to later access the uploaded image, and assigning a tag to simplify management of the images. In addition, we show an example of building a dynamic URL that performs an on-the-fly image manipulation: generating a 150x100 face-detection-based thumbnail of the uploaded images for embedding in your application.
NSData *imageData = [NSData dataWithContentsOfFile:imageFilePath];
[uploader unsignedUpload:imageData uploadPreset:#"zcudy0uz" options:
[NSDictionary dictionaryWithObjectsAndKeys:#"user_sample_image_1002",
#"public_id", #"tags", #"ios_upload", nil] withCompletion:^(NSDictionary
*successResult, NSString *errorResult, NSInteger code, id context) {
if (successResult) {
NSString* publicId = [successResult valueForKey:#"public_id"];
NSLog(#"Upload success. Public ID=%#, Full result=%#", publicId,
successResult);
CLTransformation *transformation = [CLTransformation transformation];
[transformation setWidthWithInt: 150];
[transformation setHeightWithInt: 100];
[transformation setCrop: #"fill"];
[transformation setGravity:#"face"];
NSLog(#"Result: %#", [cloudinary url:publicId
options:#{#"transformation":
transformation, #"format": #"jpg"}]);
} else {
NSLog(#"Upload error: %#, %d", errorResult, code);
}
} andProgress:^(NSInteger bytesWritten, NSInteger totalBytesWritten,
NSInteger totalBytesExpectedToWrite, id context) {
NSLog(#"Upload progress: %d/%d (+%d)", totalBytesWritten,
totalBytesExpectedToWrite, bytesWritten);
}];
I found solution, and it works very good:
// image for sending
UIImage *image = [UIImage imageNamed:#"image.png"];
// Dictionary that holds post parameters. You can set your post parameters that your server accepts or programmed to accept.
NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
[_params setObject:#"SECKET_PRESET" forKey:#"upload_preset"];
// the boundary string : a random string, that will not repeat in post data, to separate post data fields.
NSString *BoundaryConstant = #"----------V2ymHFg03ehbqgZCaKO6jy";
// string constant for the post parameter 'file'. My server uses this name: `file`. Your's may differ
NSString* FileParamConstant = #"file";
// the server url to which the image (or the media) is uploaded. Use your server url here
NSURL* requestURL = [NSURL URLWithString:#"https://api.cloudinary.com/v1_1/SECKET_KEY/image/upload"];
// create request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:#"POST"];
// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", BoundaryConstant];
[request setValue:contentType forHTTPHeaderField: #"Content-Type"];
// post body
NSMutableData *body = [NSMutableData data];
// add params (all params are strings)
for (NSString *param in _params) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
// add image data
NSData *imageData = UIImagePNGRepresentation(image);
if (imageData) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"; filename=\"image.jpg\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
[body appendData:[[NSString stringWithFormat:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
// set the content-length
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[body length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
// set URL
[request setURL:requestURL];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *recievedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSLog(#"RECEIVED: %#", recievedData);
}] resume];

upload picked image in objective-c

I'm new to objective-c. I need the image picked in the first function to be uploaded in the second one:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (IBAction)uploadPic:(UIButton *)sender {
// COnvert Image to NSData
NSData *dataImage = UIImageJPEGRepresentation([UIImage imageNamed:#"yourImage"], 1.0f);
//added after editing
// set your URL Where to Upload Image
NSString *urlString = #"http://url";
// set your Image Name
NSString *filename = #"uploaded_file";
// Create 'POST' MutableRequest with Data and Other Image Attachment.
NSMutableURLRequest* request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *postbody = [NSMutableData data];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#.jpg\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[NSData dataWithData:dataImage]];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postbody];
// Get Response of Your Request
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"Response %#",responseString);
//end editing
}
The added code, in btween editing comments, is the one that I use to upload the image
You should use neither UIImageJPEGRepresentation nor UIImagePNGRepresentation. Those will lose the image's meta-data, make the file larger (or if you choose a JPEG compression factor to make the NSData smaller, it will degrade the image), etc.
I'd suggest that you save the UIImagePickerControllerReferenceURL and, then, when the user chooses to save the image, that you go back to the Photos framework and retrieve the underlying NSData of the image.
So, make sure to import the Photos framework:
#import Photos;
Also, define a property to capture the URL:
#property (nonatomic, strong) NSURL *imageReferenceURL;
And then capture this URL when you get the image:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
self.imageReferenceURL = info[UIImagePickerControllerReferenceURL];
[picker dismissViewControllerAnimated:YES completion:nil];
}
And when you go to upload the picture, retrieve the original asset's NSData from the Photos framework:
- (IBAction)uploadPic:(UIButton *)sender {
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:#[self.imageReferenceURL] options:nil];
PHAsset *asset = [result firstObject];
if (asset) {
PHImageManager *manager = [PHImageManager defaultManager];
[manager requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
// insert your code for uploading here, referencing the `imageData` here rather than `dataImage`.
// Or, I might recommend AFNetworking:
//
// For example, if your web service was expecting a `multipart/form-data` POST and was
// going to return a JSON response, you could do something like:
NSString *urlString = #"http://192.168.0.10/udazz/2.0/2.2/ios/1.0/actions.php?targ=user&subTarg=post&txtComment=123456&txtType=ff";
NSDictionary *parameters = #{#"targ" : #"user",
#"subTarg" : #"post",
#"txtComment" : #"123456",
#"txtType" : #"ff"};
NSURL *fileURL = info[#"PHImageFileURLKey"];
NSString *filename = [fileURL lastPathComponent];
NSString *mimeType = [self mimeTypeForPath:filename];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // if response is string rather than JSON, uncomment this line
[manager POST:urlString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"userfile" fileName:filename mimeType:mimeType];
} success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(#"responseObject = %#", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"error = %#", error);
}];
}];
}
}
Or, if you want to use your own upload code, just adjust it to use NSURLSession (because NSURLConnection is now deprecated and you should never do synchronous network requests, anyway):
- (IBAction)uploadPic:(UIButton *)sender {
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:#[self.imageReferenceURL] options:nil];
PHAsset *asset = [result firstObject];
if (asset) {
PHImageManager *manager = [PHImageManager defaultManager];
[manager requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
// upload the `imageData`
NSURL *fileURL = info[#"PHImageFileURLKey"];
NSString *filename = [fileURL lastPathComponent];
NSString *mimeType = [self mimeTypeForPath:filename];
NSString *urlString = #"http://192.168.0.10/udazz/2.0/2.2/ios/1.0/actions.php?targ=user&subTarg=post&txtComment=123456&txtType=ff";
NSMutableURLRequest* request= [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *postbody = [NSMutableData data];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Type: %#\r\n\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:imageData];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:postbody completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response %#",responseString);
}];
[task resume];
}];
}
}
By the way, my routine for programmatically determining the mime-type (because you really can't just assume the image is a JPEG; it could be a PNG, amongst other types, too) is as follows:
- (NSString *)mimeTypeForPath:(NSString *)path {
// get a mime type for an extension using MobileCoreServices.framework
CFStringRef extension = (__bridge CFStringRef)[path pathExtension];
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension, NULL);
assert(UTI != NULL);
NSString *mimetype = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType));
assert(mimetype != NULL);
CFRelease(UTI);
return mimetype;
}
If you need to support iOS versions that predate the Photos framework, then use the ALAssetsLibrary to get the NSData. If you need example of how to do that (only if you need to support iOS versions before 8.0), let me know.
You are assigning the picked image to your imageView. So you can access it using the image property of that UIImageView.
You can access like:
- (IBAction)uploadPic:(UIButton *)sender
{
NSData *dataImage = UIImageJPEGRepresentation(self.imageView.image, 1.0f);
// Do your stuff here
}
I have done your requirement in my demo project. I have picked image using UIIMagePicker delegate function
#interface ViewController ()
{
UIImage *chooseImage;
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSDate *time = [NSDate date];
NSDateFormatter* df = [NSDateFormatter new];
[df setDateFormat:#"ddMMyyyy-hhmmss"];
NSString *timeString = [df stringFromDate:time];
NSString *fileName = [NSString stringWithFormat:#"%#", timeString];
chooseImage = info[UIImagePickerControllerEditedImage];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectoryPath = [paths objectAtIndex:0];
NSLog(#"View Controller Path:%#",documentsDirectoryPath);
savedImagePath = [documentsDirectoryPath
stringByAppendingPathComponent:[NSString stringWithFormat: #"%#-%d.png", fileName, num]];
num += 1;
NSData *imageData = UIImagePNGRepresentation(chooseImage);
[imageData writeToFile:savedImagePath atomically:NO];
[picker dismissViewControllerAnimated:YES completion:NULL];
[self displayImage];
}
-(void)displayImage
{
self.imageView.image = chooseImage;
}
and from that method i have called another function->displayImage, which i am using for displaying image in UIImageView. Here below is code.

Resources