objective-c,How to send file as a parameter - ios

I want to upload my image from my phone gallery to the server so I am not able to upload my program ,it runs successfully and shows print -
NSLog(#">>>>>>>>>> enter in ");
but it could not upload image on the server ,when I checked it in the app then there is no image ,and I also checked parameter, I think I am not sending proper file format in the parameter.
Please can anyone help me with proper file formate how to convert it
`
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)img
editingInfo:(NSDictionary *)editingInfo
{
[picker dismissModalViewControllerAnimated:YES];
NSURL *imagePath = [editingInfo objectForKey:#"UIImagePickerControllerReferenceURL"];
imageName = [imagePath lastPathComponent];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
localFilePath = [documentsDirectory stringByAppendingPathComponent:imageName];
NSLog(#"localFilePath.%#",localFilePath);
}
- (IBAction)submitBtn:(id)sender
{
NSURL* url;
url = [NSURL URLWithString:UrlBasic];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:url];
manager.requestSerializer = [AFJSONRequestSerializer serializerWithWritingOptions:NSJSONWritingPrettyPrinted];
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:#"text/html"];
fileURL = [NSURL fileURLWithPath:localFilePath];
reqData=[[NSMutableDictionary alloc]initWithObjectsAndKeys:imageName1,#"image",#"addclassphotoactmobs",#"droot",schoolFolderA,#"schoolfolder",_choseGalleryTextF.text,#"gname",dividNum,#"classid",fileURL,#"uploadedfile",nil];
NSLog(#"reqData=%#",reqData);
[manager POST:UrlBasic parameters:reqData constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { }
progress:nil
success:^(NSURLSessionTask *task, NSMutableDictionary *responseObject) {
NSLog(#" %#",responseObject);
NSLog(#">>>>>>>>>> enter in ");
[self.view makeToast:#"submitted ....."
duration:3.0
position:CSToastPositionCenter];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"error-=%#",error);
// [self.view makeToast:#"Please check internet connection !"];
}];
}

[Updated with imageNameStr]
While uploading your image data, it is necessary to send Name of the file.To generate a file Name, Here I've used Date and time.
Add the Code below the Line NSLog(#"reqData=%#",reqData);
====================
You have missed the formData Code.
Where as the image is the actual image in the below code.
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"yyyyMMddhhmmssSSS"];
NSString *imageNameStr = [NSString stringWithFormat:#"%#.jpg",[formatter stringFromDate:[NSDate date]]];
[sessionManager POST:appendURL
parameters:postParamDict
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
if(image!=nil){
NSData * imageData = UIImageJPEGRepresentation(image,0.5f);
if(imageData!=nil){
[formData appendPartWithFileData:imageData
name:#"image"
fileName:imageNameStr
mimeType:#"image/jpg"];
}
}
}
progress:^(NSProgress * _Nonnull uploadProgress) {
}
success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) {
NSLog(#"%#",responseObject);
if(success)
success (responseObject);
}
failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(#"error %#",error);
if(failure)
failure (error);
}]

Related

Passing NSData to web service along with NSDictionary Parameter

I have all the AFNetworking Services written in Separate web service classe. upto now i have been doing it fine passing NSDictionary parameters. but now i got a problem when i need to pass NSData file to web service.
Here how im performing web service
NSData *imageData = UIImageJPEGRepresentation(self.profileImg.image, 0.5); // I need to pass this imageData
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSString *stringFromDate = [dateFormatter stringFromDate:[NSDate date]];
//Encrypting Password
NSString *passwordString = _password.text;
NSString *passwordMD5 = [passwordString MD5String];
NSDictionary *params = #{#"username": _username.text,
#"password": passwordMD5,
#"email": _email.text,
#"date":stringFromDate};
WebService *serviceObj = [[WebService alloc] init];
serviceObj.delegate = self;
[serviceObj performSelectorInBackground:#selector(doRegister:) withObject:params];
Here how i have written web service
NSMutableDictionary * parameters = [[NSMutableDictionary alloc]initWithDictionary:params];
NSURL *baseURL = [NSURL URLWithString:#"http://www.example.com/register.php"];
AFHTTPSessionManager * manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:#"" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
[formData appendPartWithFileData:imageData name:#"image" fileName:#"profile.png" mimeType:#"image/png"];
} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
[delegate didReceiveRegisterResponse:responseObject];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
but i dont know how to assign that imagedata now.
I Have done it passing NSData and NSDictionary inside array. like below
[self performSelectorInBackground:#selector(reloadPage:)
withObject:[NSArray arrayWithObjects:pageIndex,firstCase,nil] ];
- (void) reloadPage: (NSArray *) args {
NSString *pageIndex = [args objectAtIndex:0];
NSString *firstCase = [args objectAtIndex:1];
}
Got the answer from this question

How to return an NSArray in the success block, iOS, Objective-C

this is my code. I want to return an array with data after data assign from the web service to the array.I have use block to check.
this is from my header file...
typedef void(^FailureBlock)(NSError *error);
typedef void(^SuccessBlock) (NSMutableArray *responseArray);
this is my implementation file ....
- (void)setupConnectionWithsuccess:(SuccessBlock)success failure:(FailureBlock)failure
{
airportArray = nil;
NSString *airportCode = [NSString stringWithFormat:#"some code"];
NSString *authenticationCode = [NSString stringWithFormat:#"some api"];
NSString *baseurl = [NSString stringWithFormat:#"some url",authenticationCode,airportCode];
// NSString *mainurlString = [NSString stringWithFormat:#""];
// NSURL *mainurl = [NSURL URLWithString:mainurlString];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:baseurl parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSArray *mainArray = (NSArray *)responseObject;
airportArray = [[NSMutableArray alloc] init];
for (NSDictionary *all in mainArray) {
airports = [all objectForKey:#"Airport"];
[airportArray addObject:airports];
NSLog(#"%#", airports);
}
if(success){
success(airportArray);
}
//NSLog(#"%#", responseObject);
}
failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) {
failure(error);
}
UIAlertController *mainAlert = [UIAlertController alertControllerWithTitle:#"Something Wrong!" message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:mainAlert animated:YES completion:nil];
}];
}
then after success, I want to return the array from this method.how can I do that
- (NSArray *)returnAll
{
[self setupConnectionWithsuccess:^(NSMutableArray *responseArray) {
} failure:^(NSError *error) {
}];
}
please help me with this.I'm new to iOS Block.
Try as follow here i use id because in id you can pass anyobject
- (void)setupConnectionWithsuccess:(void (^)(id responseObject, NSError *error))completion{
airportArray = nil;
NSString *airportCode = [NSString stringWithFormat:#"some code"];
NSString *authenticationCode = [NSString stringWithFormat:#"some api"];
NSString *baseurl = [NSString stringWithFormat:#"some url",authenticationCode,airportCode];
// NSString *mainurlString = [NSString stringWithFormat:#""];
// NSURL *mainurl = [NSURL URLWithString:mainurlString];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:baseurl parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSArray *mainArray = (NSArray *)responseObject;
airportArray = [[NSMutableArray alloc] init];
for (NSDictionary *all in mainArray) {
airports = [all objectForKey:#"Airport"];
[airportArray addObject:airports];
NSLog(#"%#", airports);
}
if (completion)
completion(responseObject,nil);
//NSLog(#"%#", responseObject);
}
failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (completion)
completion(nil,error);
UIAlertController *mainAlert = [UIAlertController alertControllerWithTitle:#"Something Wrong!" message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:mainAlert animated:YES completion:nil];
}];}
and to call it
[self setupConnectionWithsuccess:^(id responseObject, NSError *error) {
if (responseObject) {
NSLog(#"responsceObect");
}
}];
It get nothing while your function return. Because your block excute at asynchonize way. you should modify your function to handle the Array data in a block.

Couldn't save data in given path of document directory by NSOutputStream

How to save downloaded content/data in the given path in document directory by NSOutputStream. If i append file name with DD then it works (ex- DD/contentPath.zip), But if i append a path like DD/hello/contentPath.zip then it doesn't work. Why ? I tried like below -
- (void) downloadCarContents:(NSString *)url forContent:(NSString *)contentPath {
//NSString *destinationPath = [self.documentDirectory getDownloadContentPath:contentPath];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *op = [manager GET:url
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//NSLog(#"Error : %#", error.localizedDescription);
}];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *dest = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"hello/%#.zip", contentPath]];// It doesn't work
//NSString *dest = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.zip", contentPath]];// It works
op.outputStream = [NSOutputStream outputStreamToFileAtPath:dest append:NO];
[op setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
float percentage = (float) (totalBytesRead * 100) / totalBytesExpectedToRead;
[self.delegate downloadProgression:percentage];
}];
}
The API doesn't create the folder for you. Your code needs to ensure it exists before you try to use it. NSFileManager can help with createDirectoryAtPath:withIntermediateDirectories:attributes:error:

POST with URL parameters and JSON body in AFNetworking

I'd like to make a POST call that has both URL parameters and a JSON body:
URL http://example.com/register?apikey=mykey
JSON { "field" : "value"}
How can I use two different serializers at the same time with AFNNetworking? Here's my code with the URL parameters missing:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:#"http://example.com/register" parameters:json success:^(AFHTTPRequestOperation *operation, id responseObject) {
I make a post method
/**
* Services gateway
* Method get response from server
* #parameter -> object: request josn object ,apiName: api endpoint
* #returm -> void
* #compilationHandler -> success: status of api, response: respose from server, error: error handling
*/
+ (void)getDataWithObject:(NSDictionary *)object onAPI:(NSString *)apiName withController:(UIViewController*)controller
:(void(^)(BOOL success,id response,NSError *error))compilationHandler {
controller = controller;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
// set request type to json
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// post request to server
[manager POST:apiName parameters:object success:^(AFHTTPRequestOperation *operation, id responseObject) {
// NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseObject
options:0
error:&error];
//NSString *JSONString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
////
// check the status of API
NSDictionary *dict = responseObject;
NSString *statusOfApi = [[NSString alloc]initWithFormat:#"%#"
,[dict objectForKey:#"OK"]];
// IF Status is OK -> 1 so complete the handler
if ([statusOfApi isEqualToString:#"1"] ) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
compilationHandler(TRUE,responseObject,nil);
} else {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSArray *errorMessages = [responseObject objectForKey:#"messages"];
NSString *message = [errorMessages objectAtIndex:0];
[Utilities showAlertViewWithTitle:apiName message:message];
compilationHandler(FALSE,responseObject,nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSString *message = [NSString stringWithFormat:#"%#",[error localizedDescription]];
NSLog(#"Message is %#", message);
NSString *errorMessage = [NSString stringWithFormat:#"%#",[error localizedDescription]];
if (!([message rangeOfString:#"The request timed out."].location == NSNotFound)) {
[Utilities showAlertViewWithTitle:apiName message:errorMessage];
}
compilationHandler(FALSE,errorMessage,nil);
}];
// For internet reachibility check if changes its state
[self checkInternetReachibility:manager];
}
**for Example when we call the Service **
// calling service gateway API
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
"field",#"value",
nil];
[self getDataWithObject:dict onAPI:KGet_Preferences withController:(UIViewController*)controller :^(BOOL success, id response, NSError *error) {
if( success ) {
NSMutableDictionary *data = [[response valueForKey:#"data"] valueForKey:#"preferences"];
compilationHandler(success,data,error);
} else {
compilationHandler(success,nil,error);
}
}];
I believe there is no automatic way of doing it. However, there is a simple way of achieving it manually:
- (NSMutableURLRequest *)someRequestWithBaseURL:(NSString *)baseUrl
method:(NSString *)method
path:(NSString *)path
uriParameters:(NSDictionary *)uriParameters
bodyParameters:(NSDictionary *)bodyParameters
NSURL *url = [NSURL URLWithString:path relativeToURL:[NSURL URLWithString:baseUrl]];
AFHTTPRequestSerializer *httpRequestSerializer = [AFJSONRequestSerializer serializerWithWritingOptions:0]
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:bodyParameters];
if ([httpRequestSerializer.HTTPMethodsEncodingParametersInURI containsObject:method]) {
[parameters addEntriesFromDictionary:uriParameters];
} else {
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
// For urlEncodedString, check http://stackoverflow.com/a/718480/856549
urlComponents.percentEncodedQuery = [uriParameters urlEncodedString];
url = [urlComponents URL];
}
NSError *error;
NSURLRequest *request = [httpRequestSerializer requestWithMethod:method
URLString:[url absoluteString]
parameters:parameters
error:&error];

AFNetworking not uploading image

I am trying to upload an image via AFnetworking. I am able to get the image url, and it does contact my server. However, it won't upload. The file upload folder is empty and when I get back my JSON response, it is "null"
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Request to save the image to camera roll
[library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
NSLog(#"error");
} else {
NSLog(#"url %#", assetURL);
NSData *data = [NSData dataWithContentsOfURL:assetURL];
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
path = [path stringByAppendingString:#"/image.jpg"];
[data writeToFile:path atomically:YES];
[self uploadPhoto:path];
// NSLog(path);
[self dismissModalViewControllerAnimated:NO];
}
}];
}
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"foo": self.targetid};
NSURL *filePath = [NSURL fileURLWithPath:file];
[manager POST:#"http:/****/uploadpics.php" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:filePath name:#"image" error:nil];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
image url looks like this:
/var/mobile/Applications/FFCAE923-1115-4209-AB39-D9D1ACEB9CB7/Documents/yourLocalImage.png
I can't seem to figure out what am I doing wrong.. The script is fine because it works for android just as it is supposed to...
PHP:
$name = $_FILES['filename']['name'];
if (is_uploaded_file($_FILES['filename']['tmp_name'])){
if (move_uploaded_file($_FILES['filename']['tmp_name'], $folder.$_FILES ['filename'] ['name'])) {
Echo $foname;
} else {
}
} else {
}
Your upload code names the file image but your script seems to expect filename. I haven't done any php for a while but I think they should match.
There is another method which allows you to specify more details about the part that you're appending to the form data so you probably need that to set the appropriate names.

Resources