Xcode, can't send UTF-8 Text - xcode

I am trying to send a post value to my server.
It successfully send English characters.
This code is for finding friend, and it can't send UTF-8 text.
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope{
/*
Update the filtered array based on the search text and scope.
*/
if(![searchText isEqualToString:#""]){
NSUserDefaults * userdef = [NSUserDefaults standardUserDefaults];
NSString *encodedSearchText = [searchText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString * uploadUrl = [NSString stringWithFormat:#"%#/%#" , GPON_URL , GPON_URL_SEARCHFRIEND];
NSURL *url = [NSURL URLWithString:uploadUrl];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:encodedSearchText forKey:#"u_id"];
[request setPostValue:[userdef objectForKey:KEY_USER_ID] forKey:#"s_username"];
[request startSynchronous];
[request setShouldAttemptPersistentConnection:NO];
NSString *response = [request responseString];
SBJsonParser * parser = [[[SBJsonParser alloc] init] autorelease];
NSDictionary * json = (NSDictionary *)[parser objectWithString:response];
[searchMember removeAllObjects];
if( [[json objectForKey:#"result"] isEqual:#"YES"] ){
[searchMember addObjectsFromArray:[json objectForKey:#"data"]];
[self.tableView reloadData];
}
}
}
here is my code. can you see what cause the error?

You don't appear to be setting the string encoding of the request; try:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setStringEncoding:NSUnicodeStringEncoding];
Also, this is a very poor way of determining if an NSString is empty:
if (![searchText isEqualToString:#""])
Use the length method instead:
if ([searchText length] > 0)

Related

Storing JSON response in iOS error

I am making a call to an online php from my iOS app. In my output window I see the JSON Response with the data. But I need to store the NSString in my userdefaults but it is coming up NULL.
In this code the NSLog(#"JSON Response is %#", responseData); returns the json data just fine and I see the ipixid. But in the NSLog (#"ipixid is %#", ilixid); it returns ipixid is (null)
NSString *post =[[NSString alloc] initWithFormat:#"email=%#", strValue];
NSLog(#"PostData: %#",post);
NSURL *url1=[NSURL URLWithString:#"http://www.ipixsocial.com/membership/getresult.php"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url1];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if ([response statusCode] >=200 && [response statusCode] <300)
{
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"JSON Response is %#", responseData);
SBJsonParser *jsonParser = [SBJsonParser new];
NSDictionary *jsonData = (NSDictionary *) [jsonParser objectWithString:responseData error:nil];
// NSString *username = [(NSString *) [jsonData objectForKey:#"email"]init];
NSInteger success = [(NSNumber *) [jsonData objectForKey:#"uid"] integerValue];
NSString* ipixid = [jsonData objectForKey:#"ipixid"];
[[NSUserDefaults standardUserDefaults] setObject:ipixid forKey:#"ipixid"];
NSLog (#"ipixid is %#", ipixid);
Don't ignore the "error" parameter you're passing to the parser. Also check that "jsonData" is not nil. I'm think that parsing is failing and because you're ignoring it and assuming jsonData is valid you're getting nil for [jsonData objectForKey:#"ipixid"];

NSMutableURLRequest posting a JSON object to CakePHP appears as an Array

I send JSON data from Xcode in the following way:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
#"Test title", #"title",
#"Test option1", #"option1",
#"Test option2", #"option2", nil];
NSError *error;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:dict options:kNilOptions error:&error];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSURL *url = [NSURL URLWithString:#"http://somedomain.com/posts/add"];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody:jsonData];
[NSURLConnection connectionWithRequest:request delegate:self];
I write the received data in CakePHP to a file in the following way:
public function add()
{
if ($this->request->is('post'))
if ($this->RequestHandler->requestedWith('json')) {
file_put_contents('debug.txt', print_r($this->request->data, true));
}
}
}
and the data in the file ('debug.txt') looks like this:
Array
(
[option2] => Test option2
[title] => Test title
[option1] => Test option1
)
I know that the data being sent is in JSON format and I expect the received data to appear as JSON format rather than an Array in 'debug.txt'. Is this a correct assumption and if so what is going wrong?
I'm not sure what the problem is here, before you can do anything with that data in PHP you'd have to convert it to an array anyway, it seems the CakePHP requesthandler is doing this automatically for you.
If you really want the original json just json_encode() it back again.

pass local declaration of NSDictionary to performSelector

How it do so that I will not need to put data object right in selector call method?
code with warning (Local declaration of data) :
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:#"SiluetaImage", #"ACTION", silueta_id, #"siluetaid", siluetaTyp_id, #"siluetatypid", nil];
[self performSelector:#selector(downloadBinDataForTyp:data:)
withObject:#"SiluetaImage"
withObject:data];
code without warning :
[self performSelector:#selector(downloadBinDataForTyp:data:)
withObject:#"SiluetaImage"
withObject:[NSDictionary dictionaryWithObjectsAndKeys:#"SiluetaImage", #"ACTION", silueta_id, #"siluetaid", siluetaTyp_id, #"siluetatypid", nil]];
the selector:
- (void)downloadBinDataForTyp:(NSString *)typ data:(NSDictionary*)data
{
ASINetworkQueue *q = [self queue];
NSString *sUrl = #"url_web_service";
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:sUrl]];
NSString *msgLength = [NSString stringWithFormat:#"%d", [[self getMsg] length]];
[request setTimeOutSeconds:60];
[request addRequestHeader: #"Content-Type" value:#"text/xml; charset=utf-8"];
[request addRequestHeader: #"SOAPAction" value:_action];
[request addRequestHeader: #"Content-Length" value:msgLength];
[request setRequestMethod: #"POST"];
request.userInfo = data;
[request appendPostData:[self getMsg]];
[request setDelegate:self];
[q addOperation:request];
[q go];
}
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:#"SiluetaImage", #"ACTION", silueta_id, #"siluetaid", siluetaTyp_id, #"siluetatypid", nil];
[self performSelector:#selector(downloadBinDataForTyp:data:)
withObject:#"SiluetaImage"
withObject:data];
In this you are passing data whose scope is just to the method. And outside the method it can not be accessed, as it is getting released.

ASIHttpRequest upload image

Hey i have a mac application with the following code:
NSURL *url;
url = [NSURL URLWithString:#"http://yfrog.com/api/xauth_upload"];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
[request setDelegate:self];
[request setUseCookiePersistence:NO];
[request setUploadProgressDelegate:self];
[request showAccurateProgress];
[request signRequestWithClientIdentifier:#"w" secret:#"x" tokenIdentifier:#"y" secret:#"z" usingMethod:ASIOAuthHMAC_SHA1SignatureMethod];
[request setPostValue:#"a" forKey:#"key"];
NSData *imageData = [[NSData alloc]initWithContentsOfFile:[draggedFilenames objectAtIndex:0]];
[request setPostValue:imageData forKey:#"media"];
[request startAsynchronous];
But the problem is i always get this response from yfrog servers:
So something is wrong with the image upload. On iPhone it works like this:
[request setData:UIImageJPEGRepresentation(picture, 0.8) withFileName:#"filename.jpg" andContentType:#"image/jpeg" forKey:#"media"];
But this doesn't work cocoa(mac) because there is no method like UIIMageJPEGRepresentation.
Also the authentication works, this cant be the problem. If you ask you about this method signRequestWithClientIdentifier it is from the asihttprequest+oauth wrapper from here:
https://github.com/keybuk/asi-http-request-oauth
So how can i upload the image correctly ?
Thanks so much.
NSData* NSImageJPEGRepresentation(NSImage* image, CGFloat compressionQuality)
{
if(nil == image)return nil;
NSDictionary *dict;
dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:compressionQuality],
NSImageCompressionFactor,
nil];
NSBitmapImageRep* imageRep;
imageRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
return [imageRep representationUsingType:NSJPEGFileType
properties:dict];
}

ASIHTTPRequest problems on iPhone (memory?)

I am using ASIHTTPRequest on the iPhone to make a call to the server, which then sends a response containing a JSON file. I got it working on a basic level, but when I added it to my project, and made a call to the server, my app started crashing with bad_access.
I make the call from viewDidLoad as such:
requestModel = [[RequestModel alloc]init];
NSURL *url = [[NSURL URLWithString:#"myURL"]retain];
[requestModel eventsRequestFor:#"myUsername" password:#"myPassword" forURL:url];
This calls a function in another class called RequestModel, and I go through and try to unpack the returned array as such (a lot of code):
-(void)eventsRequestFor:(NSString*)username password:(NSString*)password forURL:(NSURL*)forURL {
//use ASIHTTPRequest to post to sever. Here you authenticate and recieve answer
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:forURL];
[request setUsername:username];
[request setPassword:password];
[request setDelegate:self];
[request setDidFailSelector:#selector(uploadFailed:)];
[request setDidFinishSelector:#selector(uploadFinished:)];
[request startAsynchronous];
[request release];
NSLog(#"Model called");
}
#pragma mark Model Delegates
- (void)uploadFinished:(ASIHTTPRequest *)request {
// Use when fetching text data
NSLog(#"upload start");
NSString *stringFromRequest = [[NSString alloc]init];
stringFromRequest = [request responseString];
[self buildArrayFromRequest:stringFromRequest];
//[stringFromRequest release];
}
- (void)uploadFailed:(ASIHTTPRequest *)request {
NSString *statusMessage = [request responseStatusMessage];
NSLog(#"%#",statusMessage);
NSError *error = [request error];
NSLog(#"%#",error);
}
-(void)buildArrayFromRequest:(NSString*)string {
NSArray *arrayFromData = [[NSArray alloc]init];
arrayFromData = [string yajl_JSON];
NSLog(#"This is the array from the JSON %#",[arrayFromData objectAtIndex:0]);
NSMutableArray *events = [[NSMutableArray alloc] init];
for(int i= 0; i < [arrayFromData count];i++)
{
/////code to unpack array
}
///here i try to populate table with unpacked array
FirstViewController *firstVC = [[FirstViewController alloc]init];
[firstVC createTableWithArray:events];
[firstVC release];
[arrayFromData release];
[events release];
}
Any ideas on where I am going wrong? It seems like I am releasing an object that has already been released, but I can't find it.
EDIT: You're releasing an NSData that's not yours.
You don't need this line :
[arrayFromData release];
because of this mistake :
You have put :
NSArray *arrayFromData = [[NSArray alloc]init];
arrayFromData = [string yajl_JSON];
when all you need is this :
NSArray *arrayFromData = [string yajl_JSON]; // This doesn't need releasing
You're releasing a request that's already autoreleased :(
// Create an autoreleased request object
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:forURL];
...
[request release]; // fail here - this line is not needed
Just FYI :
This is unneeded code :
NSString *stringFromRequest = [[NSString alloc]init];
stringFromRequest = [request responseString];
You are making a string object and then getting a different one. The first one you're making will be leaked. This code will do what you want :
NSString *stringFromRequest = [request responseString]; // This doesn't need releasing :)
However, it's the cause of a leak, not the crash that you are reporting.
(You've got this pattern in other places in your code, not just here.)

Resources