Xcode iOS: Retrieving values from NSDictionary and displaying it in UITextView - objective-c

I want to display the json data obtained as:
NSDictionary *detail = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&e];
and want to display it in UITextView(contact):
self.contact.text = [NSString stringWithFormat:#"%#",[detail valueForKey:#"Contact"];
But, I get the output as follows:
("Washington St, SD, CA")
detail is as follows:
(
{
Contact = "Washington St, SD, CA";
Id = 1;
Name = BJs;
}
)
I understand since it returns an array, But how do I display it in a string without the round brackets?

For dictionary access, you should ideally be using objectForKey:, not valueForKey: (which has to do with key-value coding).
I don't know what your original JSON looks like, but if it is like:
{"Contact": "Washinton St, SD, CA", ...}
Then this should work fine. If not (i.e. it actually is an array in JSON), you might want to extract the first element (with [... objectAtIndex:0], or joining the elements, or something else depending on your application).

Related

socketio-objc SocketIOPacket Parsing

I have the packet data coming in on a recieveEvent delegate.
getting dictionary of packet.dataAsJSON works, and doing an NSLog on that looks like this
args = (
{
id = "123";
name = "John Doe";
status = "Yeah";
}
};
= "JoinedChat";
First, I'm confused as to why it has '=' and ';' instead of ':' and ','
Second, when I getObjectAtKey:#"args", I don't get another dictionary of 3 objects , I get a dictionary of 1 object...and there's no keys...if I parse it as an Array, and get objectsAtIndex:0, I'm getting 3 objects but not dictionaries, I'm trying to access the data in there, but it isn't working. help please
I use the below code in my app:-
NSData *data = [packet.data dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
then use "json" variable and reload the table. This is working in my chat application.

How to get value from json with duplicate key?

I looked for a long time for an answer to this and couldn't find anything. Perhaps it is because I don't know how to ask the question as I am new to json. Essentially I am a new ios developer and am trying to learn how to access and use json data. Below is a portion of the json I am using:
{
"status": null,
"data": {
"1088": {
"nid": "1088",
"title": "RE 1 (2000)",
"articles": [
{
"nid": "2488",
"title": "Copyright Page"
},
...
etc.
my confusion is that there are two layers with the value title. So when I'm using something like
self.dict = [self getDictionaryFromJson]; and have saved the json in a dictionary, then I go to use
self.mainTitle = [self.dict objectForKey:#"title"]; and it would presumedly give me back RE 1 (2000). But then I also want to get back the secondary title which is Copyright Page so then i would do self.secondaryTitle = [self.dict objectForKey:#"title"];???
Anyways, my confusion is that I would think it would just again give me back RE 1 (2000) because there is no change to the call and so I don't know how to access the next item with the same key.
Perhaps I am sure the solution is simple I just don't quite understand what I need to do.
You are neglecting the hierarchy of the data which is mapped into the dict - log it to check.
So, to get the first title (RE 1 (2000)), you would do:
NSString *title = [self.dict valueForKeyPath:#"data.1088.title"];
to drill down through the levels in the JSON (and thus the dictionary). And the same approach applies for deeper nested items (though you can't always use valueForKeyPath: because it won't do what you expect with arrays...).
The JSON you posted contains nested arrays (denoted by square brackets []) and dictionaries (denoted by curly brackets {}). You can convert JSON to an NSDictionary using NSJSONSerialization:
NSData *data = ... // Get JSON Data
self.dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
self.mainTitle = [[[self.dict objectForKey:#"data"] objectForKey:#"1088"] objectForKey:#"title"]
self.secondaryTitle = [[[[[self.dict objectForKey:#"data"] objectForKey:#"1088"] objectForKey:#"articles"] objectAtIndex:0] objectForKey:#"title"]
For more info about JSON, you can read the spec.

Printing the most frequent words in a file(string) Objective-C

New to objective-c, need help to solve this:
Write a function that takes two parameters:
1 a String representing a text document and
2 an integer providing the number of items to return. Implement the function such that it returns a list of Strings ordered by word frequency, the most frequently occurring word first. Use your best judgement to decide how words are separated. Your solution should run in O(n) time where n is the number of characters in the document. Implement this function as you would for a production/commercial system. You may use any standard data structures.
What I tried so far (work in progress): ` // Function work in progress
// -(NSString *) wordFrequency:(int)itemsToReturn inDocument:(NSString *)textDocument ;
// Get the desktop directory (where the text document is)
NSURL *desktopDirectory = [[NSFileManager defaultManager] URLForDirectory:NSDesktopDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
// Create full path to the file
NSURL *fullPath = [desktopDirectory URLByAppendingPathComponent:#"document.txt"];
// Load the string
NSString *content = [NSString stringWithContentsOfURL:fullPath encoding:NSUTF8StringEncoding error:nil];
// Optional code for confirmation - Check that the file is here and print its content to the console
// NSLog(#" The string is:%#", content);
// Create an array with the words contain in the string
NSArray *myWords = [content componentsSeparatedByString:#" "];
// Optional code for confirmation - Print content of the array to the console
// NSLog(#"array: %#", myWords);
// Take an NSCountedSet of objects in an array and order those objects by their object count then returns a sorted array, sorted in descending order by the count of the objects.
NSCountedSet *countedSet = [[NSCountedSet alloc] initWithArray:myWords];
NSMutableArray *dictArray = [NSMutableArray array];
[countedSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
[dictArray addObject:#{#"word": obj,
#"count": #([countedSet countForObject:obj])}];
}];
NSLog(#"Words sorted by count: %#", [dictArray sortedArrayUsingDescriptors:#[[NSSortDescriptor sortDescriptorWithKey:#"count" ascending:NO]]]);
}
return 0;
}
This is a classic job for map-reduce. I am very familiar with objective-c, but as far as I know - these concepts are very easily implemented in it.
1st map-reduce is counting the number of occurances.
This step is basically grouping elements according to the word, and then counting them.
map(text):
for each word in text:
emit(word,'1')
reduce(word,list<number>):
emit (word,sum(number))
An alternative for using map-reduce is to use iterative calculation and a hash-map which will be a histogram that counts number of occurances per word.
After you have a a list of numbers and occurances, all you got to do is actually get top k out of them. This is nicely explained in this thread: Store the largest 5000 numbers from a stream of numbers.
In here, the 'comparator' is #occurances of each word, as calculated in previous step.
The basic idea is to use a min-heap, and store k first elements in it.
Now, iterate the remaining of the elements, and if the new one is bigger than the top (minimal element in the heap), remove the top and replace it with the new element.
At the end, you have a heap containing k largest elements, and they are already in a heap - so they are already sorted (though in reversed order, but dealing with it is fairly easy).
Complexity is O(nlogK)
To achieve O(n + klogk) you may use selection algorithm instead of the min-heap solution to get top-k, and then sort the retrieved elements.

Converting NSStrings to Json

I have search a lot ,i did found many answers, but not the specific one i need-which is so simple.
I want to take 2 different NSString that the user type, and create a json from them to send to server .
I wrote this :
-(id)stringToJason:(NSString*)stringData
{
NSData *data = [stringData dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
return json;
}
But there is something i dont get. this return 1 nsstring as json.
How would i take 2 different NSStrings, and create from them together ,the json ?
Lets say: userName:me (when each one is comes from text field)
json should look like :
"Username": "me",
"Firstname": "r",
"Lastname": "k",
If you're wanting to produce JSON that looks like:
{
"Username":"me",
"Firstname":"r",
"Lastname":"k"
}
Where r and k are values taken from the textfields, you could write a method along the lines of this:
-(NSData*)jsonFromFirstName:(NSString*)firstName andLastName:(NSString*)lastName
{
NSDictionary* dic = #{#"Username" : #"me", #"Firstname" : firstName, #"Lastname" : lastName};
// In production code, _check_for_errors!
NSData* json = [NSJSONSerialization dataWithJSONObject:dic options:0 error:nil];
return json;
}
You would call this method, passing the r (firstName) and k (lastName) values to it. It would construct a dictionary that has the structure of the desired JSON, with the desired values. You'd then use NSJSONSerialization's -dataWithJSONObject:options:error selector to convert the dictionary into a JSON data object (stored in an NSData object). You then have the data to send to the server!
The dictionary created in the first line of the method could be expanded as much as you desired, and you could even pass in non-strings (such as numbers, arrays, or even other dictionaries!).

Does core data do its own type casting in the background?

I am working on a simple comparison of two lists to see which items in an "evaluation" list are contained in a larger "target" list. I am getting the data on-the-fly- by parsing two CSV files and storing everything as strings. I successfully import the data into the data store and I can get a list of entities no problem
The problem comes when I actually do a search. Essentially, I am looking for short ISBNs in the form of 1234 from the evaluation list in the target list, which are in the form of 1234-5. The predicate I am using is I am using the CONTAINS comparison in the form of [NSString stringWithFormat:#"%# CONTAINS %#", kOC_Target_PrintBookCode, evalIsbn]
The error I get is the following (grabbed by my NSLog)
NSInvalidArgumentException: Can't look for value (1494) in string (49885); value is not a string
I get the impression that even though the ISBN is being read from a NSString and the Core Data store has the data point spec'd as a String, that Core Data is still doing something in the background with the value for whatever reason it sees fit. Any ideas?
Here is the relevant process logic (though I use that term dubiously) code. Unless otherwise noted in the code, all values being manipulated and/or stored are NSString:
NSArray *evalBooks = [self getEntitiesByName:kOC_EntityName_EvalBook
usingPredicateValue:[NSString stringWithFormat:#"%# > \"\"", kOC_Eval_Bookcode]
withSubstitutionVariables:nil
inModel:[self managedObjectModel]
andContext:[self managedObjectContext]
sortByAttribute:nil];
if ( ( !evalBooks ) || ( [evalBooks count] == 0 ) ) {
// we have problem
NSLog(#"( !evalBooks ) || ( [evalBooks count] == 0 )");
return;
}
[evalBooks retain];
int firstEvalBook = 0;
int thisEvalBook = firstEvalBook;
int lastEvalBook = [evalBooks count]; NSLog(#"lastEvalBook: %i", lastEvalBook);
for (thisEvalBook = firstEvalBook; thisEvalBook < lastEvalBook; thisEvalBook++) {
NSManagedObject *evalBook = [[evalBooks objectAtIndex:thisEvalBook] retain];
NSString *rawIsbn = [[evalBook valueForKey:kOC_Eval_Bookcode] retain];
NSString *isbnRoot = [[self getIsbnRootFromIsbn:rawIsbn] retain];
// this is a custom method I created and use elsewhere without any issues.
NSArray *foundBooks = [self getEntitiesByName:kOC_EntityName_TargetBook
usingPredicateValue:[NSString stringWithFormat:#"%# CONTAINS %#", kOC_Target_PrintBookCode, isbnRoot]
withSubstitutionVariables:nil
inModel:[self managedObjectModel]
andContext:[self managedObjectContext]
sortByAttribute:kOC_Target_PrintBookCode];
if ( foundBooks != nil ) {
[foundBooks retain];
NSLog(#"foundBooks: %lu", [foundBooks count]);
} else {
}
If you're building your predicate as an NSString, I believe
[NSString stringWithFormat:#"%# CONTAINS %#", kOC_Target_PrintBookCode, isbnRoot]
should actually be
[NSString stringWithFormat:#"%# CONTAINS '%#'", kOC_Target_PrintBookCode, isbnRoot]
It seems that you're confusing the way predicateWithFormat: works with the way stringWithFormat: works.
Presumably either kOC_Target_PrintBookCode or isbnRoot is not an object that can be converted to a string. E.g. if either is an integer, the %# operator cannot convert the integer to a string value.