deal with special characters in NSURL - ios

i have this code to url of image , i have little problem with my url it contain \u and xcode consider it as special character So i escape it by adding \u in my url
but when i pass it
fullPath = [NSString stringWithFormat:#"http:\\www.school-link.net\\uploads\\%#",image_url];
NSLog(#"file path %#",fullPath);
//i try escape space by this code it dosnt work
//fullPath = [fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [[NSURL alloc]initWithString:fullPath];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
AFHTTPRequestOperation *posterOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
posterOperation.responseSerializer = [AFImageResponseSerializer serializer];
[posterOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response: %#", responseObject);
image_view.image = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Image request failed with error: %#", error);
}];
[[NSOperationQueue mainQueue] addOperation:posterOperation];
[posterOperation start];
it give me error , any ideas
thank you all
image request failed with error: Error Domain=NSURLErrorDomain Code=-1000 "bad URL" UserInfo=0x8f9f900 {NSUnderlyingError=0x9a94cf0 "bad URL", NSLocalizedDescription=bad URL}

Your URL is malformed. Right now you have:
http:\\www.school-link.net\\uploads\\%#
Those backslashes should instead be forward slashes. Ex:
http://www.school-link.net/uploads/%#
Now you can append image_url to the URL, and presuming image_url doesn't cause the URL to be malformed, your request will go through.

Use NSUTF8String encoding. It will solve the problem. For example
NSString *strURL = [NSString stringWithContentsOfURL:yourURL encoding:NSUTF8StringEncoding error:NULL];
A line using this is commented in your code.

Related

how to handle space in sending json parameters to server in ios?

I am sending data to the server it is going successful but response coming with %20 at the space in data what I have sent to server here is the code I am using
NSString *str = [NSString stringWithFormat:#"http://www.me911.com/new/miphone3/android_edithealth.php?profile_id=%#&health_condition=%#&health_insurance_provider=%#&primary_physician_name=%#&primary_physician_phone=%#&last_physical=%ld&blood_type=%#&organ_donor=%#",profileId,txthospital.text,textinsurence.text,txtprimary.text,txtphone.text,dateInMillis,questionNo,textorgan.text];
str = [str stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSLog(#"Healthinfo URL: %#",str);
NSMutableURLRequest *dataRqst = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:str] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
[dataRqst setHTTPMethod:#"POST"];
NSString *stringBoundary = #"0xKhTmLbOuNdArY---This_Is_ThE_BoUnDaRyy---pqo";
NSString *headerBoundary = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",stringBoundary];
[dataRqst addValue:headerBoundary forHTTPHeaderField:#"Content-Type"];
NSMutableData *postBody = [NSMutableData data];
[dataRqst setHTTPBody:postBody];
NSHTTPURLResponse *dataresponse =[[NSHTTPURLResponse alloc] init];
NSError* error = [[NSError alloc] init] ;
//synchronous filling of data from HTTP POST response
NSData *responseData = [NSURLConnection sendSynchronousRequest:dataRqst returningResponse:&dataresponse error:&error];
//convert data into string
NSString *responseString = [[NSString alloc] initWithBytes:[responseData bytes] length:[responseData length] encoding:NSUTF8StringEncoding];
NSLog(#"responseString %# ",responseString);
if (responseString == NULL)
{
NSDictionary *infoDic = [[NSDictionary alloc] initWithObjectsAndKeys:#"There was a small problem",
#"title",
#"The network doesn't seem to be responding, please try again.",
#"message",
#"OK",
#"cancel",
#"1",
#"tag",nil,
#"delegate", nil];
[CommonFunctions performSelectorOnMainThread:#selector(showAlertWithInfo:) withObject:infoDic waitUntilDone:NO];
}
else
{
NSDictionary *jsonResponse = [responseString JSONValue];
if ([jsonResponse objectForKey:#"error"]){
NSLog(#"response %#",jsonResponse);
}
else{
}
NSMutableArray *dataresponse=[jsonResponse valueForKey:#"success"];
if ([jsonResponse objectForKey:#"success"])
{
NSLog(#"Array response %#",dataresponse);
}
}
And this is web service
:http://anaadit.net/miphone3/android_edithealth.php?profile_id=287&health_condition=palo%20Alto%20Veterans%20Hospital%20&health_insurance_provider=Blue%20Cross&primary_physician_name=Dr.Akki&primary_physician_phone=6504935000&last_physical=-57600&blood_type=7&organ_donor=No
Here I am sending data in textfield in like guru prasad but response getting like this guru%20prasad.
So please correct me where am I going wrong .
thanks in advance
Your code has a number of issues.
In order to create a URL with query params, I recommend to use the utility class NSURLComponents (see Apple documentation: NSURLComponents).
Composing a POST request whose content type is "multipart/formdata" is quite error prone. If you absolutely have to compose such a request I very strongly recommend to use a Network Library, for example AFNetworking.
On the other hand, using a POST request whose Content-Type is application/json is very easy to setup, especially with NSURLSession and friends.
You can find specific solutions for any of the suggested approaches mentioned above on SO, too.
Its seems there is some problem in parsing data, the space are replaced with %20...It seems you are using NSURL Connection for making API Calls.
Use AFNetworking for making API Calls, the response data will automatically come in JSON format and you can initialize Dictionary from same.
Please find below link for AFNetworking:
https://github.com/AFNetworking/AFNetworking
Please use "AFNetworking" and the code will be:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"profile_id": #"287", #"health_condition": #"palo Alto Veterans Hospital", #"health_insurance_provider": #"Blue Cross",
#"primary_physician_name":#"Dr.Akki",
#"primary_physician_phone":#"6504935000",
#"last_physical":#"-57600",
#"blood_type":#"7",
#"organ_donor":#"No"};
[manager POST:#"http://anaadit.net/miphone3/android_edithealth.php" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Please try the above code. I think this will help you.

How to get the HTML of a website and parse it with NSXMLParser

I am trying to parse the XML from a website (e.g. "http://www.kick-girl.com/?cat=3")
I can easily get the XML using:
NSURL *url = [NSURL URLWithString:#"http://www.kick-girl.com/?cat=3"];
NSLog(#"%#", [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]);
However when I try to use NSXMLParser it simply does not work. I have already tried converting the string to data
NSString *s = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData *d = [s dataUsingEncoding:NSUTF8Encoding];
NSXMLParser *xmlparser = [NSXMLParser alloc] initWithData:d];
xmlparser.delegate = self;
[xmlparser parse];
And it still does not work. The NSXMLParserDelegate methods do not get called.
e.g.
- (void)parser:didStartElement:namespaceURI:qualifiedName:attributes:
I have also tried using AFnetworking to see if that would help
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *requestOp = [[AFHTTPRequestOperation alloc] initWithRequest:request];
requestOp.responseSerializer = [AFXMLParserResponseSerializer serializer];
[requestOp.responseSerializer setAcceptableContentTypes:[NSSet setWithObjects:#"application/xml", #"text/xml", #"text/html", nil]];
[requestOp setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSXMLParser *xmlparser = responseObject;
xmlparser.delegate = self;
[xmlparser parse]; //Delegate methods are not called for some reason...
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"OOPS: %#", error);
}];
[requestOp start];
I don't understand what is the problem.
I get a parse error from -parser:parserErrorOccurred:
Error Domain=NSXMLParserErrorDomain Code=65 "The operation couldn’t be completed. (NSXMLParserErrorDomain error 65.)" UserInfo=0x8da6ce0 {NSXMLParserErrorLineNumber=2, NSXMLParserErrorColumn=17, NSXMLParserErrorMessage=attributes construct error
}
How do I fix this?
Apparently the XML that I got from the webpage is not perfect and has some weird stuff in it. Although a web browser is quite forgiving when it comes to reading xml, the nsxmlparser is very strict.
To prevent that weird stuff from coming out I simply took a substring of the parts that I wanted, then removed whitespaces like new lines carriage returns and tabs. And did some string manipulations to make sure the tags were actually balanced.

AFHttpclient get json body in block but outer function returns null

I am trying to send post request on some url and in body to be only json data (trying to register new user sending json like
{
"username": "test",
"password": "test",
"email": "email#gmail.com"
}
I have function like
-(NSString*) sendPostOnUrl:(NSString*) url
withParameters:(NSDictionary*)params{
__block NSString* response = nil;
NSError *error;
NSURL *u = [NSURL URLWithString:url];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL: u];
[httpClient postPath:REGISTER
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
response = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Request Successful, response '%#'", response);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"[HTTPClient Error]: %#", error.localizedDescription);
}];
return response;
}
where params are NSDictionary with keys username, password and email and values for those keys.
Problem is when I send I always in return get null in response (the latest line) but in NSLog I get json response.. I am very new to ios, and it looks to me that I need to sync on some way block with return from function but don't know how, can anybody give me a clue what am I doing wrong ? (params contains all those keys when I try to debug, url is ok, REGISTER is NSString constant)
Blocks are asynchronous - the problem here is that "response = [[NSString alloc] initWithData..." is within the block which gets executed after you've exited the method. A better approach is to not do this in a method, instead place this code where you were calling sendPostOnUrl:withParameters: and do whatever it is you need to do within the success block. So instead of:
self.something = [self sendPostOnUrl:url withParameters:#{"username":"test" etc}];
you do this:
NSError *error;
NSURL *u = [NSURL URLWithString:url];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL: u];
__weak YourClassName *me = self;
[httpClient postPath:REGISTER
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
me.something = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Request Successful, response '%#'", response);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"[HTTPClient Error]: %#", error.localizedDescription);
}];
Also, take note of "__weak YourClassName *me = self", you cannot reference self within a block because it will cause a retain cycle.

issue With AFNetworking?

I Wanna Get Data From PhP Page
My Code Is
NSURL *url = [NSURL URLWithString:#"http://avicenna-apps.com/harleychatget.php"];
AFHTTPClient * Client = [AFHTTPClient clientWithBaseURL:url];
[Client defaultValueForHeader:#"Accept"];
[Client getPath:#"" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"Data %#",responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error retrieving data: %#", error);
}];
The Output Is
Data <32352020 32303133 2d30312d 31302030 383a3234 3a353620 2041686d 65642020 68656c6c 6f206865 6c6c6f20 3c627220 2f3e3234 20203230 31332d30 312d3130 2030383a 32343a35 30202041 686d6564 20203c62 72202f3e 32332020 32303133 2d30312d 31302030 383a3234 3a343920 2041686d 65642020 3c627220 2f3e3230 20203230 31332d30 312d3130 2030383a 32343a34 38202041 686d6564 20203c62 72202f3e 32312020 32303133 2d30312d 31302030 383a3234 3a343820 2041686d 65642020 3c627220 2f3e200a 0a>
Any Help Please ?
That is binary data. You should convert it.
Try NSString *response = [[NSString alloc] initWithData:(NSData*)responseObject encoding:NSUTF8StringEncoding]; to get the response as string
or simple:
NSString *response = request.responseString;

Posting a serialized object with AFNetworking failing

I have a a data object, called DataElement. It contains a string of Base64 converted image bytes, along with a couple of other fields.
I am trying to post this to my wcf service and am getting an error 'Expected status code in (200-299), got 400.
The goal is to post data + an image to the WCF (rest) service, and get a modified image back- an end to end test of what I am working on.
In my post method, if I leave the encoded string empty on the object everything works just fine- but if that string is anything other than empty I get this error.
My WCF service isn't even being hit, it just bombs right to the error. Here is my post method... what am I doing wrong?
- (void)postDataToServer:(NSString*)server dataElement:(DataElement*)dataElement asJson:(BOOL)useJson
{
NSString *urlString = [[NSString alloc] init];
NSData *encodedData;
urlString = [[server copy] stringByAppendingString:#"EchoXml"];
encodedData = [self encodeDataElementAsXml:dataElement];
NSURL *url = [NSURL URLWithString:urlString];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST" path:urlString parameters:nil];
[request setHTTPBody:encodedData];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
[_responseTextView setText:[NSString stringWithFormat:#"Successfully uploaded file to %#", urlString]];
NSObject *httpResponseObject;
httpResponseObject = [self parseResponseAsXml:responseObject];
if ([httpResponseObject isKindOfClass:[DataElement class]])
{
DataElement *dataElement = (DataElement *)httpResponseObject;
_responseTextView.text = dataElement.DataText;
if (dataElement.DataImageBase64 != nil)
{
UIImage *dataImage = [self getImageFromString:dataElement.DataImageBase64];
self.responseImageView.image = dataImage;
}
}
NSLog(#"Successfully uploaded file to %#", urlString);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// It goes here immediately
[_responseTextView setText:[NSString stringWithFormat:#"Error: %#", error]];
NSLog(#"Error: %#", error);
}];
[operation start];
}
Edit: Sorry the formatting got wonky when I pasted it in...
The important parts of your code are:
NSString* urlString = [server stringByAppendingString:#"EchoXml"];
NSURL *url = [NSURL URLWithString:urlString];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSMutableURLRequest *request = [httpClient
requestWithMethod:#"POST" path:urlString parameters:nil];
The actual URL that AFNetorking requests is the AFHTTPClient's base URL, with the specified path appended to it.
Your mistake is that you are specifying the same urlString again.
So, if urlString is http://your.server.com/EchoXml, then the effective URL that you're requesting is http://your.server.com/EchoXmlhttp://your.server.com/EchoXml. As you see, that doesn't work.
Fix your base URL and path to be something more appropriate. Since you didn't say what URL you are trying to access, it's hard to give much more detail. Maybe server should be the base URL, and EchoXml the path?
I know its bad form to answer my own question- but I found and fixed the problem. Bottom line, the code I was using above is fine- maybe not optimal (as Kurt pointed out) but it does what it is supposed to do.
The problem was on on my WCF service- REST service requests by default have a 65k upload limit. I reconfigured the service to allow large file uploads and everything is good.

Resources