How edit a NSString that contains a NSMutableDictionary key/value? - ios

I have a NSDictionary and make a copy of NSDictionary:
NSDictionary *immutableDict = (NSDictionary *)json;
NSMutableDictionary *mutableDict = [immutableDict mutableCopy];
I want to convert this into a NSString selection category for then edit contain.
NSString * name = [mutableDict objectForKey:#"category"];
name = [name stringByAppendingString:[NSString stringWithFormat:#"mytexttoadd"]];
But when I want to change this NSString my app crash because the NSString is a NSCFArray ..
How can make this a NSString so I can edit it?

Related

Build URL from NSDictionary

In my application I need to build an url like :
https://www.thefootballapi/football/league1/player/stats
In order to be able to build the url, I need to access the objects in an NSDictionary, since NSDictionary is an unordered data set, I need to sort the objects alphabetically in order to build the correct url:
NSDictionary
{
category = "football";
league = " League1 " ;
section = player;
"sub_category" = "stats";
}
I have tried doing this by writing this block of code:
Accessing the objects:
NSArray *keyyy0= [self.redirect allKeys];
id aaKey0 = [keyyy0 objectAtIndex:0];
id aanObject0 = [self.redirect objectForKey:aaKey0];
NSArray *keys = [self.redirect allKeys];
id aKey = [keys objectAtIndex:1];
id anObject = [self.redirect objectForKey:aKey];
NSArray *keyyy = [self.redirect allKeys];
id aaKey = [keyyy objectAtIndex:2];
id aanObject = [self.redirect objectForKey:aaKey];
and building the full url like this :
NSString *fullurl = [NSString stringWithFormat:#"%#%#%#%#", newurl,anObject,aanObject,aanObject3 ];
This method works fine for now, however I was wondering if this is the correct way of doing this ? is there a better way of implementing this ?
For example as it's mentioned here : Joe's answer ,NSURLQueryItem is used to access objects from dictionaries and build queries from it, however when I used NSURLQueryItem the full url was built with ? and = signs.
Are there any other methods that can be used to just get all of the objects in an NSDictionary ?
When accessing values from an NSDictionary there's no guarantee what type it will be. With full type-checking, a safer and more readable way of creating your URL might be something like:
NSDictionary *redirect = #{#"category" : #"football",
#"league" : #" League1 ",
#"section" : #"player",
#"sub_category" : #"stats"};
id category = redirect[#"category"];
id league = redirect[#"league"];
id section = redirect[#"section"];
id subCategory = redirect[#"sub_category"];
if ([category isKindOfClass:[NSString class]] &&
[league isKindOfClass:[NSString class]] &&
[section isKindOfClass:[NSString class]] &&
[subCategory isKindOfClass:[NSString class]])
{
NSString *urlString = [NSString stringWithFormat:#"https://www.thefootballapi/%#/%#/%#/%#",
[((NSString*)category).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],
[((NSString*)league).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],
[((NSString*)section).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],
[((NSString*)subCategory).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSLog(#"%#", urlString); // https://www.thefootballapi/football/league1/player/stats
}
This also ensures the URL is generated as you wanted (lowercase "league1" without leading/trailing whitespace) given your input JSON.
Try this code.
//Your Dictionary
NSMutableDictionary *dict = [NSMutableDictionary new];
[dict setValue:#"football" forKey:#"category"];
[dict setValue:#"League1" forKey:#"league"];
[dict setValue:#"player" forKey:#"section"];
[dict setValue:#"stats" forKey:#"sub_category"];
// Get desired URL like this
NSArray *arr = [[dict allValues] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *strURL = [NSString stringWithFormat:#"https://www.thefootballapi/%#/%#/%#/%#", [arr objectAtIndex:0], [arr objectAtIndex:1], [arr objectAtIndex:2], [arr objectAtIndex:3]];
NSLog(#"%#", strURL);
It will return ULR same as you want : https://www.thefootballapi/football/League1/player/stats

Put multiple arrays in Dictionary

I am parsing a CSV file multiple times with for loop, here I need to store these arrays one by one dictionary. There are very less questions in stack about adding NSArray to NSDictionary. I am parsing CSV with below code but I strucked at storing in NSDictionary, The program is terminating and showing warning at assigning string to dictionary
for (i=0; i<=57; i++) {
NSString *keysString = [csvArray objectAtIndex:i];
NSArray *keysArray = [keysString componentsSeparatedByString:#","];
NSLog(#"Serail No %d %#",i,keysArray);
NSString *string = [NSString stringWithFormat:#"%d", i];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjects: keysArray forKeys: string];
}
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
for (i=0; i<=57; i++) {
NSString *keysString = [csvArray objectAtIndex:i];
NSArray *keysArray = [keysString componentsSeparatedByString:#","];
NSString *key = [NSString stringWithFormat:#"serial%d",i];
[dict setObject:keysArray forKey:key];
}
To get back data from dictionary,
NSArray *array = [dict valueForKey:#"serial24"];//to get array 24.
If I understand you correctly, you want to add the arrays to a dictionary, with the key being the string value of integer i ? What you need to do is allocate the dictionary outside your loop -
NSMutableDictionary *dict=[NSMutableDictionary new];
for (i=0; i<=57; i++) {
NSString *keysString = [csvArray objectAtIndex:i];
NSArray *keysArray = [keysString componentsSeparatedByString:#","];
NSLog(#"Serial No %d %#",i,keysArray);
NSString *string = [NSString stringWithFormat:#"%d", i];
dict[string]=keysArray;
}
I am not sure why you would want to do this, because this is basically an array. You could simply do -
NSMutableArray *outputArray=[NSMutableArray new];
for (NSString *keysString in csvArray) {
NSArray *keysArray = [keysString componentsSeparatedByString:#","];
[outputArray addObject:keysArray];
}

Create a Custom Formatted Dictionary Array from CSV File of Data

I've created an iPhone app that has a dictionary array of locations (lat,long,point). I created the array by manually entering each value.
myLocationArray = #[
#{
kStation : #"1",
kLatitude : #( 41.656467),
kLongitude : #(-81.277963)
},
#{
kStation : #"2",
kLatitude : #(41.657118),
kLongitude : #(-81.276545)
},
#{
kStation : #"3",
kLatitude : #(41.658493),
kLongitude : #(-81.273542)
},
...
This is good and works but now I want to create this array programmatically by getting the data from a .CSV file. I have a .CSV file (TestCSV.csv) that looks like this.
41.656467,-81.277963,27200
41.657118,-81.276545,27650
41.658493,-81.273542,28631.5
41.660728,-81.268547,30195
41.661830,-81.266065,30991
41.662828,-81.263819,31700
41.663677,-81.261962,32300
41.664578,-81.259909,32950
41.666210,-81.256312,34100
41.666921,-81.254708,34605
41.668043,-81.252191,35400
41.669044,-81.250043,36099
41.670120,-81.247495,36900
41.670778,-81.245957,37380
41.671459,-81.244292,37905
41.672028,-81.242832,38349
41.672487,-81.241702,38700
41.673106,-81.240175,39175
41.674364,-81.237007,40150
41.675170,-81.235038,40762.5
41.675716,-81.233698,41182
41.676143,-81.232614,41516
Specifically, I'd like to create myLocationArray (with formatting as shown) by reading straight from the TestCSV.csv. I'm not familiar with the code to achieve this and would really appreciate some direction.
Also, would it be any different or easier if the data was provided via text file instead of csv?
Try
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Locations" ofType:#"csv"];
NSString *csvString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
NSArray *locations = [csvString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableArray *locationsArray = [NSMutableArray array];
for (NSString * location in locations)
{
NSArray *components = [location componentsSeparatedByString:#","];
double latitude = [components[0] doubleValue];
double longitude = [components[1] doubleValue];
NSString *station = components[2];
NSDictionary *dict = #{#"kLatitude": #(latitude),
#"kLongitude": #(longitude),
#"kStation": station};
[locationsArray addObject:dict];
}
CSV File
Answer inspired from
csv file IS a plain-text file. To achive what you want you can use NSScanner and NSString componentsSeparatedByString: Everything else is really simple.
Answer provided by Anupdas. Cheers!
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Locations" ofType:#"csv"];
NSString *csvString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
NSArray *locations = [csvString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableArray *locationsArray = [NSMutableArray array];
for (NSString * location in locations)
{
NSArray *components = [location componentsSeparatedByString:#","];
double latitude = [components[0] doubleValue];
double longitude = [components[1] doubleValue];
NSString *station = components[2];
NSDictionary *dict = #{#"kLatitude": #(latitude),
#"kLongitude": #(longitude),
#"kStation": station};
[locationsArray addObject:dict];
}

IOS: How to read specific data in one list of XML

When I use NSXMLParser to parse XML in iPhone app, I know how to do it in the scenario like this:
> <title>L3178 : Freiensteinau Richtung Grebenhain</title> // From XML
But, if I want to extract data from a list, e.x. I want to get the lat and lon from <>id>, how should I deal with that?
<>id>
http://www.freiefahrt.info/?id=468B0243-E15C-4580-9AD2 14D8CF692999&lon=9.3495&lat=50.49465&country=DE&filter=0&expires=2013-12-20T03:13:00
<>/id>
It is very strange if I use instead of <>id>, it will disappear. So, I have to use this ugly notation.
Thank you in advance!
Create a method which extracts parameters from urlString
- (NSDictionary *)paramsFromURLString:(NSString *)urlString
{
NSRange range = [urlString rangeOfString:#"?"];
NSString *subString = [urlString substringFromIndex:range.location+range.length];
NSArray *components = [subString componentsSeparatedByString:#"&"];
NSMutableDictionary *params = [NSMutableDictionary dictionary];
for (NSString *string in components) {
NSRange subRange = [string rangeOfString:#"="];
NSString *key = [string substringToIndex:subRange.location];
NSString *value = [string substringFromIndex:subRange.location+subRange.length];
[params setObject:value forKey:key];
}
return params;
}
From the params find the lat and lon
NSString *urlString = #"http://www.freiefahrt.info/?id=468B0243-E15C-4580-9AD2 14D8CF692999&lon=9.3495&lat=50.49465&country=DE&filter=0&expires=2013-12-20T03:13:00";
NSDictionary *params = [self paramsFromURLString:urlString];
NSString *latitude = params[#"lat"];
NSString *longitude = params[#"lon"];

remove append strings

I have an nsarray with strings like this,
albumname/song42.mp3
albumname/song43.mp3 etc .
I want to remove the string "album name" and ".mp3" from the above array,and display it in a tableview as follows ,
song42
song43
then in the DidSelectRow ,i want to add the string
"http://www.domain.com/albumname/" and ".mp3" to the indepath.row element .
fo eg :
if user selects song42 in tableview ,then it must create a string like this "http://www.domain.com/albumname/song42.mp3"
How to do this ?
- [NSString stringByDeletingPathExtension] <--- This to remove
+ [NSString stringWithFormat:] <--- And this to recreate
EDIT My mistake, you first need to do this before you call the first method:
NSString *lastPath = [string lastPathComponent]; //song43.mp3
NSString *tableString = [lastPath stringByDeletingPathExtension]; //song43
You can use lastPathComponent and stringByDeletingPathExtension methods:
NSMutableArray *songs = [NSArray arrayWithCapacity:[sourceArray count]];
for (NSString *filename in sourceArray) {
[songs addObject:[[filename lastPathComponent] stringByDeletingPathExtension]];
}
use the String method componentsSeparatedByString first separate the strings using / and then . and discard what you don't need.
NSString *str="albumname/song42.mp3";
NSArray *mainStrArray = [str componentsSeparatedByString:#"/"];
NSArray remainingStrArray=[[mainStrArray objectAtIndex:1]componentsSeparatedByString:#"."];
NSString *result=[remainingStrArray objectAtIndex:0]; //here you have song42
You can use, as :
NSString *str = #"album name/song43.mp3";
str=[[str componentsSeparatedByString:#"/"][1]componentsSeparatedByString:#".mp3"][0];
NSLog(#"->%#",str); //song43
NSString *file = #"albumname/song42.mp3";
NSString *name = [[[[file componentsSeparatedByString:#"/"] objectAtIndex:1] componentsSeparatedByString:#"."] objectAtIndex:0];

Resources