how to capture the required values from a URL - iphone

I need to extract a variable's value from a string, which happens to be a URL. The string/url is loaded as part of a separate php query, not the url in the browser.
The url's will look like:
http://gmail.com?access_token=ab8w4azq2xv3dr4ab37vvzmh&token_type=bearer&expires_in=3600
How can I capture the value of the access_token which in this example is ab8w4azq2xv3dr4ab37vvzmh?

This code should do it:
- (NSString *)extractToken:(NSURL *)URL
{
NSString *urlString = [URL absoluteString];
NSRange start = [urlString rangeOfString:#"access_token="];
if (start.location != NSNotFound)
{
NSString *token = [urlString substringFromIndex:start.location+start.length];
NSRange end = [token rangeOfString:#"&"];
if (end.location != NSNotFound)
{
//trim off other parameters
token = [token substringToIndex:end.location];
}
return token;
}
//not found
return nil;
}
Alternatively, here is a more general solution that will extract all the query parameters into a dictionary:
- (NSDictionary *)URLQueryParameters:(NSURL *)URL
{
NSString *queryString = [URL query];
NSMutableDictionary *result = [NSMutableDictionary dictionary];
NSArray *parameters = [queryString componentsSeparatedByString:#"&"];
for (NSString *parameter in parameters)
{
NSArray *parts = [parameter componentsSeparatedByString:#"="];
NSString *key = [[parts objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([parts count] > 1)
{
id value = [[parts objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[result setObject:value forKey:key];
}
}
return result;
}

Good Category for NSDictionary:
#import "NSDictionary+URL.h"
#implementation NSDictionary (URL)
+ (NSDictionary *)dictionaryWithUrlString:(NSString *)urlString{
NSRange urlRange = [urlString rangeOfString:#"?"];
if(urlRange.length>0){
urlString = [urlString substringFromIndex:urlRange.length+urlRange.location];
}
NSArray *pairsArray = [urlString componentsSeparatedByString:#"&"];
NSMutableDictionary *parametersDictionary = [[NSMutableDictionary alloc] initWithCapacity:[pairsArray count]];
for(NSString *pairString in pairsArray){
NSArray *valuesArray = [pairString componentsSeparatedByString:#"="];
if([valuesArray count]==2){
[parametersDictionary setValue:[valuesArray objectAtIndex:1] forKey:[valuesArray objectAtIndex:0]];
}
}
return [parametersDictionary autorelease];
}
#end

NSMutableDictionary *querycomponent = [[NSMutableDictionary alloc] init];
if (![query isEqualToString:#""]){
NSArray *queryArray = [query componentsSeparatedByString:#"&"];
for (NSString *subquery in queryArray){
NSArray *subqueryArray = [subquery componentsSeparatedByString:#"="];
NSString *key = [subqueryArray objectAtIndex:0];
NSString *val = [subqueryArray objectAtIndex:1];
[querycomponent setObject:val forKey:key];
}
NSLog(#"querycomponent %#",querycomponent);
}

Related

Parsing RSS feed - retrieve images, urls?

Hello I am parsing a RSS And Atom feeds, and my question is how can I check for < img > and < url > tags in < description >?
There must be some sort of check. Thanks.
Here is how I parse them:
- (NSArray *)parseFeed:(NSURL *)feedURL{
NSError *error;
NSData *data = [NSData dataWithContentsOfURL:feedURL];
GDataXMLDocument *xmlParse = [[GDataXMLDocument alloc] initWithData:data error:&error];
GDataXMLElement *rootElement = xmlParse.rootElement;
NSArray *array = [[NSArray alloc] init];
if ([rootElement.name compare:#"rss"] == NSOrderedSame) {
array = [self parseRSSFeed:rootElement];
return array;
} else if ([rootElement.name compare:#"feed"] == NSOrderedSame) {
array = [self parseAtomFeed:rootElement];
return array;
} else {
NSLog(#"Unsupported root element: %#", rootElement.name);
return nil;
}
}
-(NSArray *)parseRSSFeed:(GDataXMLElement *) rootElement
{
NSMutableArray *entries = [[NSMutableArray alloc] init];
NSArray *channels = [rootElement elementsForName:#"channel"];
for (GDataXMLElement *channel in channels) {
NSArray *items = [channel elementsForName:#"item"];
for (GDataXMLElement *item in items) {
FeedItem *itemF = [[FeedItem alloc] init];
itemF.title = [item valueForChild:#"title"];
itemF.description = [item valueForChild:#"description"];
NSLog(#"IMAGE - %#", [item valueForChild:#"img"]);
itemF.dateString = [item valueForChild:#"pubDate"];
itemF.link = [NSURL URLWithString:[item valueForChild:#"link"]];
itemF.dateString = [item valueForChild:#"updated"];
itemF.author = [item valueForChild:#"author"];
[entries addObject:itemF];
NSLog(#"RSS - %#", itemF.title);
}
}
NSArray *RSSArray = [entries copy];
return RSSArray;
}
-(NSArray *)parseAtomFeed:(GDataXMLElement *) rootElement
{
NSMutableArray *entries = [[NSMutableArray alloc] init];
NSArray *entry = [rootElement elementsForName:#"entry"];
for (GDataXMLElement *entryElement in entry) {
// NSArray *items = [channel elementsForName:#"item"];
//for (GDataXMLElement *item in items) {
FeedItem *itemF = [[FeedItem alloc] init];
itemF.title = [entryElement valueForChild:#"title"];
itemF.description = [entryElement valueForChild:#"summary"];
NSArray *links = [entryElement elementsForName:#"link"];
for (GDataXMLElement *link in links) {
itemF.link = [NSURL URLWithString:[[link attributeForName:#"href"] stringValue]];
}
itemF.dateString = [entryElement valueForChild:#"updated"];
NSArray *authors = [entryElement elementsForName:#"author"];
for (GDataXMLElement *authorElement in authors) {
itemF.author = [authorElement valueForChild:#"name"];
}
[entries addObject:itemF];
NSLog(#"Atom - %#", itemF.title);
}
NSArray *atomArray = [entries copy];
return atomArray;
}
I am parsing them using GDataXMLParser, and my own parser class.
Do it like this:
NSString *Str=[item valueForChild:#"description"];
NSArray *tmp=[Str componentsSeparatedByString:#"<Img>"];
if([tmp count]>1){
NSString *urlstr=[[tmp objectatindex:1] stringByReplacingOccurrencesOfString:#" </Img>" withString:#""];
}
Now urlstr contains your image url.
Enjoy
I thought that
itemF.description = [item valueForChild:#"description"];
is NSString. So you can use componentsSeparatedByString with "your tag".
It will return array. In array at postion 1 you will get your img url.
This url has closing bracket "your closing tag".
Replace "your closing tag" with space. You will get image url.
Hope, this will help you.

sending NSDictionary with openURL

I want to open an other application using
[[UIApplication sharedApplication]openURL:[[NSURL alloc]initWithString:myString]];
as log as myString is like
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?%#",#"123"];
it works fine but if I try to use an NSDictionary like
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?%#",userInfo];
it fails without an error
Hope you can help me.
Try enumerating all the elements in your dictionary and appending those to your URL.
NSMutableString *params = [[[NSMutableString alloc] init] autorelease];
NSEnumerator *keys = [userInfo keyEnumerator];
NSString *name = [keys nextObject];
while (nil != name) {
[params appendString: name];
[params appendString: #"="];
[params appendString: [userInfo objectForKey:name]];
name = [keys nextObject];
if (nil != name) {
[params appendString: #"&"];
}
}
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?%#",params];
When you use an NSDictionary in the format string, you get a URL that looks like this:
testHandleOpenUrl://?{
bar = foo;
}
The result of calling -description on userInfo is simply substituted for the %#. Presumably, you want to pass parameters contained in the dictionary in the URL. Probably something like this:
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:#"bar", #"foo", nil];
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?foo=%#", [userInfo objectForKey:#"foo"]];
NSLog(#"myString: %#", myString); // prints "myString: testHandleOpenUrl://?foo=bar"
NSString * paramString = #"";
int i = 0;
for(NSString * key in [userInfo allKeys]){
NSString * value = (NSString*)[userInfo objectForKey:key];
NSString * valueParam = [NSString stringWithFormat:#"%#%#=%#",(i==0)?#"?":#"&",key,value];
paramString = [paramString stringByAppendingString:valueParam];
i++;
}
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://%#", paramString];

iPhone:Convert NSString 123-123-1234 into (123) 123-1234

I have string like 123-123-1234 so I want to convert string into this format
(123) 123-1234 so any idea to develop this functionality.
Thanks in advance.
I think something like this:
NSString *list = #"123-123-1234";
NSArray *listItems = [list componentsSeparatedByString:#"-"];
NSString *result = [NSString stringWithFormat:#"(%#) %#-%#", [listItem objectAtIndex:0], [listItem objectAtIndex:1], [listItem objectAtIndex:2]];
NSString * original = #"123-123-1234";
NSArray * components = [original componentsSeparatedByString:#"-"];
NSString * first = [NSString stringWithFormat:#"(%#)",[components objectAtIndex:0] ];
NSString * second = [NSString stringWithFormat:#"%#-%#",[components objectAtIndex:1],[components objectAtIndex:2]];
NSString * finalString = [NSString stringWithFormat:#"%#%#",first,second];
NSLog(#"Final Result = %#",finalString);
NSString *str = #"123-123-1234";
NSArray *arrForDate = [str componentsSeparatedByString: #"-"];
NSString *str1 = [NSString stringWithFormat:#"(%#) %#-%#",[arrForDate objectAtIndex:0],[arrForDate
objectAtIndex:1],[arrForDate objectAtIndex:2]];
NSLog(#"str1 %#",str1);
TESTED CODE: 100% WORKS
NSString *inputString=#"123-123-1234";
NSArray *TotalString=[inputString componentsSeparatedByString:#"-"];
NSString *outputString = [NSString stringWithFormat:#"(%#) %#-%#",[TotalString objectAtIndex:0],[TotalString objectAtIndex:1],[TotalString objectAtIndex:2]];
NSLog(#"outputString is : %# \n\n",outputString);
OUTPUT:
outputString is : (123) 123-1234
For Dynamic Sollution:
NOTE: if u have more dashes with ur string then it is really hard code everything with objectAtIndex with number 0,1,2,....
moreover it will crash if it has unexpected length
so here is the solution for this
NSString *inputString=#"123-123-1234";
NSArray *TotalString=[inputString componentsSeparatedByString:#"-"];
NSMutableString *outputString=[NSMutableString string];
for (NSMutableString *obj in TotalString) {
if ([TotalString objectAtIndex:0] == obj && [outputString length]<=0) {
outputString=[[outputString stringByAppendingFormat:#"(%#)",obj] mutableCopy];
}
else if ([TotalString objectAtIndex:1] == obj) {
outputString=[[outputString stringByAppendingFormat:#"%#%#",#" ",obj] mutableCopy];
}
else {
outputString=[[outputString stringByAppendingFormat:#"-%#",obj] mutableCopy];
}
}
OUTPUT:
outputString is : (123) 123-1234
NSString *list = #"123-123-1234";
NSArray *listItems = [list componentsSeparatedByString:#"-"];
NSString *result = [NSString stringWithFormat:#"(%#) %#-%#", [listItem objectAtIndex:0], [listItem objectAtIndex:1], [listItem objectAtIndex:2]];

parse a NSURL mailto

How can I parse a mailto request ?
'mailto:someone#example.com?cc=someone_else#example.com&subject=This%20is%20the%20subject&body=This%20is%20the%20body'
From this NSURL, I want to extract the recipient, the subject and the body. How should I do ?
Thanks
Here is some code that will parse any URL and return a dictionary with the parameters and the associated objects in a dictionary. It works for mailto URLs, too.
Please note: This code assumes you're using ARC!
#interface NSString (URLDecoding)
- (NSString *) URLDecodedString;
#end
#implementation NSString (URLDecoding)
- (NSString *) URLDecodedString {
NSString *result = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (__bridge CFStringRef)self, CFSTR(""), kCFStringEncodingUTF8);
return result;
}
#end
- (NSDictionary *) parameterDictionaryFromURL:(NSURL *)url {
NSMutableDictionary *parameterDictionary = [[NSMutableDictionary alloc] init];
if ([[url scheme] isEqualToString:#"mailto"]) {
NSString *mailtoParameterString = [[url absoluteString] substringFromIndex:[#"mailto:" length]];
NSUInteger questionMarkLocation = [mailtoParameterString rangeOfString:#"?"].location;
[parameterDictionary setObject:[mailtoParameterString substringToIndex:questionMarkLocation] forKey:#"recipient"];
if (questionMarkLocation != NSNotFound) {
NSString *parameterString = [mailtoParameterString substringFromIndex:questionMarkLocation + 1];
NSArray *keyValuePairs = [parameterString componentsSeparatedByString:#"&"];
for (NSString *queryString in keyValuePairs) {
NSArray *keyValuePair = [queryString componentsSeparatedByString:#"="];
if (keyValuePair.count == 2)
[parameterDictionary setObject:[[keyValuePair objectAtIndex:1] URLDecodedString] forKey:[[keyValuePair objectAtIndex:0] URLDecodedString]];
}
}
}
else {
NSString *parameterString = [url parameterString];
NSArray *keyValuePairs = [parameterString componentsSeparatedByString:#"&"];
for (NSString *queryString in keyValuePairs) {
NSArray *keyValuePair = [queryString componentsSeparatedByString:#"="];
if (keyValuePair.count == 2)
[parameterDictionary setObject:[[keyValuePair objectAtIndex:1] URLDecodedString] forKey:[[keyValuePair objectAtIndex:0] URLDecodedString]];
}
}
return [parameterDictionary copy];
}
And here is how you use it:
NSURL *mailtoURL = [NSURL URLWithString:#"mailto:foo#example.com?cc=bar#example.com&subject=Greetings%20from%20Cupertino!&body=Wish%20you%20were%20here!"];
NSDictionary *parameterDictionary = [self parameterDictionaryFromURL:mailtoURL];
NSString *recipient = [parameterDictionary objectForKey:#"recipient"];
NSString *subject = [parameterDictionary objectForKey:#"subject"];
NSString *body = [parameterDictionary objectForKey:#"body"];
EDIT:
I updated the code to work with any URL and recipients are now in the dictionary for mailto URLs.
I would pull the email from that like this:
NSString * mailToString = #"'mailto:someone#example.com?cc=someone_else#example.com&subject=This%20is%20the%20subject&body=This%20is%20the%20body'";
NSArray *tempArray = [mailToString componentsSeparatedByString:#"?"];
//get email address from array
NSString * emailString = [[tempArray objectAtIndex:0]description];
//clean up string
emailString = [emailString stringByReplacingOccurrencesOfString:#"'mailto:" withString:#""];
//and here is your email string
NSLog(#"%#",emailString);
Since iOS 7 this is easily doable with NSURLComponents. You can create that object with:
if let components = NSURLComponents(URL: url, resolvingAgainstBaseURL:false) { ...
Then you can get the recipient accessing the path property of NSURLComponents; and the parameters with the queryItems property. For instance, if we wanted to get the subject, something like this would do our job
let queryItems = components.queryItems as? [NSURLQueryItem]
let subject = queryItems?.filter({$0.name == "subject"}).first?.value
NSURL category for just mailto: This method also has a fix for a crash bug in Fabian's answer above when mailto: url doesn't contain a ?. It also doesn't require the URLDecodedString category method.
#implementation NSURL (Additions)
- (NSDictionary *) parameterDictionaryForMailTo {
NSMutableDictionary *parameterDictionary = [[NSMutableDictionary alloc] init];
NSString *mailtoParameterString = [[self absoluteString] substringFromIndex:[#"mailto:" length]];
NSUInteger questionMarkLocation = [mailtoParameterString rangeOfString:#"?"].location;
if (questionMarkLocation != NSNotFound) {
[parameterDictionary setObject:[mailtoParameterString substringToIndex:questionMarkLocation] forKey:#"recipient"];
NSString *parameterString = [mailtoParameterString substringFromIndex:questionMarkLocation + 1];
NSArray *keyValuePairs = [parameterString componentsSeparatedByString:#"&"];
for (NSString *queryString in keyValuePairs) {
NSArray *keyValuePair = [queryString componentsSeparatedByString:#"="];
if (keyValuePair.count == 2)
[parameterDictionary setObject:[[keyValuePair objectAtIndex:1] stringByRemovingPercentEncoding] forKey:[[keyValuePair objectAtIndex:0] stringByRemovingPercentEncoding]];
}
}
else {
[parameterDictionary setObject:mailtoParameterString forKey:#"recipient"];
}
return [parameterDictionary copy];
}
- (NSDictionary *) parameterDictionaryFromURL:(NSURL *)url {
NSMutableDictionary *parameterDictionary = [[NSMutableDictionary alloc] init];
NSURLComponents * urlComponents = [NSURLComponents componentsWithString:url.absoluteString];
for (NSURLQueryItem *item in urlComponents.queryItems) {
parameterDictionary[item.name] = item.value;
}
if ([url.scheme isEqualToString:#"mailto"]) {
NSUInteger questionMarkLocation = [url.resourceSpecifier rangeOfString:#"?"].location;
if (questionMarkLocation == NSNotFound) {
parameterDictionary[#"recipient"] = url.resourceSpecifier;
} else {
parameterDictionary[#"recipient"] = [url.resourceSpecifier substringToIndex:questionMarkLocation];
}
}
return [parameterDictionary copy];
}

Best way to split and convert url params into string values

I would like to split a custom url for app opening in iPhone into values, my scheme would be something like:
appname://user=jonsmith&message=blah%20blah
Where I would like to be able to get "user" and "message" as two NSStrings. Any advice on best approach?
Assuming your url is in an NSURL object called url:
NSMutableDictionary *queryParams = [[NSMutableDictionary alloc] init];
NSArray *components = [[url query] componentsSeparatedByString:#"&"];
for (NSString *component in components) {
NSArray *pair = [component componentsSeparatedByString:#"="];
[queryParams setObject:[[pair objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding: NSMacOSRomanStringEncoding]
forKey:[pair objectAtIndex:0]];
}
...
[queryParams release];
Use Google's gtm_dictionaryWithHttpArgumentsString NSDictionary category
http://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/Foundation/GTMNSDictionary%2BURLArguments.h
NSString* yourString = #"appname://user=jonsmith&message=blah%20blah";
NSString* queryString = [yourString substringFromIndex:strlen("appname://")];
NSArray* queryArray = [queryString componentsSeparatedByString:#"&"];
NSMutableDictionary* queryDict = [NSMutableDictionary dictionary];
for (NSString* query in queryArray) {
NSUInteger indexOfEqualsSign = [query rangeOfString:#"="].location;
if (indexOfEqualsSign != NSNotFound) {
NSString* key = [[query substringToIndex:indexOfEqualsSign] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString* value = [[query substringFromIndex:indexOfEqualsSign+1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[queryDict setObject:value forKey:key];
}
}
return queryDict;
Use an NSScanner if you need to save more memory.