Realm retrieving specific data - ios

Good Day! I started using Realm.io Database for iOS 3 days ago. I can store data from the app to the database. But Retrieving it gives me headache. My problem is i cannot select specific data on database. I'm using this to get the data
RLMResults *data = [MapLocationCoordinates allObjects];
NSString *rawData = [NSString stringWithFormat:#"%#",[data objectAtIndex:0]];
NSLog(#"%#",rawData);
Now the result:
2015-05-07 05:31:01.554 Sample App[2401:79922] MapLocationCoordinates {
objectId = k0zpFLr5Un;
fName = George;
fLatitude = 11.985050;
fLongitude = 121.925295;
}
How can i get the specific data i want? For example, the fName and objectId
Thanks for your answers! More power!

RLMResults has many similar methods as NSArray and in some cases can be treated as such. For example, you can get the first object in the RLMResults using the -firstObject method.
In your code:
MapLocationCoordinates *coords = [data firstObject];
NSString *fName = [coords fName];
NSString *objectId = [coords objectId];
You can also iterate over an RLMResults collection in the same way as you would an array with for(id obj in collection){}.

Related

How to stop a pointer from updating data from a previous loop?

I am using a for loop to loop though and insert data into a NSMutableDictionary and then inserting that NSMutableDictionary into an NSMutableArray, the code is fairly simple and shown below:
for (NSDictionary *selectedOption in selectedOptions) {
NSString *name = selectedOption[#"name"];
NSString *value = selectedOption[#"value"];
[variantRow setObject:name forKey:#"name"];
[variantRow setObject:value forKey:#"value"];
[variantInfo addObject:variantRow];
}
The problem I am trying to solve is that *name and *value always gets the last value of the loop even for previously inserted dicts into the variantInfo NSMutableArray, I am assuming my problem is because I am inserting pointers etc, but I don't understand how else I can do it? I need to insert the values and have future inserts not affect previous ones.
I hope the description makes sense as its not to easy to explain.
You are modifying the same NSDictionary object reference(variantRow) in every iteration and appending it to the array variantInfo. You need to create a new NSDictionary object:
for (NSDictionary *selectedOption in selectedOptions) {
NSString *name = selectedOption[#"name"];
NSString *value = selectedOption[#"value"];
if(name && value) {
NSDictionary* newVariantRow = #{"name": name, #"value":value};
[variantInfo addObject: newVariantRow];
}
}

Realm Results To Array In Kii

am using Realm as a local store. I am currently trying to get the objects found in a realm Query (RLMResults) and store them in an array as part of a KiiObject.
I have very little experience using NSArray or NSDictionary to create an array of JSON to store in the KiiObject. As the number of objects in the realm search will vary i thought this might work:
for (RLMObject *object in currentEventResults) {
[array addObject:object];
}
and then add the array to my KiiObject.
[object setObject:array forKey:#"arryofObj"];
But the array has no objects in it when saved to Kii, but i know currentEventResults has 45 objects.
After a night of tinkering came up with this:
for (RLMObject *object in currentEvent) {
NSDictionary *dictOBJ =
#{#"eventID":[object objectForKeyedSubscript:#"eventID"],
#"longValue":[object objectForKeyedSubscript:#"longValue"],
#"latValue":[object objectForKeyedSubscript:#"latValue"],
#"pingTime":[object objectForKeyedSubscript:#"pingTime"]};
[mutableArray addObject:dictOBJ];
}
I then :
NSArray *arrayToSave = [mutableArray copy];
I then save the array to my Kii Object.
It works well. If there is a better solution please post it.

ios nsarray/nsmutablearray group by/sum on custom objects

I'm just getting through tons of research and tutorials on ios app development.
Making my first app now and using array with tableviews. My question is now that I have populated arrays with custom objects, I want to query it.
Group By with Sum... things of that nature.
In my research I've found predicates for some types of filtering. So far I have successfully returned a new array where on property in my class is equal to "x".
Predicate worked for that part.
But I'm not sure how to expand to groupby/sum. I've been reading core data might accomplish this but is probably overkill.
Can someone please help me out with some options to research?
Thanks!!!
example
Person Class
name age salary
how can I group by name, and at the same time sum up the salaries?
I found this also ... is this an efficient way to tackle problem
// Get all the airline names with no duplicates using the KVC #distinctUnionOfObjects collection operator
NSArray *airlineNames = [arrayMealRating valueForKeyPath:#"#distinctUnionOfObjects.Airline"];
// Loop through all the airlines
for (NSString *airline in airlineNames) {
// Get an array of all the dictionaries for the current airline
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(Airline == %#)", airline];
NSArray *airlineMealRating = [arrayMealRating filteredArrayUsingPredicate:predicate];
// Get the sum of all the ratings using KVC #sum collection operator
NSNumber *rating = [airlineMealRating valueForKeyPath:#"#sum.Rating"];
NSLog(#"%#: %#", airline, rating);
}
You probably want to use a dictionary so you can efficiently look up the running total for each person by name. Since you're new at Objective-C, I'll spell everything out:
NSMutableDictionary *totalSalaryForName = [NSMutableDictionary dictionary];
for (Person *person in people) {
NSString *name = [person name];
int total = [person salary];
NSNumber *priorTotal = [totalSalaryForName objectAtIndex:name];
if (priorTotal != nil) {
total += [priorTotal intValue];
}
NSNumber *newTotal = [NSNumber numberWithInt:total];
[totalSalaryForName setObject:newTotal forKey:name];
}
However, modern Objective-C provides some “syntactic sugar” you can use to shorten the code:
NSMutableDictionary *totalSalaryForName = [NSMutableDictionary dictionary];
for (Person *person in people) {
NSString *name = person.name;
int total = person.salary;
NSNumber *priorTotal = totalSalaryForName[name];
if (priorTotal != nil) {
total += priorTotal.intValue;
}
totalSalaryForName[name] = #(total);
}
Now you have a dictionary that maps each person's name to total salary.

NSDictionary allKeysForObject in an array

I have a NSDictonary that looks like this. I need to get all the key values that are associated for a particular name. For example the name Samrin is associated with keys 11.titleKey, 110.titleKey and so on. The problem I have is that I am not sure how can I get to the object in an array and then pass they key value back?
I tried the following code with not much success.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"birthdays.plist"];
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:stringsPlistPath];
NSArray *temp = [dictionary allKeysForObject:#"Samrin Ateequi"];
NSLog(#"temp: %# ...", temp);
OUTPUT:
temp: (
) ...
I think you can use keysOfEntriesPassingTest for that. Something like:
NSSet *keysSet = [dictionary keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) {
if ([[obj objectAtIndex:0] isEqualToString:#"Samrin Ateequi"]) {
return YES;
} else {
return NO;
}
}];
allKeysForObject: looks through the dictionary for values equal to that object using isEqual:. Your values for that dictionary are NSArrays, so it will never match the NSString you are looking for.
If you don't change the data structure you will have to loop through everything to get the results you need.
If you are willing to upgrade to Core Data with an SQL store, then your results will be fast and the code will be easier than looping through the dictionary. This is the kind of problem that Core Data was meant to solve. You can get started with the Core Data Programming Guide.
Hope this will help you: I have taken an example.
NSDictionary *dict = #{#"key1":#[#"mania",#"champ"],
#"key2":#[#"mann",#"champ"],
#"key3":#[#"mania",#"champ",#"temp"]};
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:#"ANY SELF=%#",#"mania"];
NSArray *allValues = [dict allValues];
NSArray *requiredRows = [allValues filteredArrayUsingPredicate:filterPredicate];
NSMutableArray *requiredKeyArray = [[NSMutableArray alloc]initWithCapacity:0];
for (id anObj in requiredRows) {
[requiredKeyArray addObject:[dict allKeysForObject:anObj]];
}
NSLog(#"Desc: %#",[requiredKeyArray description]);

IOS Data Import Strategy/Design

I'm in the midst of writing a data import routine for an iPad application. It seems to be working fine. However, because I'm an IOS noob and coming from an application development background in which such tasks are handled via calls to an SQL server, I'm feeling the need to double-check if I'm using the correct approach.
Here is the basic approach I'm using to import data into one of my master data entities:
// SET UP SOME VARIABLES/VALUES APPLICABLE TO ALL IMPORTS
NSStringEncoding encoding = 1;
NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
NSString* file = nil;
NSError* error = nil;
NSArray* records = nil;
NSArray* fields = nil;
NSPredicate* predicate = nil;
NSArray* filteredArray = nil;
// IMPORT GEO DATA
// ProvinceState
file = [[NSBundle bundleForClass:[self class]] pathForResource:#"ProvinceState" ofType:#"txt"];
error = nil;
records = [NSArray arrayWithContentsOfCSVFile:file usedEncoding:&encoding error:&error];
NSManagedObject* provinceState = nil;
NSMutableArray* provinceStateArray = [NSMutableArray arrayWithCapacity:[records count]];
for (int i = 0; i < [records count]; ++i)
{
fields = [records objectAtIndex:i];
if ([fields count] == 2)
{
provinceState = [NSEntityDescription insertNewObjectForEntityForName:#"ProvinceState" inManagedObjectContext:self.managedObjectContext];
[provinceState setValue: [numberFormatter numberFromString:[fields objectAtIndex:0]] forKey:#"id"];
[provinceState setValue:[fields objectAtIndex:1] forKey:#"name"];
[provinceStateArray addObject:provinceState];
}
}
A couple of key points. This particular entity is very simple - just an integer id and a string name. Its source table is a simple csv file. The method arrayWithContentsOfCSVFile:usedEncoding:error: is from Dave Delong's excellent CHCSV parser, which makes parsing a breeze. I have not yet applied any error handling because I'm trying to work out the basic techniques first.
Okay, so unless you spot anything wrong with this simple code, I'll now get on with my main questions. The provinceStateArray referenced in the last meaningful line of the above code is to save myself the hassle of having to query the master data entities later on, when I need to populate them into the relationships of my transactional data. I realize this a) increases my memory requirements and b) prevents me, by implication, from draining the associated autoreleasepool, but since the half-dozen or so master data entities contain only a few hundred small objects in total, I didn't think this was a concern. Anyone think differently?
Now the part that does concern me. In the following code, which populates a Locations entity, I'm using these same master data entity arrays as follows:
file = [[NSBundle bundleForClass:[self class]] pathForResource:#"Location" ofType:#"txt"];
error = nil;
records = [NSArray arrayWithContentsOfCSVFile:file usedEncoding:&encoding error:&error];
NSManagedObject* location = nil;
NSMutableArray* locationArray = [NSMutableArray arrayWithCapacity:[records count]];
for (int i = 0; i < [records count]; ++i)
{
NSArray* fields = [records objectAtIndex:i];
if ([fields count] == 5)
{
location = [NSEntityDescription insertNewObjectForEntityForName:#"Location" inManagedObjectContext:self.managedObjectContext];
[location setValue: [numberFormatter numberFromString:[fields objectAtIndex:0]] forKey:#"id"];
predicate = [NSPredicate predicateWithFormat:#"id = %#", [numberFormatter numberFromString:[fields objectAtIndex:1]]];
filteredArray = [provinceStateArray filteredArrayUsingPredicate:predicate];
if ([filteredArray count] > 0)
{
[location setValue:[filteredArray objectAtIndex:0] forKey:#"provinceState"];
}
...and so on down through the other relationship entities that must be set.
This is the part - having to construct large quantities of objects simply to set the relationships - that feels foreign to me, even though I don't see any alternative.
Also, because the source data is from an RDBMS, I'm populating the one side of one-to-many relationships instead of iterating through sets.
Anything smell bad in all of this, or can I carry on with some comfort that I understand?
I think it is better to create SQLite database, import it to your project and import data from a file to that database(it is hard drive memory), not to arrays in RAM. Then, when your database is ready for use, make queries to it to populate only needed data for your user to iPhone RAM.

Resources