sending NSDictionary with openURL - iphone

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];

Related

Convert NSString to NSDictionary separated by specific character

I need to convert this "5?8?519223cef9cee4df999436c5e8f3e96a?EVAL_TIME?60?2013-03-21" string into dictionary. Separated by "?"
Dictionary would be some thing like
{
sometext1 = "5",
sometext2 = "8",
sometext3 = "519223cef9cee4df999436c5e8f3e96a",
sometext4 = "EVAL_TIME",
sometext5 = "60",
sometext6 = "2013-03-21"
}
Thank you .
Break the string to smaller strings and loop for them.
This is the way
NSArray *objects = [inputString componentsSeparatedByString:#"?"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
int i = 1;
for (NSString *str in objects)
{
[dict setObject:str forKey:[NSString stringWithFormat:#"sometext%d", i++]];
}
Try
NSString *string = #"5?8?3519223cef9cee4df999436c5e8f3e96a?EVAL_TIME?60?2013-03-21";
NSArray *stringComponents = [string componentsSeparatedByString:#"?"];
//This is very risky, your code is at the mercy of the input string
NSArray *keys = #[#"cid",#"avid",#"sid",#"TLicense",#"LLicense",#"date"];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
for (int idx = 0; idx<[stringComponents count]; idx++) {
NSString *value = stringComponents[idx];
NSString *key = keys[idx];
[dictionary setObject:value forKey:key];
}
EDIT: More optimized
NSString *string = #"5?8?3519223cef9cee4df999436c5e8f3e96a?EVAL_TIME?60?2013-03-21";
NSArray *stringComponents = [string componentsSeparatedByString:#"?"];
NSArray *keys = #[#"cid",#"avid",#"sid",#"TLicense",#"LLicense",#"date"];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjects:stringComponents forKeys:keys];
first separate the string into several arrays by '?'.
then add the string in you dictionary.
sth like this:
NSString *str = #"5?8?519223cef9cee4df999436c5e8f3e96a?EVAL_TIME?60?2013-03-21";
NSArray *valueArray = [str componentsSeparatedByString:#"?"];
NSMutableArray *keyArray = [[NSMutableArray alloc] init];
for (int i = 0; i <[valueArray count]; i ++) {
[keyArray addObject:[NSString stringWithFormat:#"sometext%d",i+1]];
}
NSDictionary *dic = [[NSDictionary alloc] initWithObjects:valueArray forKeys:keyArray];
For the future: If you were to store your data in JSON format (closer to what you have anyway), it'll be much easier to deal with and transfer between systems. You can easily read it...using NSJSONSerialization

exc_breakpoint while JSON parsing

I want to parse many JSON strings. Here is the code:
while(stations.count > 0) {
NSString*string = [[[NSString alloc] initWithString:[stations objectAtIndex:0]] retain];
NSMutableDictionary*dic = [[[NSMutableDictionary alloc]init]retain];
NSData*data = [[[NSData alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]]retain];
NSMutableDictionary* pars = [[NSMutableDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]];
[dic setObject:[NSString stringWithString:[pars objectForKey:#"nm"]] forKey:#"nm"];
[dic setObject:[NSString stringWithString:[pars objectForKey:#"btr"]] forKey:#"btr"];
[dic setObject:[NSString stringWithString:[pars objectForKey:#"id"]] forKey:#"id"];
[dic setObject:[NSString stringWithString:[pars objectForKey:#"cntr"]] forKey:#"cntr"];
[dic setObject:[NSString stringWithString:[pars objectForKey:#"gnr"]] forKey:#"gnr"];
[pars release];
#try {
[parsedData addObject:[NSDictionary dictionaryWithDictionary:dic]];
}
#catch (NSException* exc) {
NSLog(#"%#, %#", exc.description, exc.reason);
}
[dic release];
[data release];
[string release];
[stations removeObjectAtIndex:0];
if (i%1000==0) {
NSLog(#"nnnn %i %i", parsedData.count, stations.count);
}
i++;
float k = count;
k = (i + 1)/k;
[self performSelectorOnMainThread:#selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
}
On adding (usually but not every time) string to array I get error:
exc_breakpoint (code=exc_i386_bpt
and:
GuardMalloc[Radiocent new try-1820]: Failed to VM allocate 68752 bytes
GuardMalloc[Radiocent new try-1820]: Explicitly trapping into debugger!!!
Stations array is pretty big... about 60000 strings.
First of all when you alloc you don't need to retain as retain count is already +1.
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
Not
NSMutableDictionary*dic = [[[NSMutableDictionary alloc]init]retain];
Below line already returs mutable dictionary so you don't have to create a new dictionary out of that and if you want to change then just call a - mutableCopy on it.
NSMutableDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
or to create a copy:
NSMutableDictionary *dictionary = [[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil] mutableCopy];
If stations is JSON string then for all stations do this:
NSData *data = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *stationsArray = [[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil] mutableCopy];
for (NSDictionary *stationDic in stationArray)
{
// This will iterate over each station dictionary in the station array
// Do your stuff here ...
}
For your example: (I have added \" to escape the double quotes, you don't have to)
Placed square brackets around your example this make it an array and you can iterate through each using the given code below. (Add only if they are not there)
NSString *example = #"[{\"id\":\"02AB99\",\"btr\":\"24\",\"cntr\":\"461E\",\"gnr\":\"8A51\",\"nm\":\"88.3 Fm Radio Q Jogjakarta\"}, {\"id\":\"026058\",\"btr\":\"160\",\"cntr\":\"461E\",\"gnr\":\"8A7B\",\"nm\":\"88.3 The Dog\"}, {\"id\":\"0300D2\",\"btr\":\"55 64\",\"cntr\":\"461C\",\"gnr\":\"8A75\",\"nm\":\"88.3 The Wind\"}, {\"id\":\"0159E6\",\"btr\":\"128\",\"cntr\":\"4610\",\"gnr\":\"8A6C\",\"nm\":\"88.30 Z Fm Radio Word Online\"}]";
NSError *error = nil;
NSArray *stationArray = [NSJSONSerialization JSONObjectWithData:[example dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
if (!error)
{
for (NSDictionary *stationDic in stationArray)
{
NSLog(#"\nName: %# \nDump: \n%#", [stationDic valueForKey:#"nm"], stationDic);
}
}

Getting crashed when NSdictionary or NSString values into UILABEL

-(void) httpDataDidFinishLoadingWithData:(NSData *)theData
{
m_activityLoaded=NO;
temp=[[NSString alloc] initWithData:[dataLoader httpData]
encoding:NSUTF8StringEncoding];
NSLog(#"TEMP IS TEMP %#", temp);
NSDictionary *dict = [[NSDictionary alloc]init];
dict = [[temp JSONValue] objectForKey:#"location"];
NSDictionary *dict1 = [[NSDictionary alloc]init];
dict1 = [[temp JSONValue] objectForKey:#"wind"];
NSDictionary *dict2 = [[NSDictionary alloc]init];
dict2 = [dict1 objectForKey:#"direction"];
NSDictionary *dict3 = [[NSDictionary alloc]init];
dict3 = [[temp JSONValue] objectForKey:#"atmosphere"];
NSDictionary *dict4 = [[NSDictionary alloc]init];
dict4 = [[temp JSONValue] objectForKey:#"condition"];
NSDictionary *dict5 = [[NSDictionary alloc]init];
dict5 = [dict4 objectForKey:#"text"];
NSDictionary *dict6 = [[NSDictionary alloc]init];
dict6 = [dict4 objectForKey:#"code"];
NSDictionary *dict7 = [[NSDictionary alloc]init];
dict7 = [dict4 objectForKey:#"temperature"];
temperatureLabel.text = [dict4 objectForKey:#"temperature"];
}
Crash occurs at temperatureLabel.text = [dict4 objectForKey:#"temperature"];
I dont know man, Data is exactly printed in the console, but crashing at UILABEL(temperatureLabel). Help me out, thanks in advance
if you look at the error you are getting it is telling you that the object return for the key temperature is not a NSString or NSDictionary but a NSNumber.
Give this a try:
-(void) httpDataDidFinishLoadingWithData:(NSData *)theData {
m_activityLoaded=NO;
temp=[[NSString alloc] initWithData:[dataLoader httpData]
encoding:NSUTF8StringEncoding];
NSLog(#"TEMP IS TEMP %#", temp);
NSDictionary *dict = [[temp JSONValue] objectForKey:#"location"];
NSDictionary *dict1 = [[temp JSONValue] objectForKey:#"wind"];
NSDictionary *dict2 = [dict1 objectForKey:#"direction"];
NSDictionary *dict3 = [[temp JSONValue] objectForKey:#"atmosphere"];
NSDictionary *dict4 = [[temp JSONValue] objectForKey:#"condition"];
NSDictionary *dict5 = [dict4 objectForKey:#"text"];
NSDictionary *dict6 = [dict4 objectForKey:#"code"];
NSNumber *temperature = [dict4 objectForKey:#"temperature"];
temperatureLabel.text = [NSString stringWithFormat:#"%#", temperature];
}
You might want to look at NSNumberFormatter for formatter the temperature with something like: °F or °C.
Are you sure that your object is of NSString class?
Try putting in something like:
if([[dict4 objectForKey:#"temperature"] isKindOfClass:[NSString class]])
NSLog(#"lalala");
If it does not get logged to the console it means that your object is not an NSString and you could try something like:
temperatureLabel.text = [NSString stringWithFormat:#"%#", [dict4 objectForKey:#"temperature"]];
You should change the %# according to the kind of object you have stored in your dictionnary.
Your dictionary contains an NSNumber instance and you are assigning that to a property of type NSString. The crash message is your tip off there. Use stringValue or some other way to get the number's data into string form.

how to capture the required values from a URL

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);
}

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.