Post Request to alchemy API in iOS8 - ios

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.

Related

Zip file not created properly in iOS

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!! ;)

How to zip a text file and post it using NSURLConnection in objective-c

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");
}

How to store .flac file content in NSData?

In my app I have added one .flac file in my resources folder. I want to send to this .flac file to Google's speech recognition service... Below is my code:
NSURL* urlGoogle = [NSURL URLWithString:#"https://www.google.com/speech-api/v1/recognize"];
NSMutableURLRequest *urlGoogleRequest = [[NSMutableURLRequest alloc]initWithURL:urlGoogle];
[urlGoogleRequest setHTTPMethod:#"POST"];
[urlGoogleRequest addValue:#"audio/x-flac; rate=16000" forHTTPHeaderField:#"Content-Type"];
NSURLResponse* response = nil;
NSError* error = nil;
NSArray *docDirs = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [docDirs objectAtIndex:0];
NSString *path = [[docDir stringByAppendingPathComponent:#"surround88"]
stringByAppendingPathExtension:#"flac" ];
NSURL* url = [NSURL fileURLWithPath:path];
//Here I'm getting flacData value is nil
NSData *flacData = [NSData dataWithContentsOfURL:url]; //flacData = nil
[urlGoogleRequest setHTTPBody:flacData];
NSData* googleResponse = [NSURLConnection sendSynchronousRequest:urlGoogleRequest
returningResponse:&response
error:&error];
id jsonObject=[NSJSONSerialization JSONObjectWithData:googleResponse options:kNilOptions error:nil];
NSLog(#"Googles response is: %#",jsonObject);
Since I'm not sending any data to the server, I'm getting empty response.
I have tested other 3rd party apis like openears, dragon, ispeech etc and not satisfied.
Can some one help me how to proceed to further. Is this the correct way to implement google's speech recognition functionality? Any help would be appreciated.
Since you're placing the file in your resources folder, you're not going to find it with NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);. That's why [NSData dataWithContentsOfURL:url] is returning nil.
Your file is now placed in your Bundle, so try loading the file's contents with this:
NSURL *url = [[NSBundle mainBundle] URLForResource:#"surround88" withExtension:#"flac"];
NSData *flacData = [NSData dataWithContentsOfURL:url];
EDIT: based on comments bellow
Make sure the file is a member of the target you're building. In other words:
Select your .flac file
Make sure to check the boxes for the targets you're testing this with
Using the test project above, I was able to successfully create an NSData object from the .flac file.

AFNetworking - json file uploading on iOS

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??

iPhone: Error uploading audio wav bytes data to server

I am developing an iOS application. I have to send an audio file to our server programmatically. I am using the following code to send an sample wav audio file to server. Our server accepts only audio file in signed bytes array format for receiving.
NSURL *urlPath = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"Crash" ofType:#"wav"]];
NSString *wavbundlepath = [urlPath absoluteString];
NSLog(#"wavbundlepath: %#",wavbundlepath);
NSData *bytes = [wavbundlepath dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"bytes: %#",bytes);
NSString *recordPostLength = [NSString stringWithFormat:#"%d", [bytes length]];
NSMutableString *urlstr = [NSMutableString stringWithFormat:#"%#", #"http://www.mywebserver/api/UploadFile?Name="];
[urlstr appendString:#"crash"];
[urlstr appendFormat:#"&MemberID=%d", 0];
[urlstr appendFormat:#"&Type=%#",#"Recording"];
[urlstr appendFormat:#"&client=%#",#"ios"];
NSLog(#"urlstr.......%#",urlstr);
NSMutableURLRequest *recordRequest = [[NSMutableURLRequest alloc] init] ;
[recordRequest setURL:[NSURL URLWithString:urlstr]];
[recordRequest setHTTPMethod:#"POST"];
[recordRequest setValue:recordPostLength forHTTPHeaderField:#"Content-Length"];
[recordRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[recordRequest setHTTPBody:bytes];
NSURLResponse *recordResponse;
NSError *recordError;
NSData *recordResponseData = [NSURLConnection sendSynchronousRequest:recordRequest returningResponse:&recordResponse error:&recordError];
NSString *recordResp = [[NSString alloc]initWithData:recordResponseData encoding:NSUTF8StringEncoding];
NSLog(#"recordResp:%#", recordResp);
But the problem is, always receving "Input string is not correct." response error.
I am not very much aware of uploading audio bytes to server. Could someone please check this code and tell me this is valid code or not for uploading a wav audio bytes array to server?
Thank you.
UPDATED CODE
I tried below code as my server side engineer said not to have any other things post body, and it works fine and getting positive response. But, the server is not able to work with format NSData bytes (32 bit elements) what i'm sending, because server side its implemented to receive only array of bytes or signed bytes data format only.
NSURL *urlPath = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"Temp" ofType:#"wav"]];
NSString *wavbundlepath = [urlPath absoluteString];
NSLog(#"wavbundlepath: %#",wavbundlepath);
NSData *bytes=[NSData dataWithContentsOfURL:urlPath];
NSLog(#"bytes: %#",bytes);
NSString *recordPostLength = [NSString stringWithFormat:#"%d", [bytes length]];
NSMutableString *urlstr = [NSMutableString stringWithFormat:#"%#", #"http://www.myserver.com/api/UploadFile?Name="];
[urlstr appendString:#"Temp"];
[urlstr appendFormat:#"&MemberID=%d", 0];
[urlstr appendFormat:#"&Type=%#",#"Recording"];
[urlstr appendFormat:#"&client=%#",#"ios"];
NSLog(#"urlstr.......%#",urlstr);
NSMutableURLRequest *recordRequest = [[NSMutableURLRequest alloc] init] ;
[recordRequest setURL:[NSURL URLWithString:urlstr]];
NSInputStream *dataStream = [NSInputStream inputStreamWithData:bytes];
[recordRequest setHTTPBodyStream:dataStream];
[recordRequest setHTTPMethod:#"POST"];
NSURLResponse *recordResponse;
NSError *recordError;
NSData *recordResponseData = [NSURLConnection sendSynchronousRequest:recordRequest returningResponse:&recordResponse error:&recordError];
NSString *recordResp = [[NSString alloc]initWithData:recordResponseData encoding:NSUTF8StringEncoding];
NSLog(#"recordResp:%#", recordResp);
recordResponceJson = [recordResp JSONValue];
NSLog(#"recordResponceJson = %#",recordResponceJson);
recId = [recordResponceJson valueForKey:#"ID"];
NSLog(#"recId....%#", recId);
Could someone please guide me, how i can send array of bytes in this http post?
There are a couple problems:
First how you're reading the file will not return a valid WAV file:
You should use [NSData dataWithContentsOfURL:] to read the bytes. The way you're reading them it will try to convert the bytes into characters. This will corrupt your wav file.
Second, the content-type of the POST body is probably incorrect. See the line:
[recordRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
The audio bytes would not be encoded in x-www-form-urlencoded format. It is more likely that the server would accept a audio/wav or application/octet-stream content type. Check with your server developers to see exactly what the server is expecting.
Also, you may want to check out the NSMutableURLRequest method called setHTTPBodyStream: that lets you send a file without having to load the entire thing into memory.

Resources