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];
Related
I am using MGtwitterengine in iPhone , I want to use USER search API http://api.twitter.com/1/users/search.json?q={username} but I don't find any method for this in MGTwitterengine. how can I use this API in iphone to get users.
Thanks
Use like This :-
- (void)searchforTwUser {
OAToken *access_token = [[OAToken alloc] initWithKey:[tEngine oauthKey] secret:[tEngine oauthSecret]];
OAConsumer *aconsumer = [[OAConsumer alloc] initWithKey:kOAuthConsumerKey
secret:kOAuthConsumerSecret];
OADataFetcher *fetcher = [[OADataFetcher alloc] init];
NSString *spaceString=#" ";
NSCharacterSet * set = [[NSCharacterSet characterSetWithCharactersInString:self.searchName] invertedSet];
if ([spaceString rangeOfCharacterFromSet:set].location == NSNotFound)
{
NSString *Name = [self.searchName stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://api.twitter.com/1/users/search.json?q=%#",Name]];
NSLog(#"search name 1 is ..................................... %#",url);
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url
consumer:aconsumer token:access_token realm:nil
signatureProvider:nil];
[request setHTTPMethod:#"GET"];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:#selector(searchTicket:didFinishWithData:)
didFailSelector:#selector(searchTicket:didFailWithError:)];
[request release];
}
else
{
NSString *addStr = #"%20";
NSString *firstCapChar = [[searchName substringToIndex:1] capitalizedString];
NSString *cappedString = [searchName stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:firstCapChar];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://api.twitter.com/1/users/search.json?q=%#%#",cappedString,addStr]];
NSLog(#"search name 2 is ..................................... %#",url);
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url
consumer:aconsumer token:access_token realm:nil
signatureProvider:nil];
[request setHTTPMethod:#"GET"];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:#selector(searchTicket:didFinishWithData:)
didFailSelector:#selector(searchTicket:didFailWithError:)];
[request release];
}
[access_token release];
[aconsumer release];
}
- (void) searchTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data {
NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *dict = [response objectFromJSONString];
NSLog(#"Dict %#",dict);
[twSearchArray removeAllObjects];
if (twSearchArray != nil) {
[twSearchArray release];
twSearchArray = nil;
}
twSearchArray = (NSMutableArray *)dict;
NSLog(#"Twitter %#",twSearchArray);
self.twLoaded = YES;
[twSearchArray retain];
[self prepareSearchResults];
[response release];
}
- (void) searchTicket:(OAServiceTicket *)ticket didFailWithError:(NSData *)error {
NSLog(#"Errors is %#",error.description);
}
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
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:#"&:" 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'.
I'm trying to fetch images from url. Can someone point where i get wrong here is my code?
NSString *filesContent = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.projects-demo.com/iphone/xml/Menu.xml"] ];
DDXMLDocument *ddDoc = [[DDXMLDocument alloc] initWithXMLString:filesContent options:0 error:nil];
DDXMLElement *ddMenu = [ddDoc rootElement];
NSArray *ddChildren = [ddMenu children];
for (int j = 0 ;j < [ddChildren count]; j++) {
DDXMLElement *image1st = [[ddMenu elementsForName:[NSString stringWithFormat:#"cookingType%d",j+1]] objectAtIndex:0];
for (DDXMLNode *n in [image1st children]) {
// if ([[n name] isEqualToString: #"cookingType"]) {
MenuModel *model = [[MenuModel alloc] init];
NSLog(#"image of cooking........%#",[n stringValue]);
model.imgsrc = [n stringValue];
[listofimages addObject:model];
//ss
//======
NSData *mydata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:model.imgsrc]];
NSLog(#"printing my data ....",mydata);
UIImage *myimage = [[UIImage alloc] initWithData:mydata];
I tried to print nsDAta but it get nothing.
Just an observation, your NSLog for the variable myData, misses %#, not sure if this is just a copy and paste error or something that the HTML doesn't show.
Also try and Log [myData length] there might be a problem with the download.
Last, I would recommend that you do all your URL calls asynchronously.
It would look somewhat like this
`
-(void) loadingThumnailFormURL:(NSString *) thumbnailURL {
[imageData release];
imageData = [[NSMutableData alloc] init];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:thumbnailURL]];
NSURLConnection *urlConnection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
[urlRequest release];
[urlConnection start];
}`
Needless to say you have to implement the delegate methods for NSURLConnection and capture the data.
I am developing an app using data from google reader's API and using GData for login.
I want to be able to mark a post inside a table cell as read / unread, but am finding the fact that this is all mainly undocumented hard to work out a solution, any ideas / links?
Here is the code for the mark read button:
//Get the token
NSString *tokenString = [NSString stringWithFormat:#"https://www.google.com/reader/api/0/token"];
NSURL *tokenURL = [NSURL URLWithString:tokenString];
NSMutableURLRequest *tokenRequest = [NSMutableURLRequest requestWithURL:tokenURL];
NSString *tokenStringResult;
NSArray *listItems;
NSError *tokenError = nil;
NSURLResponse *tokenResponse = nil;
NSData *tokenData = [NSURLConnection sendSynchronousRequest:tokenRequest
returningResponse:&tokenResponse
error:&tokenError];
if (tokenData)
{
tokenStringResult = [[NSString alloc] initWithData:tokenData encoding:NSUTF8StringEncoding];
listItems = [tokenStringResult componentsSeparatedByString:#"/"];
}
else
{
NSLog(#"tokenError = %#", tokenError);
}
// Mark it as read
NSString *readerURLString = [NSString stringWithFormat:#"http://www.google.com/reader/api/0/edit-tag?a=user/-/state/com.google/read&async=true&s=feed/%#&i=%#&T=%#", siteLink, postID, [listItems lastObject]];
NSURL *readerURL = [NSURL URLWithString:readerURLString];
NSMutableURLRequest *readerRequest = [NSMutableURLRequest requestWithURL:readerURL];
[mAuth authorizeRequest:readerRequest];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:readerRequest
returningResponse:&response
error:&error];
if (data)
{
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response;
assert( [httpResponse isKindOfClass:[NSHTTPURLResponse class]] );
NSLog(#"response.allHeaderFields = %#", [httpResponse allHeaderFields]);
NSLog(#"response.statusCode = %i", [httpResponse statusCode]);
}
the log from this is:
response.statusCode = {
"Cache-Control" = "private, max-age=0";
"Content-Length" = 1334;
"Content-Type" = "text/html; charset=UTF-8";
Date = "Fri, 21 Jan 2011 03:49:07 GMT";
Expires = "Fri, 21 Jan 2011 03:49:07 GMT";
Server = GSE;
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = SAMEORIGIN;
"X-Reader-Google-Version" = "527-000";
"X-Reader-User" = 01940378872835844713;
"X-Xss-Protection" = "1; mode=block";
}
response.statusCode = 400
So through alot of trial and error I've got it working.
EDIT - Added Auth code
NSString *GOOGLE_CLIENT_AUTH_URL = #"https://www.google.com/accounts/ClientLogin?client=SomeName";
NSString *gSourceString = #"SomeName";
NSMutableURLRequest *httpReq = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:GOOGLE_CLIENT_AUTH_URL]];
[httpReq setTimeoutInterval:30.0];
[httpReq setCachePolicy:NSURLRequestReloadIgnoringCacheData];
[httpReq setHTTPMethod:#"POST"];
[httpReq addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSString *requestBody = [[NSString alloc] initWithFormat:#"Email=%#&Passwd=%#&service=reader&accountType=HOSTED_OR_GOOGLE&source=%#", userString, passwordString, [NSString stringWithFormat:#"%#%d", gSourceString]];
[httpReq setHTTPBody:[requestBody dataUsingEncoding:NSASCIIStringEncoding]];
[requestBody release];
NSHTTPURLResponse *response = nil;
NSData *data = nil;
NSString *responseStr = nil;
NSArray *responseLines = nil;
int responseStatus = 0;
data = [NSURLConnection sendSynchronousRequest:httpReq returningResponse:&response error:&error];
[httpReq release];
if ([data length] > 0)
{
responseStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
responseStatus = [response statusCode];
if (responseStatus == 200 )
{
authOK = TRUE;
NSLog(#"Successfully authenticated with Google.");
NSArray *authLines = nil;
authLines = [responseStr componentsSeparatedByString:#"\n"];
int j;
for (j =0; j < [authLines count]; j++ )
{
if ([[authLines objectAtIndex:j] rangeOfString:#"Auth="].length != 0) {
NSMutableString *teststring = [NSMutableString stringWithString:[authLines objectAtIndex:j]];
[teststring replaceCharactersInRange:NSMakeRange(0,4) withString:#"auth"];
authString = teststring;
}
}
}
}
NSString *auth = [[NSString alloc] initWithString: [NSString stringWithFormat:#"GoogleLogin %#", authString]];
NSDictionary *createHeader = [[NSDictionary dictionaryWithObjectsAndKeys:#"www.google.com", #"Host", #"EditApp", #"User-Agent", #"gzip, deflate", #"Accept-Encoding", auth, #"Authorization", nil]retain];
[auth release];
NSURL *url =[NSURL URLWithString:#"http://www.google.com/reader/api/0/token?client=EditApp"];
NSData *recieveData;
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc]initWithURL:url];
[urlRequest setHTTPMethod:#"GET"];
[urlRequest setAllHTTPHeaderFields:createHeader];
NSURLResponse *response;
NSError *error;
recieveData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
// Get token
NSString *pretokenString = [[NSString alloc] initWithData:recieveData encoding:NSASCIIStringEncoding];
tokenString = [pretokenString substringWithRange:NSMakeRange(2, [pretokenString length]-2)];
[pretokenString release];
[urlRequest release];
NSMutableURLRequest *thttpReq = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.google.com/reader/api/0/edit-tag?"]];
[thttpReq setTimeoutInterval:30.0];
[thttpReq setHTTPMethod:#"POST"];
NSString *authHeader = [NSString stringWithFormat:#"GoogleLogin %#", authString];
[thttpReq addValue:authHeader forHTTPHeaderField:#"Authorization"];
[thttpReq addValue:#"Content-Type" forHTTPHeaderField:#"application/x-www-form-urlencoded"];
// siteLink is the url of the feed
// googlePostID is the id from the XML output: tag:google.com,2005:reader/item/e3345c69e174bdec
NSString *trequestBody = [[NSString alloc] initWithFormat:#"a=user/-/state/com.google/read&ac=edit-tags&s=feed/%#&i=%#&T=%#", siteLink, googlePostID, tokenString];
[thttpReq setHTTPBody:[trequestBody dataUsingEncoding:NSASCIIStringEncoding]];
NSURLConnection *con = [[NSURLConnection alloc]
initWithRequest:thttpReq
delegate:self
startImmediately:NO];
[con scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
[con start];
If you are familiar with php I wrote a tutorial on using the google readi api recently.
http://mobile.tutsplus.com/tutorials/mobile-web-apps/building-a-mobile-web-application-with-the-google-reader-api/
One thing I notice is that in this string
http://www.google.com/reader/api/0/edit-tag/a=user/-/state/com.google/read&async=true&s=feed/%#&i=%#
Your not including the "edit" token the url should look like this. and you need the ? after edit-tag.
http://www.google.com/reader/api/0/edit-tag?a=user/-/state/com.google/read&async=true&s=feed/%#&i=%#&T=%#
You can get the "edit" token from this link once you have the user logged in, https://www.google.com/reader/api/0/token
Sorry can't help with objective-c stuff.