I'm learning "Programming in Objective-C" from Stephen Kochan and I have a problem with a mutable copy of NSDictionary.
So, here is my code:
NSMutableString *value1 = [[NSMutableString alloc ] initWithString: #"Value for Key one" ];
NSMutableString *value2 = [[NSMutableString alloc ] initWithString: #"Value for Key two" ];
NSMutableString *value3 = [[NSMutableString alloc ] initWithString: #"Value for Key three" ];
NSMutableString *value4 = [[NSMutableString alloc ] initWithString: #"Value for Key four" ];
NSString *key1 = #"key1";
NSString *key2 = #"key2";
NSString *key3 = #"key3";
NSString *key4 = #"key4";
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys: value1, key1, value2, key2, value3, key3, nil];
NSDictionary *dictionaryCopy = [[NSDictionary alloc] init];
NSMutableDictionary *dictionaryMutableCopy = [[NSMutableDictionary alloc] init];
dictionaryCopy = [dictionary copy];
dictionaryMutableCopy = [dictionary mutableCopy];
[value1 setString: #"New value for Key one" ];
[value2 setString: #"New value for Key two" ];
[value3 setString: #"New value for Key three" ];
dictionaryMutableCopy[key4] = value4;
NSLog(#"All key for value 4");
for (NSValue *key in [dictionaryMutableCopy allKeysForObject:value4]) {
NSLog(#"key: %#", key);
}
NSLog(#"All values");
for (NSValue *val in [dictionaryMutableCopy allValues]) {
NSLog(#"value: %#", val);
}
for (NSValue *key in [dictionaryMutableCopy allKeys]) {
NSLog(#"Key: %# value: %#", key, dictionary[key]);
}
How you see and the end of the code I'm printing all key/values from my NSMutableDictionary, but for key 4 I haven't a value!
Screen from terminal
But how you can see the value for key 4 is't null!
[Content of NSMutableDictionary][2]
What's the problem? Please help
In the final for loop, you are getting the value from dictionary instead of dictionaryMutableCopy:
for (NSValue *key in [dictionaryMutableCopy allKeys]) {
NSLog(#"Key: %# value: %#", key, dictionaryMutableCopy[key]);
// ^^^^^^^^^^^^^^^^^^^^^
}
Related
I have below snippet that I am supposed to create in objective-c.
{
"expression": "???=n1+n2+n3+n4",
"terms": [
{
"name": "termsTitle",
"term": [
{
"name": "answer",
"value": "???"
}
]
}
]
}
Here's my attempt to create it
NSMutableArray *terms= [[NSMutableArray alloc] init];
NSArray *keysTerms = [[NSArray alloc] initWithObjects:#"name", #"term", nil];
NSMutableArray *term= [[NSMutableArray alloc] init];
NSArray *objectsTerms = [[NSArray alloc] initWithObjects:#"answer",term, nil];
NSDictionary *termsDict = [[NSMutableDictionary alloc] initWithObjects:objectsTerms forKeys:keysTerms];
[terms addObject:termsDict];
NSDictionary *statement = [[NSDictionary alloc]
initWithObjectsAndKeys:expression,#"expression",
terms,#"terms",
nil];
I think I am close but for some reason, this is not working for me. I would appreciate any help. Thanks in advance.
this should work
NSDictionary* termDict = [NSDictionary dictionaryWithObjects:#[#"answer",#"???"] forKeys:#[#"name",#"value"]];
NSArray* termArray = [NSArray arrayWithObjects:termDict, nil];
NSDictionary* termsDict = [NSDictionary dictionaryWithObjects:#[#"termsTitle",termArray] forKeys:#[#"name",#"term"]];
NSMutableArray* terms = [NSMutableArray arrayWithObjects:termsDict, nil];
NSDictionary* result = [NSDictionary dictionaryWithObjects:#[#"???=n1+n2+n3+n4",terms] forKeys:#[#"expression",#"terms"]];
NSLog(#"result: %#",[result description]);
The Result
2014-11-21 15:03:14.396 Answering_question[23716:113224] result: {
expression = "???=n1+n2+n3+n4";
terms = (
{
name = termsTitle;
term = (
{
name = answer;
value = "???";
}
);
}
);
}
If you have some problems with the structure you need to write more detailed code. Like this:
NSMutableDictionary *mainDict= [NSMutableDictionary new];
[mainDict setObject:#"???=n1+n2+n3+n4" forKey:#"expression"];
NSMutableArray *terms = [NSMutableArray new];
NSMutableDictionary *term = [NSMutableDictionary new];
[term setObject:#"name" forKey:#"termsTitle"];
NSMutableArray *subTerms = [NSMutableArray new];
NSMutableDictionary *subTerm = [NSMutableDictionary new];
[subTerm setObject:#"answer" forKey:#"name"];
[subTerm setObject:#"???" forKey:#"value"];
[subTerms addObject:subTerm];
[term setObject:subTerms forKey:#"term"];
[terms addObject:term];
[mainDict setObject:terms forKey:#"terms"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:mainDict
options:NSJSONWritingPrettyPrinted
error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
Output:
{
"expression" : "???=n1+n2+n3+n4",
"terms" : [
{
"termsTitle" : "name",
"term" : [
{
"name" : "answer",
"value" : "???"
}
]
}
]
}
Webservice sends me JSON that looks like that:
[
{"key":"key1","value":"value1"},
{"key":"key2","value":"value2"},
{"key":"key3","value":"value3"}
]
How should I set up RestKit mapping to get the following NSDictionary?
#{ #"key1" : #"value1", #"key2" : #"value2", #"key3": #"value3" }
This may help you, try this.
NSDictionary *dict1 = [[NSMutableDictionary alloc] init];
NSArray *arr = [[NSArray alloc] initWithArray:<Parse the array here from RESTkit>];
for (int i = 0;i < [arr count], i++)
{
NSDictionary *dict = [arr objectAtIndex:i];
NSString *key = [dict objectForKey:#"key"];
NSString *value = [dict objectForKey:#"value"];
[dict1 setObject:value forKey:key];
}
NSLog(#" Dictionary %#", dict1);
[dict1 release];
I am getting a string response from the Google Directions API that contains characters that are supposed to represent a different-language character. Similiar to Ƨ³, similiar to these type of characters. I think the characters are portugese, but anyways my string contains like this:
\U00e3o
(I am not sure if those are zeroes or 'O's)
I am not sure what the technical term for these characters are, but how can I fix them in my string so they print properly.
Thank you
UPDATE:
I have updated my question title with the correct term 'unicode'.
I have checked a few questions:
NSString Unicode display
Detect Unicode characters in NSString on iPhone
iOS HTML Unicode to NSString?
And a few others. I have followed the answer, but the unicode characters are not fixed.
UPDATE:
Here is my code to get the response from GDirection.
Forming the request and getting a response:
AFHTTPClient *_httpClient = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://maps.googleapis.com/"]];
[_httpClient registerHTTPOperationClass: [AFJSONRequestOperation class]];
[_httpClient setDefaultHeader:#"Accept" value:#"application/json"];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
[parameters setObject:[NSString stringWithFormat:#"%f,%f", location.coordinate.latitude, location.coordinate.longitude] forKey:#"origin"];
[parameters setObject:[NSString stringWithFormat:#"%f,%f", location2.coordinate.latitude, location2.coordinate.longitude] forKey:#"destination"];
[parameters setObject:#"false" forKey:#"sensor"];
[parameters setObject:#"driving" forKey:#"mode"];
[parameters setObject:#"metric" forKey: #"units"];
NSMutableURLRequest *request = [_httpClient requestWithMethod:#"GET" path: #"maps/api/directions/json" parameters:parameters];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
AFHTTPRequestOperation *operation = [_httpClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSInteger statusCode = operation.response.statusCode;
if (statusCode == 200) {
[self parseResponse:responseObject];
} else {
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { }];
[_httpClient enqueueHTTPRequestOperation:operation];
}
Retrieving information from response object:
- (void)parseResponse:(NSDictionary *)response {
NSString *status = [response objectForKey: #"status"];
if (![status isEqualToString: #"OK"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat: #"Google Directions Response Status: %#", status] delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[alert show];
}
else {
NSArray *routes = [response objectForKey:#"routes"];
NSDictionary *routePath = [routes lastObject];
if (routePath) {
NSString *overviewPolyline = [[routePath objectForKey: #"overview_polyline"] objectForKey:#"points"];
legs = [routePath valueForKey: #"legs"];
if (legs) {
/* DIRECTION SET ================================================================================================================================
*/
directionOverview = [[NSMutableDictionary alloc] init];
NSString *legsDis = [NSString stringWithFormat: #"%#", [[legs valueForKey: #"distance"] valueForKey: #"text"]];
NSString *kmDistance = [self cutStringToPreference: legsDis];
if (kmDistance) {
[directionOverview setObject:kmDistance forKey: #"distance"];
milesLabel.text = kmDistance;
milesLabel.font = [UIFont fontWithName:#"interstate" size: 20.0];
}
NSString *durationText = [NSString stringWithFormat: #"%#", [[legs valueForKey: #"duration"] valueForKey: #"text"]];
durationText = [self cutStringToPreference: durationText];
if (durationText) {
[directionOverview setObject:durationText forKey: #"duration"];
}
NSString *startAddress = [NSString stringWithFormat: #"%#", [legs valueForKey: #"start_address"]];
startAddress = [self cutStringToPreference: startAddress];
NSString *endAddress = [NSString stringWithFormat: #"%#", [legs valueForKey: #"end_address"]];
endAddress = [self cutStringToPreference: endAddress];
[directionOverview setObject:startAddress forKey: #"origin"];
[directionOverview setObject:endAddress forKey: #"destination"];
NSArray *steps = [legs valueForKey: #"steps"];
if (steps) {
instructionArray = [[NSMutableArray alloc] init];
durationArray = [[NSMutableArray alloc] init];
distanceArray = [[NSMutableArray alloc] init];
int number = [[[steps lastObject] valueForKey: #"html_instructions"] count];
for (int i = 1; i <= number; ++i) {
NSString *instruction = [[[steps lastObject] valueForKey: #"html_instructions"] objectAtIndex: i-1];
instruction = [self cutStringToPreference: instruction];
instruction = [self flattenHTML: instruction];
instruction = [self stringByDecodingHTMLEntitiesInString: instruction];
[instructionArray addObject: instruction];
NSString *distance = [[[[steps lastObject] valueForKey: #"distance"] objectAtIndex: i-1] valueForKey: #"text"];
[distanceArray addObject: distance];
NSString *duration = [[[[steps lastObject] valueForKey: #"duration"] objectAtIndex: i-1] valueForKey: #"text"];
[durationArray addObject: duration];
}
}
}
_path = [self decodePolyLine:overviewPolyline];
NSInteger numberOfSteps = _path.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [_path objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[self.mapView addOverlay:polyLine];
}
}
}
Displaying the text in a label:
NSString *overviewAddressText = [NSString stringWithFormat: #"%# to %#", [directionOverview objectForKey: #"origin"], [directionOverview objectForKey: #"destination"]];
overviewAddress.text = overviewAddressText;
UPDATE:
Image of label
So as you can see, in the label, the text contains this kind of substring: S/U00e3o, which is a word that has an unsupported character. How can I fix that so that unicode turns into this: São
I wonder if it is possible to fill rangeOfString objects of a NSArray. Because I have a long list of objects for after rangeOfString:
NSArray biglist´s count is higher than list´s count.
I want to filter away the objects from the small list of the main list.
Please tell me if this is not clear.
My codes below:
NSArray *biglist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"smalllist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
for (NSString *listword in list);
NSMutableArray *wordlist = [[NSMutableArray alloc] init];
NSMutableArray *worindex = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
NSMutableDictionary *mutdic = [[NSMutableDictionary alloc] init];
NSMutableArray *mutarray = [[NSMutableArray alloc] init];
for (NSString *s in mainlist)
{
NSRange ran = [s rangeOfString:listword];
if (ran.location !=NSNotFound)
{
//my codes here
}
}
EDIT:
I think I can solve this by writing
int i;
for (i = 0; i<[list count]; i++)
{
NSString *same = [list objectAtIndex:i];
NSLog (#"listword: %#", same);
}
But I am not sure where to place it, inside the for loop s in mainlist or outside.
EDIT: This for loop works inside the main for loop.
EDIT:
Tried these codes, but it doesnt work somehow..
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"small" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *mainlist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSMutableArray *large = [NSMutableArray arrayWithArray:mainlist];
NSArray *newlarge;
for (NSString *listword in list)
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(SELF beginswith[c] %#)",listword];
newlarge = [large filteredArrayUsingPredicate:predicate];
}
NSLog (#"large: %#", newlarge);
NSLog (#"finished!");
"I want to filter away the objects from the small list of the main list."
If I understand correctly, you want to remove an array of items from another array. You don't want to do that much work and allocations inside an n^2 loop.
This removes an array of items from another array. Depending on how large your array is you may need to optimize further but this works:
NSArray *small = [NSArray arrayWithObjects:#"three", #"two", nil];
NSMutableArray *large = [NSMutableArray arrayWithObjects:#"one", #"two", #"three", #"four", nil];
[large removeObjectsInArray:small];
// print
for (NSString *current in large)
{
NSLog(#"item: %#", current);
}
This outputs:
2011-10-13 08:39:21.176 Craplet[5235:707] item: one
2011-10-13 08:39:21.178 Craplet[5235:707] item: four
I figured it out by myself and solved this :)
It works almost perfectly.
My codes:
NSArray *big = [[NSArray alloc] initWithObjects:#"hello ->mache", #"heisann hoppsann ->hiya", #"nei men ->da", #"however ->what", #"may ->april", #"mai ->maj", nil];
NSArray *small = [[NSArray alloc] initWithObjects: #"heisann ", #"nei men ", #"however ", #"mai", nil];
NSMutableArray *smallwithh = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
for (NSString *same in small)
{
NSLog (#"listword: %#", same);
for (NSString *s in big)
{
NSRange ran = [s rangeOfString:same];
if (ran.location !=NSNotFound)
{
[smallwithh addObject:s];
NSUInteger ind = [big indexOfObject:s];
[mindexes addIndex:ind];
}
}
}
NSLog (#"smallwith: %#", smallwithh);
[smallwithh release];
NSMutableArray *newWords =[NSMutableArray arrayWithArray: big];
[newWords removeObjectsAtIndexes: mindexes];
[big release];
[small release];
NSLog (#"newWords: %#", newWords);
I just want to parse this JSON string in Objective-C using the SBJSON framework, and retrieve the three units of data:
{"x":"197","y":"191","text":"this is a string"}
How can this be done?
NSString * jsonString = #"{\"x\":\"197\",\"y\":\"191\",\"text\":\"this is a string\"}";
SBJSON *jsonParser = [[SBJSON alloc] init];
NSDictionary * dictionary = [jsonParser objectWithString:jsonString];
NSLog(#"x is %#",[dictionary objectForKey:#"x"]);
[jsonParser release];
Here's an example:
NSString *jsonText = #"...";
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *dict = [parser objectWithString:jsonText];
for (NSString *key in [#"x y text" componentsSeparatedByString:#" "]) {
NSLog(#"%# => %#", key, [dict objectForKey]);
}
Here's something similar for SBJson4Parser:
id parser = [SBJson4Parser parserWithBlock:^(id v, BOOL *stop) {
for (NSString *key in [#"x y text" componentsSeparatedByString:#" "]) {
NSLog(#"%# => %#", key, [v objectForKey]);
}
}
allowMultiRoot:NO
unwrapRootArray:NO
errorHandler:^(NSError *err) {
// handle error here
}];
NSString *jsonText = #"...";
[parser parse: [jsonText UTF8String]];