I am starting to grow grey hairs here:-)
I have this code, which was based from an image upload - which there are so many of on the web, but I need it to upload a .json file - the file generates correctly to appear in my Documents Directory, but I need it to be uploaded to my server.
_myJSON= [NSMutableString stringWithFormat:#"{ \" %# \" : [ ", _menuCategoryPickerFld.text];
[_myJSON appendString: [NSString stringWithFormat: #"{ \"name\" : \"%#\", \"model\" : \"%#\", \"size\" : \"%#\" }",
_menuTitlePickerFld.text, _menuSubTitlePickerFld.text, _menuPricePickerFld.text]];
[_myJSON appendString: #" ]}"];
NSData *data = [_myJSON dataUsingEncoding:NSUTF8StringEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"testJSON2.json"];
[data writeToFile:appFile atomically:YES];
NSString *tempString = #"http://thepalmsmarket.co.nz/jsonExports/uploads/";
NSURL *remoteURL = [NSURL URLWithString:tempString];
// Back to NSData
NSData *convertedFile = [_myJSON dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:remoteURL];
[request setHTTPMethod: #"POST"];
[request setHTTPBody:convertedFile];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite)
{
}];
[operation start];
Ok so I think some of the formatting is wrong, but also for files to be uploaded don't I need to add the username and password of my web-server in my app somewhere, so it can be authenticated for the upload??
Related
I have a problem while trying to session.dataTaskWithRequest in a function to read gzip from URL.
The server side changes .gzip to .bin and stores the file.
I want to read the file with .bin. However, The network connection was lost.
However, a The network connection was lost error will occur.
Could you tell me how to solve this problem?
Server side file name: xxx.bin (this bin file is a gzip file.)
Following the code:
NSURLSessionConfiguration *config = [NSURLSessionConfiguration
defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURL *url = [NSURL URLWithString:#"http://...../xxx.bin"];
NSURLSessionDataTask *task = [session dataTaskWithURL: url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"error [%#]", [error localizedDescription]);
}
else {
NSLog(#"success");
}
}];
[task resume];
You can try two steps of codes to download and extract zip files.
//Fetching zip file from server
-(void)dataSyncFileDonload{
NSString *stringURL = [NSString stringWithFormat:#"http://yourzipfilecontainedURL"];
stringURL = [stringURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
[self extractDownloadedZipFile:urlData];
}
//File Extraction from Zip file
-(void)extractDownloadedZipFile:(NSData *)data {
//If you are using SQlite and storing in local directory for extraction
NSData *outputData = [data gunzippedData];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *dataPath = [path stringByAppendingPathComponent:#"myAppDB.sql"];
NSString *dataPath1 = [path stringByAppendingPathComponent:#"myAppDB.sql.gz"];
dataPath = [dataPath stringByStandardizingPath];
[outputData writeToFile:dataPath atomically:YES];
[data writeToFile:dataPath1 atomically:YES];
[self readExtractedFile:dataPath];
}
//Read upzip file
-(void)readExtractedFile:(NSString *)filepath loaderPercent:(float)loaderPercent loaderTo:(float)loaderTo{
NSData *fileData = [NSData dataWithContentsOfFile:filepath];//destinationPath
NSString *fileString = [[NSString alloc] initWithData:fileData encoding:NSASCIIStringEncoding];
NSArray* allLinedStrings = [fileString componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]];
//You can use you data now.
}
Here is what I have tried so far:
-(void)postMethod_Param
{
NSString *urlString=#"http://192.168.1.139:49/api//Grievance/PostCreateRequest";
NSString *bodydata =[NSString stringWithFormat:#"&user_fb_id=%#&status=%d",fbUserId,status];
}
If you want to post data to server
Pick Image from Gallery and save it to array
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image=[info objectForKey:#"UIImagePickerControllerOriginalImage"];
imageView.image=image;
[arrayImage addObject:image];
picker.delegate =self;
[picker dismissViewControllerAnimated:YES completion:nil];
}
For saving image as path and also convert into path as string
for (UIImage *img in array_Image)
{
int i=0;
NSString *pathName =nil;
NSString *file_name = [[self getCurrentDate]stringByAppendingString:[self getCurrentTime]];
file_name =[file_name stringByAppendingPathExtension:#"jpeg"];
NSArray *paths1 =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath =([paths1 count] >i) ? [paths1 objectAtIndex:i] : nil;
NSString *path = [basePath stringByAppendingPathComponent:#"Photo"];
//Get Directory in FileManager
NSFileManager *fileManager =[NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:path])
return;
[fileManager createDirectoryAtPath:path withIntermediateDirectories:NO attributes:nil error:nil];
pathName =[path stringByAppendingPathComponent:file_name];
NSData *imgData =UIImageJPEGRepresentation(image, 0.4);
[imgData writeToFile:pathName atomically:YES];
[arryImagePath addObject:pathName];
}
I Call the below methods in file_name
+(NSString*)getCurrentTime
{
//Get Current Time for saving Images
NSString *path =nil;
NSDateFormatter *timeFormatter =[[NSDateFormatter alloc]init];
[timeFormatter setDateFormat:#"HH:mm:ss.SSS"];
NSDate *now = [[NSDate alloc]init];
NSString *str_time = [timeFormatter stringFromDate:now];
NSString *curr_time;
curr_time =[str_time stringByReplacingOccurrencesOfString:#"." withString:#""];
path = [NSString stringWithFormat:#"%#",curr_time];
return path;
}
+(NSString*)getCurrentDate
{
NSString *today =nil;
NSDateFormatter *dateFormatter1;
dateFormatter1 =[[NSDateFormatter alloc]init];
[dateFormatter1 setDateFormat:#"d MMM yyyy"];
NSDate *now =[[NSDate alloc]init];
NSLocale *usLocale =[[NSLocale alloc]initWithLocaleIdentifier:#"en_US"];
[dateFormatter1 setLocale:usLocale];
NSString *str_date =[dateFormatter1 stringFromDate:now];
today=[NSString stringWithFormat:#"%#",str_date];
return today;
}
In above code If you print the arryImagePath you can see the image path.Before that you need to allocate and initialize the arryImagePath and array_image.
For Posting data into Server
NSURL *url = [NSURL URLWithString:urlString];
NSString *output = [NSString stringWithContentsOfURL:url encoding:0 error:&error];
NSLog(#"%#",output);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[postData dataUsingEncoding:NSUTF8StringEncoding]];
NSData *strJsondata=[NSData dataWithBytes:[output UTF8String] length:[output length]];
//If the response is dictionary......
NSDictionary *responseDict = strJsondata ? [NSJSONSerialization JSONObjectWithData:strJsondata options:0 error:&error] : nil;
To upload a file on server you need to make a multipart request which I suggest you to use AFNetworking to do that !
In case you need some multipart example using AFNetworking you can see this or (Upload an image with AFNetworking 2.0) link.
Hope this links could help you.
Update
: To upload Image and Voice on server you need to convert them into data file, his is how you can convert image to data and upload it on server :
NSData *imageData = UIImageJPEGRepresentation(selectedImage, 1.0f);
Then you need to make a request :
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:stringURL parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// If you have image you need to do this :
NSString *fileName = #"Some name";
if (imageData) [formData appendPartWithFileData:imageData name:#"photo" fileName:fileName mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Everything is ok
NSLog(#"Success (%d): %#\n\n", (int) operation.response.statusCode, responseObject);
if (success) success(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Ops ! we have error
NSLog(#"Failure (%d): %#\n\n", (int) operation.response.statusCode, [error localizedDescription]);
if (failure) failure(nil);
}];
Important : pay attention on mime Type and name , they must be the same name and type requested by server.
I am writing all the NSLOG's to a text file and post it to the server on click of a table view cell . I convert the text file to zip file before I post it using NSURLConnection . However , There is Some garbage data present inside the Zip file posted , But the text file has the correct content. I am using SSZipArchive, The code that I use to post the file is
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"Logger.txt"]];
NSString* zipfile = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"Logger.zip"]];
//create zip file, return true on success
BOOL isZipCreated=[SSZipArchive createZipFileAtPath:zipfile withContentsOfDirectory:logFilePath];
if (isZipCreated) {
NSLog(#"Zip file Created at Path : %#",zipfile);
NSString *contentOfZipFile = [NSString stringWithContentsOfFile:zipfile encoding:NSUTF8StringEncoding error:NULL];
NSData *zipData = [contentOfZipFile dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[zipData length]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:finalURL]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/zip" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:zipData ];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
}
else {
NSLog(#"Zip create error");
}
Any assistance would be of great help.
You can use this library Objective-Zip, actually I have used this and its working fine for me.
Creating a Zip File:
ZipFile *zipFile= [[ZipFile alloc] initWithFileName:#"Logger.zip" mode:ZipFileModeCreate];
Adding a file to a zip file
ZipWriteStream *stream= [zipFile writeFileInZipWithName:#"Logger.txt" compressionLevel:ZipCompressionLevelBest];
[stream writeData:abcData];
[stream finishedWriting];
Reading a file from a zip file:
ZipFile *unzipFile= [[ZipFile alloc] initWithFileName:#"Logger.zip" mode:ZipFileModeUnzip];
[unzipFile goToFirstFileInZip];
ZipReadStream *read= [unzipFile readCurrentFileInZip];
NSMutableData *data= [[NSMutableData alloc] initWithLength:256];
int bytesRead= [read readDataWithBuffer:data];
[read finishedReading];
Hope this code will help you :)
Happy Coding!! ;)
I have a text file in which I write all the NSLOG's and I post it to the server whenever required. Since I want to optimise the size of the file that is sent to the server , I want to zip the text file . I referred a lot of examples but could not clearly understand . This is my code to create the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName =[NSString stringWithFormat:#"Logger.txt"];
NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:fileName];
freopen([logFilePath cStringUsingEncoding:NSUTF8StringEncoding],"a+",stderr);
and this is the code to post the file to the server.
NSString *finalURL = [self getSupportServletURL:persist];
NSURL *url = [NSURL URLWithString:finalURL];
NSMutableURLRequest * requests = [[NSMutableURLRequest alloc]initWithURL:url];
[requests setHTTPMethod:#"POST"];
[requests setValue:#"text" forHTTPHeaderField:#"Content-type"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Logger.txt"];
NSString *content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
LogInfo(#"Data being posted to server %#",finalURL);
LogTrace(#"Post Data : Data being posted to server \n%#",content);
[requests setTimeoutInterval:60.0];
[requests setHTTPBody:[content dataUsingEncoding:NSUTF8StringEncoding]];
[requests setValue:[NSString stringWithFormat:#"%lu",(unsigned long)[content length]] forHTTPHeaderField:#"Content-Length"];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:requests delegate:self];
and this works perfectly. Can anyone help me in converting this to a zip file ( including the things that need to be included in .m file & .h file ) and posting it to the server . Thank You in advance.
Create logger file following way. I just created file in different directory instead of document directory so we can zip that directory.
//creating logger file in document directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//logger file name
NSString *fileName =[NSString stringWithFormat:#"Logger.txt"];
//we will add log file in "LogFiles" directory so we can zip that directory
NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/LogFiles/%#",fileName]];
//"LogFiles" directory path
NSString *LogFilesDirectory = [documentsDirectory stringByAppendingPathComponent:#"/LogFiles"];
NSError *error;
//create "LogFiles" directory if not created
if (![[NSFileManager defaultManager] fileExistsAtPath:LogFilesDirectory])
[[NSFileManager defaultManager] createDirectoryAtPath:LogFilesDirectory withIntermediateDirectories:NO attributes:nil error:&error];
//writing logger file
freopen([logFilePath cStringUsingEncoding:NSUTF8StringEncoding],"a+",stderr);
Now
#import "SSZipArchive.h" in viewController.m
To create zip file use following code
//getting logger.txt file path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/LogFiles"]];
NSString* zipfile = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/LogFiles/Logger.Zip"]];
//create zip file, return true on success
BOOL isZipCreated=[SSZipArchive createZipFileAtPath:zipfile withContentsOfDirectory:logFilePath];
if (isZipCreated) {
NSLog(#"Zip file Created at Path : %#",zipfile);
NSData *zipData = [NSData dataWithContentsOfFile:zipFile]; // note, autorelease object
NSString *postLength = [NSString stringWithFormat:#"%d", [zipData length]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/zip" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:zipData];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:requests delegate:self];
}
else
{
NSLog(#"Zip create error");
}
Im trying to use the API call TextGetRankedNamedEntities http://www.alchemyapi.com/api/entity/textc.html#rtext
Here is my relevant code:
NSString *data = #"Data I want analyzed";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"result.txt"];
[data writeToFile:appFile atomically:YES encoding:NSUTF8StringEncoding error:NULL];
//I have verified the data is in the file
NSString *queryString = [NSString stringWithFormat:#"http://access.alchemyapi.com/calls/text/TextGetRankedNamedEntities?apikey=MY_API_KEY&showSourceText=1"];
NSMutableURLRequest *theRequest=[NSMutableURLRequest
requestWithURL:[
NSURL URLWithString: queryString]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
//Set request method to post
[theRequest setHTTPMethod:#"POST"];
NSString *post = [NSString stringWithFormat:#"&text=%#", appFile];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding];
[theRequest setHTTPBody:postData];
my result for this request is:
<?xml version="1.0" encoding="UTF-8"?>
<results>
<status>OK</status>
<usage>By accessing AlchemyAPI or using information generated by AlchemyAPI, you are agreeing to be bound by the AlchemyAPI Terms of Use: http://www.alchemyapi.com/company/terms.html</usage>
<url></url>
<language>english</language>
<text>/var/mobile/Containers/Data/Application/6C00A4F8-4DEE-44F2-9DBF-7568CEF72054/Documents/result.txt</text>
<entities>
</entities>
</results>
It appears that the data that is being send is the file path and not that actual contents of the file.
EDIT: Solved, Leaving the question for possible feedback and best practices for using HTTTP requests in iOS as I am new to both.
Change:
NSString *post = [NSString stringWithFormat:#"&text=%#", appFile];
To:
NSString *post = [NSString stringWithFormat:#"&text=%#", data];
It didn't occur to me to try this before posting the question because I had previous tried to do this but at that point I was sending the request with the GET method not the POST method.