NSXMLParser problem with "&"(Ampersand) character - iphone

My NSXMLParsing is not working because of "&" character.. my code s below .any help please ?
NSString *myRequestString = [NSString stringWithFormat:#"http://abc.com/def/webservices/aa.php?family_id=%d",self.passFamilyId];
//NSLog(#"Requested Service = %#",myRequestString);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:myRequestString]];
[request setHTTPMethod: #"POST" ];
NSData *downloadedData = [ NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:downloadedData encoding:NSASCIIStringEncoding];
//NSString *contentString = [str stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
NSData * data=[str dataUsingEncoding:NSUTF8StringEncoding];
//NSLog (#"string is :%#" ,str);
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
// Call the XMLParsers's initXMLParse method.
ClientDetailXmlParser *parser = (ClientDetailXmlParser*)[[ClientDetailXmlParser alloc] initXMLParser];
[xmlParser setDelegate:parser];
BOOL success = [xmlParser parse];
// Check for XML parsing.
if(success)
{
NSLog(#"No Errors in clientDetailXml.xml");
}
else
{
NSLog(#"Error Error Error in clientDetailXml.xml!!!");
}
[parser release];
parser = nil;
if (objClientAddUpdate != nil) {
[objClientAddUpdate createBubbleList];
}

Replace
NSString *str = [[NSString alloc] initWithData:downloadedData encoding:NSASCIIStringEncoding];
//NSString *contentString = [str stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
NSData * data=[str dataUsingEncoding:NSUTF8StringEncoding];
With:
NSString *str = [[NSString alloc] initWithData:downloadedData encoding:NSASCIIStringEncoding];
NSString *contentString = [str stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
NSData * data=[contentString dataUsingEncoding:NSUTF8StringEncoding];

Very similar to sepehr-mahmoudian's answer, but instead of replace any & you should really just replace & characters that are unescaped, to do this you can use a regexp:
NSString *str = [[NSString alloc] initWithData:downloadedData encoding:NSASCIIStringEncoding];
//NSString *contentString = [str stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
NSData * data=[str dataUsingEncoding:NSUTF8StringEncoding];
With:
NSString *str = [[NSString alloc] initWithData:downloadedData encoding:NSASCIIStringEncoding];
NSRange searchedRange = NSMakeRange(0, [str length]);
NSString *pattern = #"&(?!(#[0-9]{2,4}|[A-z]{2,6});)";
NSError *error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
str = [regex stringByReplacingMatchesInString:str options:0 range:searchedRange withTemplate:#"&"];
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];

Here's what worked for me:
NSString *response = [[NSString alloc]initWithData:dataResponse encoding:NSUTF8StringEncoding];
NSString *newResponse = [response stringByReplacingOccurrencesOfString:#"&amp:" withString:#"AND"];
NSData *dataObj = [newResponse dataUsingEncoding:NSUTF8StringEncoding];
If I replaced it with symbol '&', the response would be correct, but it would throw parsing error: 68. So I had to use 'and'.

Related

Convert Unicode character to NSString

I have received string from webservice which contains Unicode character. I want to convert that To plain NSString. so How can i do that?
ex: "This isn\u0092t your bike"
So how can remove unicode and replace it with its equal special symbol characted.
The output would be : "This isn't your bike"
char cString[] = "This isn\u2019t your bike";
NSData *data = [NSData dataWithBytes:cString length:strlen(cString)];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"result string: %#", string);
This should work.
UPDATE FOR THE COMMENT:
The unicode character specified by you is not supported in all fonts.
http://www.fileformat.info/info/unicode/char/92/fontsupport.htm
But this one does.
http://www.fileformat.info/info/unicode/char/2019/fontsupport.htm
Thats why it throws an error.
NSString *final_url = [NSString stringWithFormat:url];
final_url = [final_url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:final_url] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:120.0];
NSURLResponse *response;
NSError *error = [[NSError alloc] init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *strResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
SBJSON *objJSON = [SBJSON new];
NSMutableDictionary *objDataDic = [objJSON objectWithString:strResponse error:nil];
There is a library which does conversion
https://github.com/alexaubry/HTMLString. It will convert all kind of Unicode character.
let escapedSnack = "Fish & Chips"
let snack = escapedSnack.removingHTMLEntities // "Fish & Chips"

Prevent iCloud Backup

I make and app that the people download content and they can access it offline, it likes a catalogue. But Apple reject it because it baking up in iCloud i I'm doing the following but it seems not working.
Funciones.m
+ (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL {
const char* filePath = [[URL path] fileSystemRepresentation];
const char* attrName = "com.apple.MobileBackup";
u_int8_t attrValue = 1;
int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
return result == 0;
}
Update.m
- (void)updateImg:(NSString *)tipo {
//tomamos el ultimo update
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSTimeInterval time = [defaults doubleForKey:#"lastUpdate"];
NSLog(#"%f", time);
CatalogoAppDelegate *app = [[UIApplication sharedApplication] delegate];
NSString *post = [NSString stringWithFormat:#"lastUpdate=%f", time];
NSData *postData = [post dataUsingEncoding:NSISOLatin1StringEncoding allowLossyConversion:NO];
NSMutableURLRequest *urlRequest = [[[NSMutableURLRequest alloc] init] autorelease];
NSString *url = [NSString stringWithFormat:#"%#iPhone/update%#Img.php", app.serverUrl, tipo];
[urlRequest setURL:[NSURL URLWithString:url]];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody:postData];
NSData *urlData;
NSURLResponse *response;
NSError *error;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
if(urlData) {
NSString *aStr = [[[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding]autorelease];
//NSLog(#"%#: %#", tipo, aStr);
NSArray *temp = [aStr componentsSeparatedByString:#";"];
//Direccionl Local de la APP
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
for (int i=0; i<[temp count]; i++) {
NSString *tempImg = [NSString stringWithFormat:#"%#", [temp objectAtIndex:i]];
//NSLog(#"%#", tempImg);
//pedimos cada url
NSURL *tempURL = [NSURL URLWithString:[NSString stringWithFormat:#"%#images/%#/%#", app.serverUrl, tipo, tempImg]];
//[Funciones addSkipBackupAttributeToItemAtURL:tempURL];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:tempURL]];
NSLog(#"%#images/%#/%#", app.serverUrl, tipo, tempImg);
NSString *pngFilePath = [NSString stringWithFormat:#"%#/%#", docDir, tempImg];
NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(image)];
[data1 writeToFile:pngFilePath atomically:YES];
NSURL *backUrl = [NSURL fileURLWithPath:pngFilePath];
[Funciones addSkipBackupAttributeToItemAtURL:backUrl];
}
}
[self performSelectorInBackground:#selector(finUpdate) withObject:nil];
}
Any idea what I am doing wrong?
Thanks
setxattr provides a result indicating success or an error, and Apple's addSkipBackupAttributeToItemAtURL: method checks for an error and passes this information back to your code. Your code simply ignores it. Start by determining if it's returning an error or not.
Maybe it's because your app is compatible with iOS 5.0.
Do not backup variable is only available since 5.1. Details here http://developer.apple.com/library/ios/#qa/qa1719/_index.html#//apple_ref/doc/uid/DTS40011342

how can i parse a json string into nsdictionary?

i am writing code for login application. can anyone help me how to parse a json string?
my code is
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *loginStatus = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSArray *loginDict = [parser objectWithString:loginDict error:nil];
[loginStatus release];
[connection release];
Example data:
NSString *strData = #"{\"1\": {\"name\": \"Jerry\",\"age\": \"12\"}, \"2\": {\"name\": \"Bob\",\"age\": \"16\"}}";
NSData *webData = [strData dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:webData options:0 error:&error];
NSLog(#"JSON DIct: %#", jsonDict);
NSLog output:
JSON DIct: {
1 = {
age = 12;
name = Jerry;
};
2 = {
age = 16;
name = Bob;
};
}
//*************Static Resopnse
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"demo" ofType:#"text"];
NSLog (#"Content: %#", filePath);
NSString *content = [[[NSString alloc] initWithContentsOfFile:filePath
usedEncoding:nil
error:nil] autorelease];
SBJSON *json = [[SBJSON new] autorelease];
NSString *str=[[NSString alloc]initWithString:content];
dictTemp = [json objectWithString:str error:nil];
NSLog(#"Actions is: %#",dictTemp);
NSArray *arr=[[dictTemp valueForKey:#"Data"] mutableCopy];
arrX=[[NSMutableArray alloc] init];
arrY=[[NSMutableArray alloc] init];
for(NSDictionary *dict in arr)
{
[arrX addObject:[dict valueForKey:#"Milestone"]];
[arrY addObject:[dict valueForKey:#"Sites"]];
}
NSLog(#"X is: %#",[arrX description]);
NSLog(#"Y is: %#",[arrY description]);
NSString *loginStatus = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding]
NSLog([[loginStatus JSONValue] description],nil);
//This will give you parsed output.
NSString *responseString = [[NSString alloc] initWithData:responseData encoding: NSASCIIStringEncoding];
NSlog(#"json String is: %#",responseString);
NSDictionary *dictionary = [responseString JSONValue];
NSLog(#"Dictionary value is %#", [dictionary objectForKey:#"json"]);
the result of this code is:json String is: {"json":{"Success":"Activation code."}}
After Conversation the result is ------- Dictionary value is {
Success = "Activation code."};

Sanitising URLS (mainly for spaces) when parsing XML iPhone

I'm parsing XML using CXML in my iphone app, works fine when the locaiton I'm searching for (using query string) is a single word. However when I add a space (Say i'm searching for shoe shop) it falls over. I tried replacing the " " space with a %20 but it doesn't seem to be able to read that url back when it parses.
My code:
- (IBAction)doSearch {
NSString *trimmedWhat = [txtboxWhat.text stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSString *trimmedWhere = [txtboxWhere.text stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *tempFullUrl = [NSString stringWithFormat:#"http://sampleurl.com/mobilesearch/place/%#/0/0/0/%#/0/0/0/0/0/0/0/0/search.aspx", trimmedWhat, trimmedWhere];
searchType = #"fullSearch";
NSLog(#"Full String: %#",tempFullUrl);
NSLog(#"Search Type: %#",searchType);
PromotionViewController *passArray = [[PromotionViewController alloc] initWithNibName:#"PromotionViewController" bundle:nil];
[passArray setCurrentCat: tempFullUrl];
[passArray setCurrentType: searchType];
[self.navigationController pushViewController:passArray animated:YES];
[PromotionViewController release];
}
Then on my PromotionViewController:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString: [NSString stringWithFormat:[NSString stringWithFormat:#"%#", currentCat]]]];
[request setHTTPMethod: #"GET"];
dataReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
stringReplyServer = [[NSString alloc] initWithData:dataReply encoding:NSUTF8StringEncoding];
if(currentType == #"categorySearch") {
...do parse
}
It just seems to fall over when the returning url for place
How do I sanitise the URL?
Tom
EDIT
I've added the following to my original pass through of search
NSString *utfString = [tempFullUrl UTF8String];
PromotionViewController *passArray = [[PromotionViewController alloc] initWithNibName:#"PromotionViewController" bundle:nil];
[passArray setCurrentCat: utfString];
[passArray setCurrentType: searchType];
[self.navigationController pushViewController:passArray animated:YES];
[PromotionViewController release];
however it falls over with the following:
2011-11-18 10:41:52.677 Del Search[2312:f203] Full String: http://web-xml.asdasdas.com/mobilesearch/place/(null)/0/0/0/<UITextField: 0x74709d0; frame = (15 7; 286 31); text = 'london'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7470af0>>/0/0/0/0/0/0/0/0/search.aspx
- (IBAction)doSearch {
NSString * trimmedWhat = [txtboxWhat.text stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString * trimmedWhere = [txtboxWhat.text stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *tempFullUrl = [NSString stringWithFormat:#"http://sampleurl.com/mobilesearch/place/%#/0/0/0/%#/0/0/0/0/0/0/0/0/search.aspx", trimmedWhat, trimmedWhere];
searchType = #"fullSearch";
NSLog(#"Full String: %#",tempFullUrl);
NSLog(#"Search Type: %#",searchType);
PromotionViewController *passArray = [[PromotionViewController alloc] initWithNibName:#"PromotionViewController" bundle:nil];
[passArray setCurrentCat: tempFullUrl];
[passArray setCurrentType: searchType];
[self.navigationController pushViewController:passArray animated:YES];
[PromotionViewController release];
}
NSString *utfString = [currentCat UTF8String];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString: utfString]];
[request setHTTPMethod: #"GET"];
dataReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
stringReplyServer = [[NSString alloc] initWithData:dataReply encoding:NSUTF8StringEncoding];
if(currentType == #"categorySearch") {
...do parse
}
To fix it I just did:
NSString *utfString = [currentCat stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

parsing json data giving error

Im fetching JSON data from this link.
http://www.krsconnect.no/community/api.html?method=event&appid=620&eventid=15946&affecteddate=1310515200000
I want to store all the required elemnts like image-medium title etc in aDetail object of Detail class but its giving error.
Here is my code:
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.krsconnect.no/community/api.html?method=event&appid=620&eventid=15946&affecteddate=1310515200000"]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSDictionary *object = [parser objectWithString:json_string error:nil];
NSArray *results = [parser objectWithString:json_string error:nil];
for (int i=0; i<[results count]; i++) {
NSDictionary*dictOne=[results objectAtIndex:i];
Detail *aDetail = [[Detail alloc] initWithDictionary:[results objectAtIndex:i]];
[appDelegate.descriptionArray addObject:aDetail];
}
that's not how you use SBJSon. Try this:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.krsconnect.no/community/api.html?method=event&appid=620&eventid=15946&affecteddate=1310515200000"]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSDictionary *object = [json_string JSONValue];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSError *error;
SBJSON *json = [[SBJSON new] autorelease];
id obj = [json objectWithString:json_string error:&error];
if ([obj isKindOfClass:[NSDictionary class]]) {
[appDelegate.descriptionArray addObject:obj];
}else if ([obj isKindOfClass:[NSArray class]]) {
for (NSDictionary *aDetail in obj) {
[appDelegate.descriptionArray addObject:aDetail];
}
}